diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..4c2b5e36 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 2 +indent_style = space +insert_final_newline = true +max_line_length = 80 +tab_width = 2 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[{package.json,.travis.yml}] +indent_style = space +indent_size = 2 diff --git a/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md similarity index 97% rename from ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE.md index 5fd7db4a..2aab9345 100644 --- a/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,20 +1,19 @@ - -![A GIF or MEME to give some spice of the internet](url) - -## *What* is wrong? - - -## *Where* does it happen? - - -## *How* do we replicate the issue? - - -## *How* important is this (1-5)? - - -## Expected behavior (i.e. solution) - - - -## Other Comments + +![A GIF or MEME to give some spice of the internet](url) + +## *What* is wrong? + + +## *Where* does it happen? + + +## *How* do we replicate the issue? + + +## *How* important is this (1-5)? + + +## Expected behavior (i.e. solution) + + +## Other Comments diff --git a/.gitignore b/.gitignore index 91b984ce..226ea865 100644 --- a/.gitignore +++ b/.gitignore @@ -1,36 +1,36 @@ -# Logs -logs -*.log -npm-debug.log* - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# node-waf configuration -.lock-wscript - -# Dependency directory -node_modules - -# Optional npm cache directory -.npm - -# Optional REPL history -.node_repl_history - -# intellij -.idea - -#yarn -yarn.lock - -# OSX .DS_Store -.DS_Store +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# node-waf configuration +.lock-wscript + +# Dependency directory +node_modules + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +# intellij +.idea + +#yarn +yarn.lock + +# OSX .DS_Store +.DS_Store diff --git a/build-tests.js b/build-tests.js new file mode 100644 index 00000000..fc8d697c --- /dev/null +++ b/build-tests.js @@ -0,0 +1,48 @@ +/** + * Question: Why are we even using QUnit? + * + * We should be migrating to a more modern unit testing framework like Jest or Ava. + * I hear some people have even gotten WebGL-related testing done with Jest. + */ + +const fs = require('fs'); +const path = require('path'); +const util = require('util'); +const { readDirDeep } = require('read-dir-deep'); + +const readFile = util.promisify(fs.readFile) +const unlink = util.promisify(fs.unlink) +const writeFile = util.promisify(fs.writeFile) + +const CWD = process.cwd(); + +async function main () { + const folder = 'test'; + const output = path.resolve(CWD, folder, 'all.html'); + const template = path.resolve(CWD, folder, 'all-template.html'); + const rootPath = path.resolve(CWD, folder); + const warning = '\n'; + + await unlink(output).catch(e => {}); + + const files = await readDirDeep(rootPath, { + patterns: [ '**/*.js' ], + ignore: [ '*.js' ] + }); + + const str = warning + files + .map(file => file.replace(/^test\//, '')) + .map(file => ``) + .join('\n'); + + const file = await readFile(template, 'utf8'); + + const data = file.replace('{{test-files}}', str); + + await writeFile(output, data); +}; + +main().catch(err => { + console.error(err.message) + process.exit(1) +}); diff --git a/dist/gpu-browser-core.js b/dist/gpu-browser-core.js index 0db03108..aebab023 100644 --- a/dist/gpu-browser-core.js +++ b/dist/gpu-browser-core.js @@ -1,14118 +1,12168 @@ /** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.0.5 - * @date Fri Oct 11 2019 07:23:33 GMT-0400 (Eastern Daylight Time) + * @date Tue Oct 29 2019 10:46:59 GMT-0400 (Eastern Daylight Time) * * @license MIT * The MIT License * * Copyright (c) 2019 gpu.js Team - */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GPU = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i 0) { - recording.pop(); + function mock1D() { + const args = setupArguments(arguments); + const row = new Float32Array(this.output.x); + for (let x = 0; x < this.output.x; x++) { + this.thread.x = x; + this.thread.y = 0; + this.thread.z = 0; + row[x] = this._fn.apply(this, args); } + return row; } - function insertVariable(name, value) { - variables[name] = value; - } - function getEntity(value) { - const name = entityNames[value]; - if (name) { - return contextName + '.' + name; + function mock2D() { + const args = setupArguments(arguments); + const matrix = new Array(this.output.y); + for (let y = 0; y < this.output.y; y++) { + const row = new Float32Array(this.output.x); + for (let x = 0; x < this.output.x; x++) { + this.thread.x = x; + this.thread.y = y; + this.thread.z = 0; + row[x] = this._fn.apply(this, args); + } + matrix[y] = row; } - return value; - } - function setIndent(spaces) { - indent = ' '.repeat(spaces); - } - function addVariable(value, source) { - const variableName = `${contextName}Variable${contextVariables.length}`; - recording.push(`${indent}const ${variableName} = ${source};`); - contextVariables.push(value); - return variableName; - } - function writePPM(width, height) { - const sourceVariable = `${contextName}Variable${contextVariables.length}`; - const imageVariable = `imageDatum${imageCount}`; - recording.push(`${indent}let ${imageVariable} = ["P3\\n# ${readPixelsFile}.ppm\\n", ${width}, ' ', ${height}, "\\n255\\n"].join("");`); - recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`); - recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`); - recording.push(`${indent}}`); - recording.push(`${indent}if (typeof require !== "undefined") {`); - recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`); - recording.push(`${indent}}`); - imageCount++; - } - function addComment(value) { - recording.push(`${indent}// ${value}`); - } - function checkThrowError() { - recording.push(`${indent}(() => { -${indent}const error = ${contextName}.getError(); -${indent}if (error !== ${contextName}.NONE) { -${indent} const names = Object.getOwnPropertyNames(gl); -${indent} for (let i = 0; i < names.length; i++) { -${indent} const name = names[i]; -${indent} if (${contextName}[name] === error) { -${indent} throw new Error('${contextName} threw ' + name); -${indent} } -${indent} } -${indent}} -${indent}})();`); + return matrix; } - function methodCallToString(method, args) { - return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; - } - - function getVariableName(value) { - if (variables) { - for (const name in variables) { - if (variables[name] === value) { - return name; - } + function mock2DGraphical() { + const args = setupArguments(arguments); + for (let y = 0; y < this.output.y; y++) { + for (let x = 0; x < this.output.x; x++) { + this.thread.x = x; + this.thread.y = y; + this.thread.z = 0; + this._fn.apply(this, args); } } - return null; } - - function getContextVariableName(value) { - const i = contextVariables.indexOf(value); - if (i !== -1) { - return `${contextName}Variable${i}`; + function mock3D() { + const args = setupArguments(arguments); + const cube = new Array(this.output.z); + for (let z = 0; z < this.output.z; z++) { + const matrix = new Array(this.output.y); + for (let y = 0; y < this.output.y; y++) { + const row = new Float32Array(this.output.x); + for (let x = 0; x < this.output.x; x++) { + this.thread.x = x; + this.thread.y = y; + this.thread.z = z; + row[x] = this._fn.apply(this, args); + } + matrix[y] = row; + } + cube[z] = matrix; } - return null; + return cube; } -} - -function glExtensionWiretap(extension, options) { - const proxy = new Proxy(extension, { get: listen }); - const extensionEntityNames = {}; - const { - contextName, - contextVariables, - getEntity, - useTrackablePrimitives, - recording, - variables, - indent, - onUnrecognizedArgumentLookup, - } = options; - return proxy; - function listen(obj, property) { - if (typeof obj[property] === 'function') { - return function() { - switch (property) { - case 'drawBuffersWEBGL': - recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`); - return extension.drawBuffersWEBGL(arguments[0]); - } - let result = extension[property].apply(extension, arguments); - switch (typeof result) { - case 'undefined': - recording.push(`${indent}${methodCallToString(property, arguments)};`); - return; - case 'number': - case 'boolean': - if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) { - recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); - contextVariables.push(result = trackablePrimitive(result)); - } else { - recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); - contextVariables.push(result); - } - break; - default: - if (result === null) { - recording.push(`${methodCallToString(property, arguments)};`); - } else { - recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); - } - contextVariables.push(result); + function apiDecorate(kernel) { + kernel.setOutput = (output) => { + kernel.output = setupOutput(output); + if (kernel.graphical) { + setupGraphical(kernel); + } + }; + kernel.toJSON = () => { + throw new Error('Not usable with gpuMock'); + }; + kernel.setConstants = (flag) => { + kernel.constants = flag; + return kernel; + }; + kernel.setGraphical = (flag) => { + kernel.graphical = flag; + return kernel; + }; + kernel.setCanvas = (flag) => { + kernel.canvas = flag; + return kernel; + }; + kernel.setContext = (flag) => { + kernel.context = flag; + return kernel; + }; + kernel.exec = function() { + return new Promise((resolve, reject) => { + try { + resolve(kernel.apply(kernel, arguments)); + } catch(e) { + reject(e); } - return result; - }; + }); + }; + kernel.getPixels = (flip) => { + const {x, y} = kernel.output; + return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0); + }; + kernel.color = function(r, g, b, a) { + if (typeof a === 'undefined') { + a = 1; + } + r = Math.floor(r * 255); + g = Math.floor(g * 255); + b = Math.floor(b * 255); + a = Math.floor(a * 255); + const width = kernel.output.x; + const height = kernel.output.y; + const x = kernel.thread.x; + const y = height - kernel.thread.y - 1; + const index = x + y * width; + kernel._colorData[index * 4 + 0] = r; + kernel._colorData[index * 4 + 1] = g; + kernel._colorData[index * 4 + 2] = b; + kernel._colorData[index * 4 + 3] = a; + }; + kernel.setWarnVarUsage = () => { + return kernel; + }; + kernel.setOptimizeFloatMemory = () => { + return kernel; + }; + kernel.setArgumentTypes = () => { + return kernel; + }; + kernel.setDebug = () => { + return kernel; + }; + kernel.setLoopMaxIterations = () => { + return kernel; + }; + kernel.setPipeline = () => { + return kernel; + }; + kernel.setPrecision = () => { + return kernel; + }; + kernel.setImmutable = () => { + return kernel; + }; + kernel.setFunctions = () => { + return kernel; + }; + kernel.addSubKernel = () => { + return kernel; + }; + kernel.destroy = () => {}; + kernel.validateSettings = () => {}; + if (kernel.graphical && kernel.output) { + setupGraphical(kernel); } - extensionEntityNames[extension[property]] = property; - return extension[property]; + return kernel; } - - function getExtensionEntity(value) { - if (extensionEntityNames.hasOwnProperty(value)) { - return `${contextName}.${extensionEntityNames[value]}`; + function setupGraphical(kernel) { + const {x, y} = kernel.output; + if (kernel.context && kernel.context.createImageData) { + const data = new Uint8ClampedArray(x * y * 4); + kernel._imageData = kernel.context.createImageData(x, y); + kernel._colorData = data; + } else { + const data = new Uint8ClampedArray(x * y * 4); + kernel._imageData = { data }; + kernel._colorData = data; + } + } + function setupOutput(output) { + let result = null; + if (output.length) { + if (output.length === 3) { + const [x,y,z] = output; + result = { x, y, z }; + } else if (output.length === 2) { + const [x,y] = output; + result = { x, y }; + } else { + const [x] = output; + result = { x }; + } + } else { + result = output; } - return getEntity(value); + return result; } - - function methodCallToString(method, args) { - return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; + function gpuMock(fn, settings = {}) { + const output = settings.output ? setupOutput(settings.output) : null; + function kernel() { + if (kernel.output.z) { + return mock3D.apply(kernel, arguments); + } else if (kernel.output.y) { + if (kernel.graphical) { + return mock2DGraphical.apply(kernel, arguments); + } + return mock2D.apply(kernel, arguments); + } else { + return mock1D.apply(kernel, arguments); + } + } + kernel._fn = fn; + kernel.constants = settings.constants || null; + kernel.context = settings.context || null; + kernel.canvas = settings.canvas || null; + kernel.graphical = settings.graphical || false; + kernel._imageData = null; + kernel._colorData = null; + kernel.output = output; + kernel.thread = { + x: 0, + y: 0, + z: 0 + }; + return apiDecorate(kernel); } - - function addVariable(value, source) { - const variableName = `${contextName}Variable${contextVariables.length}`; - contextVariables.push(value); - recording.push(`${indent}const ${variableName} = ${source};`); - return variableName; + function flipPixels(pixels, width, height) { + const halfHeight = height / 2 | 0; + const bytesPerRow = width * 4; + const temp = new Uint8ClampedArray(width * 4); + const result = pixels.slice(0); + for (let y = 0; y < halfHeight; ++y) { + const topOffset = y * bytesPerRow; + const bottomOffset = (height - y - 1) * bytesPerRow; + temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); + result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); + result.set(temp, bottomOffset); + } + return result; } -} + var gpuMock_js = { + gpuMock + }; + var gpuMock_js_1 = gpuMock_js.gpuMock; -function argumentsToString(args, options) { - const { variables, onUnrecognizedArgumentLookup } = options; - return (Array.from(args).map((arg) => { - const variableName = getVariableName(arg); - if (variableName) { - return variableName; + const ARGUMENT_NAMES = /([^\s,]+)/g; + const FUNCTION_NAME = /function ([^(]*)/; + const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; + function isFunction(funcObj) { + return typeof(funcObj) === 'function'; + }function getFunctionNameFromString(funcStr) { + return FUNCTION_NAME.exec(funcStr)[1].trim(); + }function functionToIFunction(source, settings) { + settings = settings || {}; + if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function'); + const sourceString = typeof source === 'string' ? source : source.toString(); + let argumentTypes = []; + if (Array.isArray(settings.argumentTypes)) { + argumentTypes = settings.argumentTypes; + } else if (typeof settings.argumentTypes === 'object') { + argumentTypes = getArgumentNamesFromString(sourceString) + .map(name => settings.argumentTypes[name]) || []; + } else { + argumentTypes = settings.argumentTypes || []; } - return argumentToString(arg, options); - }).join(', ')); - - function getVariableName(value) { - if (variables) { - for (const name in variables) { - if (!variables.hasOwnProperty(name)) continue; - if (variables[name] === value) { - return name; - } + return { + source: sourceString, + argumentTypes, + returnType: settings.returnType || null, + }; + }function warnDeprecated(type, oldName, newName) { + const msg = newName + ? `It has been replaced with "${ newName }"` + : 'It has been removed'; + console.warn(`You are using a deprecated ${ type } "${ oldName }". ${msg}. Fixing, but please upgrade as it will soon be removed.`); + }function isFunctionString(fn) { + if (typeof fn === 'string') { + return (fn + .slice(0, 'function'.length) + .toLowerCase() === 'function'); + } + return false; + }function getArgumentNamesFromString(fn) { + const fnStr = fn.replace(STRIP_COMMENTS, ''); + let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); + if (result === null) { + result = []; + } + return result; + }function isArray(array) { + return !isNaN(array.length); + }function erectMemoryOptimized2DFloat(array, width, height) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const offset = y * width; + yResults[y] = array.subarray(offset, offset + width); + } + return yResults; + }function erectMemoryOptimized3DFloat(array, width, height, depth) { + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const offset = (z * height * width) + (y * width); + yResults[y] = array.subarray(offset, offset + width); } + zResults[z] = yResults; } - if (onUnrecognizedArgumentLookup) { - return onUnrecognizedArgumentLookup(value); + return zResults; + }function getAstString(source, ast) { + const lines = Array.isArray(source) ? source : source.split(/\r?\n/g); + const start = ast.loc.start; + const end = ast.loc.end; + const result = []; + if (start.line === end.line) { + result.push(lines[start.line - 1].substring(start.column, end.column)); + } else { + result.push(lines[start.line - 1].slice(start.column)); + for (let i = start.line; i < end.line; i++) { + result.push(lines[i]); + } + result.push(lines[end.line - 1].slice(0, end.column)); } - return null; + return result.join('\n'); } -} -function argumentToString(arg, options) { - const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options; - if (typeof arg === 'undefined') { - return 'undefined'; - } - if (arg === null) { - return 'null'; - } - const i = contextVariables.indexOf(arg); - if (i > -1) { - return `${contextName}Variable${i}`; - } - switch (arg.constructor.name) { - case 'String': - const hasLines = /\n/.test(arg); - const hasSingleQuotes = /'/.test(arg); - const hasDoubleQuotes = /"/.test(arg); - if (hasLines) { - return '`' + arg + '`'; - } else if (hasSingleQuotes && !hasDoubleQuotes) { - return '"' + arg + '"'; - } else if (!hasSingleQuotes && hasDoubleQuotes) { - return "'" + arg + "'"; + var common = /*#__PURE__*/Object.freeze({ + isFunction: isFunction, + getFunctionNameFromString: getFunctionNameFromString, + functionToIFunction: functionToIFunction, + warnDeprecated: warnDeprecated, + isFunctionString: isFunctionString, + getArgumentNamesFromString: getArgumentNamesFromString, + isArray: isArray, + erectMemoryOptimized2DFloat: erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat: erectMemoryOptimized3DFloat, + getAstString: getAstString + }); + + class Input { + constructor(value, size) { + this.value = value; + if (Array.isArray(size)) { + this.size = size; } else { - return '\'' + arg + '\''; - } - case 'Number': return getEntity(arg); - case 'Boolean': return getEntity(arg); - case 'Array': - return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`); - case 'Float32Array': - case 'Uint8Array': - case 'Uint16Array': - case 'Int32Array': - return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`); - default: - if (onUnrecognizedArgumentLookup) { - const instantiationString = onUnrecognizedArgumentLookup(arg); - if (instantiationString) { - return instantiationString; + this.size = new Int32Array(3); + if (size.z) { + this.size = new Int32Array([size.x, size.y, size.z]); + } else if (size.y) { + this.size = new Int32Array([size.x, size.y]); + } else { + this.size = new Int32Array([size.x]); + } + } + const [w, h, d] = this.size; + if (d) { + if (this.value.length !== (w * h * d)) { + throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`); + } + } else if (h) { + if (this.value.length !== (w * h)) { + throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`); + } + } else { + if (this.value.length !== w) { + throw new Error(`Input size ${this.value.length} does not match ${w}`); } } - throw new Error(`unrecognized argument type ${arg.constructor.name}`); - } -} - -function trackablePrimitive(value) { - return new value.constructor(value); -} - -if (typeof module !== 'undefined') { - module.exports = { glWiretap, glExtensionWiretap }; -} - -if (typeof window !== 'undefined') { - glWiretap.glExtensionWiretap = glExtensionWiretap; - window.glWiretap = glWiretap; -} - -},{}],3:[function(require,module,exports){ -function setupArguments(args) { - const newArguments = new Array(args.length); - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - if (arg.toArray) { - newArguments[i] = arg.toArray(); - } else { - newArguments[i] = arg; } - } - return newArguments; -} - -function mock1D() { - const args = setupArguments(arguments); - const row = new Float32Array(this.output.x); - for (let x = 0; x < this.output.x; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - row[x] = this._fn.apply(this, args); - } - return row; -} - -function mock2D() { - const args = setupArguments(arguments); - const matrix = new Array(this.output.y); - for (let y = 0; y < this.output.y; y++) { - const row = new Float32Array(this.output.x); - for (let x = 0; x < this.output.x; x++) { - this.thread.x = x; - this.thread.y = y; - this.thread.z = 0; - row[x] = this._fn.apply(this, args); + toArray() { + const [ w, h, d ] = this.size; + if (d) { + return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); + } else if (h) { + return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h); + } else { + return this.value; + } } - matrix[y] = row; + }function input(value, size) { + return new Input(value, size); } - return matrix; -} -function mock2DGraphical() { - const args = setupArguments(arguments); - for (let y = 0; y < this.output.y; y++) { - for (let x = 0; x < this.output.x; x++) { - this.thread.x = x; - this.thread.y = y; - this.thread.z = 0; - this._fn.apply(this, args); + class Texture { + constructor(settings) { + const { + texture, + size, + dimensions, + output, + context, + type = 'NumberTexture', + } = settings; + if (!output) throw new Error('settings property "output" required.'); + if (!context) throw new Error('settings property "context" required.'); + this.texture = texture; + this.size = size; + this.dimensions = dimensions; + this.output = output; + this.context = context; + this.kernel = null; + this.type = type; } - } -} - -function mock3D() { - const args = setupArguments(arguments); - const cube = new Array(this.output.z); - for (let z = 0; z < this.output.z; z++) { - const matrix = new Array(this.output.y); - for (let y = 0; y < this.output.y; y++) { - const row = new Float32Array(this.output.x); - for (let x = 0; x < this.output.x; x++) { - this.thread.x = x; - this.thread.y = y; - this.thread.z = z; - row[x] = this._fn.apply(this, args); - } - matrix[y] = row; + toArray() { + throw new Error(`Not implemented on ${this.constructor.name}`); + } + delete() { + return this.context.deleteTexture(this.texture); } - cube[z] = matrix; } - return cube; -} -function apiDecorate(kernel) { - kernel.setOutput = (output) => { - kernel.output = setupOutput(output); - if (kernel.graphical) { - setupGraphical(kernel); + function getSystemEndianness() { + const b = new ArrayBuffer(4); + const a = new Uint32Array(b); + const c = new Uint8Array(b); + a[0] = 0xdeadbeef; + if (c[0] === 0xef) return 'LE'; + if (c[0] === 0xde) return 'BE'; + throw new Error('unknown endianness'); + }const _systemEndianness = getSystemEndianness(); + function systemEndianness() { + return _systemEndianness; + }function getVariableType(value, strictIntegers) { + if (isArray(value)) { + if (value[0].nodeName === 'IMG') { + return 'HTMLImageArray'; + } + return 'Array'; } - }; - kernel.toJSON = () => { - throw new Error('Not usable with gpuMock'); - }; - kernel.setConstants = (flag) => { - kernel.constants = flag; - return kernel; - }; - kernel.setGraphical = (flag) => { - kernel.graphical = flag; - return kernel; - }; - kernel.setCanvas = (flag) => { - kernel.canvas = flag; - return kernel; - }; - kernel.setContext = (flag) => { - kernel.context = flag; - return kernel; - }; - kernel.exec = function() { - return new Promise((resolve, reject) => { - try { - resolve(kernel.apply(kernel, arguments)); - } catch(e) { - reject(e); - } - }); - }; - kernel.getPixels = (flip) => { - const {x, y} = kernel.output; - return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0); - }; - kernel.color = function(r, g, b, a) { - if (typeof a === 'undefined') { - a = 1; + switch (value.constructor) { + case Boolean: + return 'Boolean'; + case Number: + return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float'; + case Texture: + return value.type; + case Input: + return 'Input'; } - - r = Math.floor(r * 255); - g = Math.floor(g * 255); - b = Math.floor(b * 255); - a = Math.floor(a * 255); - - const width = kernel.output.x; - const height = kernel.output.y; - - const x = kernel.thread.x; - const y = height - kernel.thread.y - 1; - - const index = x + y * width; - - kernel._colorData[index * 4 + 0] = r; - kernel._colorData[index * 4 + 1] = g; - kernel._colorData[index * 4 + 2] = b; - kernel._colorData[index * 4 + 3] = a; - }; - - kernel.setWarnVarUsage = () => { - return kernel; - }; - kernel.setOptimizeFloatMemory = () => { - return kernel; - }; - kernel.setArgumentTypes = () => { - return kernel; - }; - kernel.setDebug = () => { - return kernel; - }; - kernel.setLoopMaxIterations = () => { - return kernel; - }; - kernel.setPipeline = () => { - return kernel; - }; - kernel.setPrecision = () => { - return kernel; - }; - kernel.setImmutable = () => { - return kernel; - }; - kernel.setFunctions = () => { - return kernel; - }; - kernel.addSubKernel = () => { - return kernel; - }; - kernel.destroy = () => {}; - kernel.validateSettings = () => {}; - if (kernel.graphical && kernel.output) { - setupGraphical(kernel); - } - return kernel; -} - -function setupGraphical(kernel) { - const {x, y} = kernel.output; - if (kernel.context && kernel.context.createImageData) { - const data = new Uint8ClampedArray(x * y * 4); - kernel._imageData = kernel.context.createImageData(x, y); - kernel._colorData = data; - } else { - const data = new Uint8ClampedArray(x * y * 4); - kernel._imageData = { data }; - kernel._colorData = data; - } -} - -function setupOutput(output) { - let result = null; - if (output.length) { - if (output.length === 3) { - const [x,y,z] = output; - result = { x, y, z }; - } else if (output.length === 2) { - const [x,y] = output; - result = { x, y }; - } else { - const [x] = output; - result = { x }; + switch (value.nodeName) { + case 'IMG': + return 'HTMLImage'; + case 'VIDEO': + return 'HTMLVideo'; } - } else { - result = output; - } - return result; -} - -function gpuMock(fn, settings = {}) { - const output = settings.output ? setupOutput(settings.output) : null; - function kernel() { - if (kernel.output.z) { - return mock3D.apply(kernel, arguments); - } else if (kernel.output.y) { - if (kernel.graphical) { - return mock2DGraphical.apply(kernel, arguments); + return value.hasOwnProperty('type') ? value.type : 'Unknown'; + }const utils$1 = { + systemEndianness, + getSystemEndianness, + isFunction, + isFunctionString, + getFunctionNameFromString, + getFunctionBodyFromString(funcStr) { + return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); + }, + getArgumentNamesFromString, + clone(obj) { + if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj; + const temp = obj.constructor(); + for (let key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + obj.isActiveClone = null; + temp[key] = utils$1.clone(obj[key]); + delete obj.isActiveClone; + } + } + return temp; + }, + isArray, + getVariableType, + getKernelTextureSize(settings, dimensions) { + let [w, h, d] = dimensions; + let texelCount = (w || 1) * (h || 1) * (d || 1); + if (settings.optimizeFloatMemory && settings.precision === 'single') { + w = texelCount = Math.ceil(texelCount / 4); + } + if (h > 1 && w * h === texelCount) { + return new Int32Array([w, h]); + } + return utils$1.closestSquareDimensions(texelCount); + }, + closestSquareDimensions(length) { + const sqrt = Math.sqrt(length); + let high = Math.ceil(sqrt); + let low = Math.floor(sqrt); + while (high * low < length) { + high--; + low = Math.ceil(length / high); + } + return new Int32Array([low, Math.ceil(length / low)]); + }, + getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) { + const totalArea = utils$1.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4); + const texelCount = totalArea / bitRatio; + return utils$1.closestSquareDimensions(texelCount); + }, + getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) { + const [w, h, d] = dimensions; + const totalArea = utils$1.roundTo((w || 1) * (h || 1) * (d || 1), 4); + const texelCount = totalArea / (4 / bitRatio); + return utils$1.closestSquareDimensions(texelCount); + }, + roundTo(n, d) { + return Math.floor((n + d - 1) / d) * d; + }, + getDimensions(x, pad) { + let ret; + if (isArray(x)) { + const dim = []; + let temp = x; + while (isArray(temp)) { + dim.push(temp.length); + temp = temp[0]; + } + ret = dim.reverse(); + } else if (x instanceof Texture) { + ret = x.output; + } else if (x instanceof Input) { + ret = x.size; + } else { + throw new Error(`Unknown dimensions of ${x}`); } - return mock2D.apply(kernel, arguments); - } else { - return mock1D.apply(kernel, arguments); - } - } - kernel._fn = fn; - kernel.constants = settings.constants || null; - kernel.context = settings.context || null; - kernel.canvas = settings.canvas || null; - kernel.graphical = settings.graphical || false; - kernel._imageData = null; - kernel._colorData = null; - kernel.output = output; - kernel.thread = { - x: 0, - y: 0, - z: 0 - }; - return apiDecorate(kernel); -} - -function flipPixels(pixels, width, height) { - const halfHeight = height / 2 | 0; - const bytesPerRow = width * 4; - const temp = new Uint8ClampedArray(width * 4); - const result = pixels.slice(0); - for (let y = 0; y < halfHeight; ++y) { - const topOffset = y * bytesPerRow; - const bottomOffset = (height - y - 1) * bytesPerRow; - - temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); - - result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); - - result.set(temp, bottomOffset); - } - return result; -} - -module.exports = { - gpuMock -}; - -},{}],4:[function(require,module,exports){ -const { utils } = require('./utils'); - -function alias(name, source) { - const fnString = source.toString(); - return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) { - ${ utils.getFunctionBodyFromString(fnString) } -}`)(); -} - -module.exports = { - alias -}; -},{"./utils":111}],5:[function(require,module,exports){ -const { FunctionNode } = require('../function-node'); - -class CPUFunctionNode extends FunctionNode { - astFunction(ast, retArr) { - - if (!this.isRootKernel) { - retArr.push('function'); - retArr.push(' '); - retArr.push(this.name); - retArr.push('('); - - for (let i = 0; i < this.argumentNames.length; ++i) { - const argumentName = this.argumentNames[i]; - - if (i > 0) { - retArr.push(', '); + if (pad) { + ret = Array.from(ret); + while (ret.length < 3) { + ret.push(1); } - retArr.push('user_'); - retArr.push(argumentName); } - - retArr.push(') {\n'); - } - - for (let i = 0; i < ast.body.body.length; ++i) { - this.astGeneric(ast.body.body[i], retArr); - retArr.push('\n'); - } - - if (!this.isRootKernel) { - retArr.push('}\n'); - } - return retArr; - } - - astReturnStatement(ast, retArr) { - const type = this.returnType || this.getType(ast.argument); - - if (!this.returnType) { - this.returnType = type; - } - - if (this.isRootKernel) { - retArr.push(this.leadingReturnStatement); - this.astGeneric(ast.argument, retArr); - retArr.push(';\n'); - retArr.push(this.followingReturnStatement); - retArr.push('continue;\n'); - } else if (this.isSubKernel) { - retArr.push(`subKernelResult_${ this.name } = `); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - retArr.push(`return subKernelResult_${ this.name };`); - } else { - retArr.push('return '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - } - return retArr; - } - - astLiteral(ast, retArr) { - - if (isNaN(ast.value)) { - throw this.astErrorOutput( - 'Non-numeric literal not supported : ' + ast.value, - ast - ); - } - - retArr.push(ast.value); - - return retArr; - } - - astBinaryExpression(ast, retArr) { - retArr.push('('); - this.astGeneric(ast.left, retArr); - retArr.push(ast.operator); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - return retArr; - } - - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput( - 'IdentifierExpression - not an Identifier', - idtNode - ); - } - - switch (idtNode.name) { - case 'Infinity': - retArr.push('Infinity'); - break; - default: - if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { - retArr.push('constants_' + idtNode.name); - } else { - retArr.push('user_' + idtNode.name); + return new Int32Array(ret); + }, + flatten2dArrayTo(array, target) { + let offset = 0; + for (let y = 0; y < array.length; y++) { + target.set(array[y], offset); + offset += array[y].length; + } + }, + flatten3dArrayTo(array, target) { + let offset = 0; + for (let z = 0; z < array.length; z++) { + for (let y = 0; y < array[z].length; y++) { + target.set(array[z][y], offset); + offset += array[z][y].length; } - } - - return retArr; - } - - astForStatement(forNode, retArr) { - if (forNode.type !== 'ForStatement') { - throw this.astErrorOutput('Invalid for statement', forNode); - } - - const initArr = []; - const testArr = []; - const updateArr = []; - const bodyArr = []; - let isSafe = null; - - if (forNode.init) { - this.pushState('in-for-loop-init'); - this.astGeneric(forNode.init, initArr); - for (let i = 0; i < initArr.length; i++) { - if (initArr[i].includes && initArr[i].includes(',')) { - isSafe = false; + } + }, + flatten4dArrayTo(array, target) { + let offset = 0; + for (let l = 0; l < array.length; l++) { + for (let z = 0; z < array[l].length; z++) { + for (let y = 0; y < array[l][z].length; y++) { + target.set(array[l][z][y], offset); + offset += array[l][z][y].length; + } } } - this.popState('in-for-loop-init'); - } else { - isSafe = false; - } - - if (forNode.test) { - this.astGeneric(forNode.test, testArr); - } else { - isSafe = false; - } - - if (forNode.update) { - this.astGeneric(forNode.update, updateArr); - } else { - isSafe = false; - } - - if (forNode.body) { - this.pushState('loop-body'); - this.astGeneric(forNode.body, bodyArr); - this.popState('loop-body'); - } - - if (isSafe === null) { - isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); - } - - if (isSafe) { - retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); - retArr.push(bodyArr.join('')); - retArr.push('}\n'); - } else { - const iVariableName = this.getInternalVariableName('safeI'); - if (initArr.length > 0) { - retArr.push(initArr.join(''), ';\n'); + }, + flattenTo(array, target) { + if (isArray(array[0])) { + if (isArray(array[0][0])) { + if (isArray(array[0][0][0])) { + utils$1.flatten4dArrayTo(array, target); + } else { + utils$1.flatten3dArrayTo(array, target); + } + } else { + utils$1.flatten2dArrayTo(array, target); + } + } else { + target.set(array); } - retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) { - retArr.push(`if (!${testArr.join('')}) break;\n`); + }, + splitArray(array, part) { + const result = []; + for (let i = 0; i < array.length; i += part) { + result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part)); } - retArr.push(bodyArr.join('')); - retArr.push(`\n${updateArr.join('')};`); - retArr.push('}\n'); - } - return retArr; - } - - astWhileStatement(whileNode, retArr) { - if (whileNode.type !== 'WhileStatement') { - throw this.astErrorOutput( - 'Invalid while statement', - whileNode - ); - } - - retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); - retArr.push('if ('); - this.astGeneric(whileNode.test, retArr); - retArr.push(') {\n'); - this.astGeneric(whileNode.body, retArr); - retArr.push('} else {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - } - - astDoWhileStatement(doWhileNode, retArr) { - if (doWhileNode.type !== 'DoWhileStatement') { - throw this.astErrorOutput( - 'Invalid while statement', - doWhileNode - ); - } - - retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); - this.astGeneric(doWhileNode.body, retArr); - retArr.push('if (!'); - this.astGeneric(doWhileNode.test, retArr); - retArr.push(') {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - - } - - astAssignmentExpression(assNode, retArr) { - const declaration = this.getDeclaration(assNode.left); - if (declaration && !declaration.assignable) { - throw this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode); - } - this.astGeneric(assNode.left, retArr); - retArr.push(assNode.operator); - this.astGeneric(assNode.right, retArr); - return retArr; - } - - astBlockStatement(bNode, retArr) { - if (this.isState('loop-body')) { - this.pushState('block-body'); - for (let i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); + return result; + }, + getAstString, + allPropertiesOf(obj) { + const props = []; + do { + props.push.apply(props, Object.getOwnPropertyNames(obj)); + } while (obj = Object.getPrototypeOf(obj)); + return props; + }, + linesToString(lines) { + if (lines.length > 0) { + return lines.join(';\n') + ';\n'; + } else { + return '\n'; } - this.popState('block-body'); - } else { - retArr.push('{\n'); - for (let i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); + }, + warnDeprecated, + functionToIFunction, + flipPixels(pixels, width, height) { + const halfHeight = height / 2 | 0; + const bytesPerRow = width * 4; + const temp = new Uint8ClampedArray(width * 4); + const result = pixels.slice(0); + for (let y = 0; y < halfHeight; ++y) { + const topOffset = y * bytesPerRow; + const bottomOffset = (height - y - 1) * bytesPerRow; + temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); + result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); + result.set(temp, bottomOffset); } - retArr.push('}\n'); - } - return retArr; - } - - astVariableDeclaration(varDecNode, retArr) { - if (varDecNode.kind === 'var' && this.warnVarUsage) { - this.varWarn(); - } - retArr.push(`${varDecNode.kind} `); - const { declarations } = varDecNode; - for (let i = 0; i < declarations.length; i++) { - if (i > 0) { - retArr.push(','); + return result; + }, + erectPackedFloat: (array, width) => { + return array.subarray(0, width); + }, + erect2DPackedFloat: (array, width, height) => { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xStart = y * width; + const xEnd = xStart + width; + yResults[y] = array.subarray(xStart, xEnd); } - this.astGeneric(declarations[i], retArr); - } - if (!this.isState('in-for-loop-init')) { - retArr.push(';'); - } - return retArr; - } - - astIfStatement(ifNode, retArr) { - retArr.push('if ('); - this.astGeneric(ifNode.test, retArr); - retArr.push(')'); - if (ifNode.consequent.type === 'BlockStatement') { - this.astGeneric(ifNode.consequent, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.consequent, retArr); - retArr.push('\n}\n'); - } - - if (ifNode.alternate) { - retArr.push('else '); - if (ifNode.alternate.type === 'BlockStatement') { - this.astGeneric(ifNode.alternate, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.alternate, retArr); - retArr.push('\n}\n'); + return yResults; + }, + erect3DPackedFloat: (array, width, height, depth) => { + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xStart = (z * height * width) + y * width; + const xEnd = xStart + width; + yResults[y] = array.subarray(xStart, xEnd); + } + zResults[z] = yResults; + } + return zResults; + }, + erectMemoryOptimizedFloat: (array, width) => { + return array.subarray(0, width); + }, + erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat, + erectFloat: (array, width) => { + const xResults = new Float32Array(width); + let i = 0; + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; } - } - return retArr; - - } - - astSwitchStatement(ast, retArr) { - const { discriminant, cases } = ast; - retArr.push('switch ('); - this.astGeneric(discriminant, retArr); - retArr.push(') {\n'); - for (let i = 0; i < cases.length; i++) { - if (cases[i].test === null) { - retArr.push('default:\n'); - this.astGeneric(cases[i].consequent, retArr); - if (cases[i].consequent && cases[i].consequent.length > 0) { - retArr.push('break;\n'); + return xResults; + }, + erect2DFloat: (array, width, height) => { + const yResults = new Array(height); + let i = 0; + for (let y = 0; y < height; y++) { + const xResults = new Float32Array(width); + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; } - continue; - } - retArr.push('case '); - this.astGeneric(cases[i].test, retArr); - retArr.push(':\n'); - if (cases[i].consequent && cases[i].consequent.length > 0) { - this.astGeneric(cases[i].consequent, retArr); - retArr.push('break;\n'); + yResults[y] = xResults; } - } - retArr.push('\n}'); - } - - astThisExpression(tNode, retArr) { - retArr.push('_this'); - return retArr; - } - - astMemberExpression(mNode, retArr) { - const { - signature, - type, - property, - xProperty, - yProperty, - zProperty, - name, - origin - } = this.getMemberExpressionDetails(mNode); - switch (signature) { - case 'this.thread.value': - retArr.push(`_this.thread.${ name }`); - return retArr; - case 'this.output.value': - switch (name) { - case 'x': - retArr.push('outputX'); - break; - case 'y': - retArr.push('outputY'); - break; - case 'z': - retArr.push('outputZ'); - break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - return retArr; - case 'value': - throw this.astErrorOutput('Unexpected expression', mNode); - case 'value[]': - case 'value[][]': - case 'value[][][]': - case 'value.value': - if (origin === 'Math') { - retArr.push(Math[name]); - return retArr; + return yResults; + }, + erect3DFloat: (array, width, height, depth) => { + const zResults = new Array(depth); + let i = 0; + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Float32Array(width); + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; + } + yResults[y] = xResults; } - switch (property) { - case 'r': - retArr.push(`user_${ name }[0]`); - return retArr; - case 'g': - retArr.push(`user_${ name }[1]`); - return retArr; - case 'b': - retArr.push(`user_${ name }[2]`); - return retArr; - case 'a': - retArr.push(`user_${ name }[3]`); - return retArr; + zResults[z] = yResults; + } + return zResults; + }, + erectArray2: (array, width) => { + const xResults = new Array(width); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 2); + } + return xResults; + }, + erect2DArray2: (array, width, height) => { + const yResults = new Array(height); + const XResultsMax = width * 4; + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * XResultsMax; + let i = 0; + for (let x = 0; x < XResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 2); } - break; - case 'this.constants.value': - case 'this.constants.value[]': - case 'this.constants.value[][]': - case 'this.constants.value[][][]': - break; - case 'fn()[]': - this.astGeneric(mNode.object, retArr); - retArr.push('['); - this.astGeneric(mNode.property, retArr); - retArr.push(']'); - return retArr; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - - if (!mNode.computed) { - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - retArr.push(`${origin}_${name}`); - return retArr; + yResults[y] = xResults; } - } - - const markupName = `${origin}_${name}`; - - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - case 'HTMLImageArray': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'HTMLImage': - default: - let size; - let isInput; - if (origin === 'constants') { - const constant = this.constants[name]; - isInput = this.constantTypes[name] === 'Input'; - size = isInput ? constant.size : null; - } else { - isInput = this.isInput(name); - size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null; - } - retArr.push(`${ markupName }`); - if (zProperty && yProperty) { - if (isInput) { - retArr.push('[('); - this.astGeneric(zProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`); - this.astGeneric(yProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); - this.astGeneric(xProperty, retArr); - retArr.push(']'); - } else { - retArr.push('['); - this.astGeneric(zProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(yProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); - } - } else if (yProperty) { - if (isInput) { - retArr.push('[('); - this.astGeneric(yProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); - this.astGeneric(xProperty, retArr); - retArr.push(']'); - } else { - retArr.push('['); - this.astGeneric(yProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + return yResults; + }, + erect3DArray2: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 2); } - } else if (typeof xProperty !== 'undefined') { - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + yResults[y] = xResults; } - } - return retArr; - } - - astCallExpression(ast, retArr) { - if (ast.type !== 'CallExpression') { - throw this.astErrorOutput('Unknown CallExpression', ast); - } - let functionName = this.astMemberExpressionUnroll(ast.callee); - - if (this.calledFunctions.indexOf(functionName) < 0) { - this.calledFunctions.push(functionName); - } - - const isMathFunction = this.isAstMathFunction(ast); - - if (this.onFunctionCall) { - this.onFunctionCall(this.name, functionName, ast.arguments); - } - - retArr.push(functionName); - - retArr.push('('); - const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - - let argumentType = this.getType(argument); - if (!targetTypes[i]) { - this.triggerImplyArgumentType(functionName, i, argumentType, this); + zResults[z] = yResults; } - - if (i > 0) { - retArr.push(', '); + return zResults; + }, + erectArray3: (array, width) => { + const xResults = new Array(width); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 3); } - this.astGeneric(argument, retArr); - } - retArr.push(')'); - - return retArr; - } - - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('new Float32Array(['); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); + return xResults; + }, + erect2DArray3: (array, width, height) => { + const xResultsMax = width * 4; + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * xResultsMax; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 3); + } + yResults[y] = xResults; } - const subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr) - } - retArr.push('])'); - - return retArr; - } - - astDebuggerStatement(arrNode, retArr) { - retArr.push('debugger;'); - return retArr; - } -} - -module.exports = { - CPUFunctionNode -}; -},{"../function-node":9}],6:[function(require,module,exports){ -const { utils } = require('../../utils'); - -function constantsToString(constants, types) { - const results = []; - for (const name in types) { - if (!types.hasOwnProperty(name)) continue; - const type = types[name]; - const constant = constants[name]; - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - results.push(`${name}:${constant}`); - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); - break; - } - } - return `{ ${ results.join() } }`; -} - -function cpuKernelString(cpuKernel, name) { - const header = []; - const thisProperties = []; - const beforeReturn = []; - - const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString()); - - header.push( - ' const { context, canvas, constants: incomingConstants } = settings;', - ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`, - ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`, - ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`, - ); - - thisProperties.push( - ' constants: _constants,', - ' context,', - ' output,', - ' thread: {x: 0, y: 0, z: 0},', - ); - - if (cpuKernel.graphical) { - header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`); - header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`); - - const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), { - thisLookup: (propertyName) => { - switch (propertyName) { - case '_colorData': - return '_colorData'; - case '_imageData': - return '_imageData'; - case 'output': - return 'output'; - case 'thread': - return 'this.thread'; + return yResults; + }, + erect3DArray3: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 3); + } + yResults[y] = xResults; } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: (object, name) => { - return null; + zResults[z] = yResults; } - }); - - const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), { - thisLookup: (propertyName) => { - switch (propertyName) { - case '_colorData': - return '_colorData'; - case '_imageData': - return '_imageData'; - case 'output': - return 'output'; - case 'thread': - return 'this.thread'; + return zResults; + }, + erectArray4: (array, width) => { + const xResults = new Array(array); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 4); + } + return xResults; + }, + erect2DArray4: (array, width, height) => { + const xResultsMax = width * 4; + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * xResultsMax; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 4); } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: () => { - return null; + yResults[y] = xResults; } - }); - - thisProperties.push( - ' _imageData,', - ' _colorData,', - ` color: ${colorFn},`, - ); - - beforeReturn.push( - ` kernel.getPixels = ${getPixelsFn};` - ); - } - - const constantTypes = []; - const constantKeys = Object.keys(cpuKernel.constantTypes); - for (let i = 0; i < constantKeys.length; i++) { - constantTypes.push(cpuKernel.constantTypes[constantKeys]); - } - if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) { - const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), { - doNotDefine: ['canvas'], - findDependency: (object, name) => { - if (object === 'this') { - return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString(); + return yResults; + }, + erect3DArray4: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 4); + } + yResults[y] = xResults; } - return null; - }, - thisLookup: (propertyName) => { - switch (propertyName) { - case 'canvas': - return; - case 'context': - return 'context'; + zResults[z] = yResults; + } + return zResults; + }, + flattenFunctionToString: (source, settings) => { + const { findDependency, thisLookup, doNotDefine } = settings; + let flattened = settings.flattened; + if (!flattened) { + flattened = settings.flattened = {}; + } + const ast = acorn.parse(source); + const functionDependencies = []; + function flatten(ast) { + if (Array.isArray(ast)) { + const results = []; + for (let i = 0; i < ast.length; i++) { + results.push(flatten(ast[i])); + } + return results.join(''); + } + switch (ast.type) { + case 'Program': + return flatten(ast.body); + case 'FunctionDeclaration': + return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; + case 'BlockStatement': { + const result = []; + for (let i = 0; i < ast.body.length; i++) { + result.push(flatten(ast.body[i]), ';\n'); + } + return `{\n${result.join('')}}`; + } + case 'VariableDeclaration': + switch (ast.declarations[0].id.type) { + case 'ObjectPattern': { + const source = flatten(ast.declarations[0].init); + const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; + if (/this/.test(source)) { + const result = []; + const lookups = properties.map(thisLookup); + for (let i = 0; i < lookups.length; i++) { + const lookup = lookups[i]; + if (lookup === null) continue; + const property = properties[i]; + result.push(`${ast.kind} ${ property } = ${ lookup };\n`); + } + return result.join(''); + } + return `${ast.kind} { ${properties} } = ${source}`; + } + case 'ArrayPattern': + return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; + } + if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { + return ''; + } + return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`; + case 'CallExpression': { + if (ast.callee.property.name === 'subarray') { + return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') { + return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + if (ast.callee.object.type === 'ThisExpression') { + functionDependencies.push(findDependency('this', ast.callee.property.name)); + return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else if (ast.callee.object.name) { + const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name); + if (foundSource === null) { + return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else { + functionDependencies.push(foundSource); + return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + } else if (ast.callee.object.type === 'MemberExpression') { + return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else { + throw new Error('unknown ast.callee'); + } + } + case 'ReturnStatement': + return `return ${flatten(ast.argument)}`; + case 'BinaryExpression': + return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`; + case 'UnaryExpression': + if (ast.prefix) { + return `${ast.operator} ${flatten(ast.argument)}`; + } else { + return `${flatten(ast.argument)} ${ast.operator}`; + } + case 'ExpressionStatement': + return `(${flatten(ast.expression)})`; + case 'ArrowFunctionExpression': + return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`; + case 'Literal': + return ast.raw; + case 'Identifier': + return ast.name; + case 'MemberExpression': + if (ast.object.type === 'ThisExpression') { + return thisLookup(ast.property.name); + } + if (ast.computed) { + return `${flatten(ast.object)}[${flatten(ast.property)}]`; + } + return flatten(ast.object) + '.' + flatten(ast.property); + case 'ThisExpression': + return 'this'; + case 'NewExpression': + return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + case 'ForStatement': + return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`; + case 'AssignmentExpression': + return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`; + case 'UpdateExpression': + return `${flatten(ast.argument)}${ast.operator}`; + case 'IfStatement': + return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`; + case 'ThrowStatement': + return `throw ${flatten(ast.argument)}`; + case 'ObjectPattern': + return ast.properties.map(flatten).join(', '); + case 'ArrayPattern': + return ast.elements.map(flatten).join(', '); + case 'DebuggerStatement': + return 'debugger;'; + case 'ConditionalExpression': + return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`; + case 'Property': + if (ast.kind === 'init') { + return flatten(ast.key); + } } + throw new Error(`unhandled ast.type of ${ ast.type }`); } - }); - beforeReturn.push(flattenedImageTo3DArray); - thisProperties.push(` _mediaTo2DArray,`); - thisProperties.push(` _imageTo3DArray,`); - } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) { - const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), { - findDependency: (object, name) => { - return null; - }, - thisLookup: (propertyName) => { - switch (propertyName) { - case 'canvas': - return 'settings.canvas'; - case 'context': - return 'settings.context'; + const result = flatten(ast); + if (functionDependencies.length > 0) { + const flattenedFunctionDependencies = []; + for (let i = 0; i < functionDependencies.length; i++) { + const functionDependency = functionDependencies[i]; + if (!flattened[functionDependency]) { + flattened[functionDependency] = true; + } + flattenedFunctionDependencies.push(utils$1.flattenFunctionToString(functionDependency, settings) + ';\n'); } - throw new Error('unhandled thisLookup'); + return flattenedFunctionDependencies.join('') + result; } - }); - beforeReturn.push(flattenedImageTo2DArray); - thisProperties.push(` _mediaTo2DArray,`); - } - - return `function(settings) { -${ header.join('\n') } - for (const p in _constantTypes) { - if (!_constantTypes.hasOwnProperty(p)) continue; - const type = _constantTypes[p]; - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - if (incomingConstants.hasOwnProperty(p)) { - console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); - } - continue; - } - if (!incomingConstants.hasOwnProperty(p)) { - throw new Error('constant ' + p + ' not found'); - } - _constants[p] = incomingConstants[p]; - } - const kernel = (function() { -${cpuKernel._kernelString} - }) - .apply({ ${thisProperties.join('\n')} }); - ${ beforeReturn.join('\n') } - return kernel; -}`; -} - -module.exports = { - cpuKernelString -}; -},{"../../utils":111}],7:[function(require,module,exports){ -const { Kernel } = require('../kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { CPUFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const { cpuKernelString } = require('./kernel-string'); - -class CPUKernel extends Kernel { - static getFeatures() { - return this.features; - } - static get features() { - return Object.freeze({ - kernelMap: true, - isIntegerDivisionAccurate: true - }); - } - static get isSupported() { - return true; - } - static isContextMatch(context) { - return false; - } - static get mode() { - return 'cpu'; - } - - static nativeFunctionArguments() { - return null; - } - - static nativeFunctionReturnType() { - return null; - } - - static combineKernels(combinedKernel) { - return combinedKernel; - } - - constructor(source, settings) { - super(source, settings); - this.mergeSettings(source.settings || settings); - - this._imageData = null; - this._colorData = null; - this._kernelString = null; - this.thread = { - x: 0, - y: 0, - z: 0 - }; - this.translatedSources = null; - } - - initCanvas() { - if (typeof document !== 'undefined') { - return document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - return new OffscreenCanvas(0, 0); - } - } - - initContext() { - if (!this.canvas) return null; - return this.canvas.getContext('2d'); - } - - initPlugins(settings) { - return []; - } + return result; + }, + }; - validateSettings(args) { - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); + class Kernel { + static get isSupported() { + throw new Error(`"isSupported" not implemented on ${ this.name }`); + } + static isContextMatch(context) { + throw new Error(`"isContextMatch" not implemented on ${ this.name }`); + } + static getFeatures() { + throw new Error(`"getFeatures" not implemented on ${ this.name }`); + } + static destroyContext(context) { + throw new Error(`"destroyContext" called on ${ this.name }`); + } + static nativeFunctionArguments() { + throw new Error(`"nativeFunctionArguments" called on ${ this.name }`); + } + static nativeFunctionReturnType() { + throw new Error(`"nativeFunctionReturnType" called on ${ this.name }`); + } + static combineKernels() { + throw new Error(`"combineKernels" called on ${ this.name }`); + } + constructor(source, settings) { + if (typeof source !== 'object') { + if (typeof source !== 'string') { + throw new Error('source not a string'); + } + if (!isFunctionString(source)) { + throw new Error('source not a function string'); + } + } + this.useLegacyEncoder = false; + this.fallbackRequested = false; + this.onRequestFallback = null; + this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null; + this.argumentTypes = null; + this.argumentSizes = null; + this.argumentBitRatios = null; + this.kernelArguments = null; + this.kernelConstants = null; + this.source = source; + this.output = null; + this.debug = false; + this.graphical = false; + this.loopMaxIterations = 0; + this.constants = null; + this.constantTypes = null; + this.constantBitRatios = null; + this.dynamicArguments = false; + this.dynamicOutput = false; + this.canvas = null; + this.context = null; + this.checkContext = null; + this.gpu = null; + this.functions = null; + this.nativeFunctions = null; + this.injectedNative = null; + this.subKernels = null; + this.validate = true; + this.immutable = false; + this.pipeline = false; + this.precision = null; + this.tactic = 'balanced'; + this.plugins = null; + this.returnType = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.optimizeFloatMemory = null; + this.strictIntegers = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + } + mergeSettings(settings) { + for (let p in settings) { + if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue; + switch (p) { + case 'output': + if (!Array.isArray(settings.output)) { + this.setOutput(settings.output); + continue; + } + break; + case 'functions': + if (typeof settings.functions[0] === 'function') { + this.functions = settings.functions.map(source => functionToIFunction(source)); + continue; + } + break; + case 'graphical': + if (settings[p] && !settings.hasOwnProperty('precision')) { + this.precision = 'unsigned'; + } + this[p] = settings[p]; + continue; + } + this[p] = settings[p]; } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { - this.output = args[0].output; + if (!this.canvas) this.canvas = this.initCanvas(); + if (!this.context) this.context = this.initContext(); + if (!this.plugins) this.plugins = this.initPlugins(settings); + } + build() { + throw new Error(`"build" not defined on ${ this.constructor.name }`); + } + run() { + throw new Error(`"run" not defined on ${ this.constructor.name }`) + } + initCanvas() { + throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`); + } + initContext() { + throw new Error(`"initContext" not defined on ${ this.constructor.name }`); + } + initPlugins(settings) { + throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`); + } + setupArguments(args) { + this.kernelArguments = []; + if (!this.argumentTypes) { + if (!this.argumentTypes) { + this.argumentTypes = []; + for (let i = 0; i < args.length; i++) { + const argType = getVariableType(args[i], this.strictIntegers); + const type = argType === 'Integer' ? 'Number' : argType; + this.argumentTypes.push(type); + this.kernelArguments.push({ + type + }); + } + } } else { - throw new Error('Auto output not supported for input type: ' + argType); + for (let i = 0; i < this.argumentTypes.length; i++) { + this.kernelArguments.push({ + type: this.argumentTypes[i] + }); + } } - } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + this.argumentSizes = new Array(args.length); + this.argumentBitRatios = new Int32Array(args.length); + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + this.argumentSizes[i] = arg.constructor === Input ? arg.size : null; + this.argumentBitRatios[i] = this.getBitRatio(arg); + } + if (this.argumentNames.length !== args.length) { + throw new Error(`arguments are miss-aligned`); } } - - this.checkOutput(); - } - - translateSource() { - this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = '; - if (this.subKernels) { - const followingReturnStatement = [] - for (let i = 0; i < this.subKernels.length; i++) { - const { - name - } = this.subKernels[i]; - followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`); + setupConstants() { + this.kernelConstants = []; + let needsConstantTypes = this.constantTypes === null; + if (needsConstantTypes) { + this.constantTypes = {}; + } + this.constantBitRatios = {}; + if (this.constants) { + for (let name in this.constants) { + if (needsConstantTypes) { + const type = getVariableType(this.constants[name], this.strictIntegers); + this.constantTypes[name] = type; + this.kernelConstants.push({ + name, + type + }); + } else { + this.kernelConstants.push({ + name, + type: this.constantTypes[name] + }); + } + this.constantBitRatios[name] = this.getBitRatio(this.constants[name]); + } } - this.followingReturnStatement = followingReturnStatement.join(''); } - const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); - this.translatedSources = functionBuilder.getPrototypes('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + setOptimizeFloatMemory(flag) { + this.optimizeFloatMemory = flag; + return this; } - } - - build() { - this.setupConstants(); - this.setupArguments(arguments); - this.validateSettings(arguments); - this.translateSource(); - - if (this.graphical) { - const { - canvas, - output - } = this; - if (!canvas) { - throw new Error('no canvas available for using graphical output'); + setOutput(output) { + if (output.hasOwnProperty('x')) { + if (output.hasOwnProperty('y')) { + if (output.hasOwnProperty('z')) { + this.output = [output.x, output.y, output.z]; + } else { + this.output = [output.x, output.y]; + } + } else { + this.output = [output.x]; + } + } else { + this.output = output; } - const width = output[0]; - const height = output[1] || 1; - canvas.width = width; - canvas.height = height; - this._imageData = this.context.createImageData(width, height); - this._colorData = new Uint8ClampedArray(width * height * 4); + return this; } - - const kernelString = this.getKernelString(); - this.kernelString = kernelString; - - if (this.debug) { - console.log('Function output:'); - console.log(kernelString); + setDebug(flag) { + this.debug = flag; + return this; } - - try { - this.run = new Function([], kernelString).bind(this)(); - } catch (e) { - console.error('An error occurred compiling the javascript: ', e); + setGraphical(flag) { + this.graphical = flag; + this.precision = 'unsigned'; + return this; } - } - - color(r, g, b, a) { - if (typeof a === 'undefined') { - a = 1; + setLoopMaxIterations(max) { + this.loopMaxIterations = max; + return this; } - - r = Math.floor(r * 255); - g = Math.floor(g * 255); - b = Math.floor(b * 255); - a = Math.floor(a * 255); - - const width = this.output[0]; - const height = this.output[1]; - - const x = this.thread.x; - const y = height - this.thread.y - 1; - - const index = x + y * width; - - this._colorData[index * 4 + 0] = r; - this._colorData[index * 4 + 1] = g; - this._colorData[index * 4 + 2] = b; - this._colorData[index * 4 + 3] = a; - } - - getKernelString() { - if (this._kernelString !== null) return this._kernelString; - - let kernelThreadString = null; - let { - translatedSources - } = this; - if (translatedSources.length > 1) { - translatedSources = translatedSources.filter(fn => { - if (/^function/.test(fn)) return fn; - kernelThreadString = fn; - return false; - }) - } else { - kernelThreadString = translatedSources.shift(); - } - return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() }; - ${ this.injectedNative || '' } - const _this = this; - ${ this._processConstants() } - return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { - ${ this._processArguments() } - ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) } - ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' } - };`; - } - - toString() { - return cpuKernelString(this); - } - - _getLoopMaxString() { - return ( - this.loopMaxIterations ? - ` ${ parseInt(this.loopMaxIterations) };` : - ' 1000;' - ); - } - - _processConstants() { - if (!this.constants) return ''; - - const result = []; - for (let p in this.constants) { - const type = this.constantTypes[p]; - switch (type) { - case 'HTMLImage': - case 'HTMLVideo': - result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`); - break; - case 'HTMLImageArray': - result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`); - break; - case 'Input': - result.push(` const constants_${p} = this.constants.${p}.value;\n`); - break; - default: - result.push(` const constants_${p} = this.constants.${p};\n`); - } + setConstants(constants) { + this.constants = constants; + return this; } - return result.join(''); - } - - _processArguments() { - const result = []; - for (let i = 0; i < this.argumentTypes.length; i++) { - const variableName = `user_${this.argumentNames[i]}`; - switch (this.argumentTypes[i]) { - case 'HTMLImage': - case 'HTMLVideo': - result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`); - break; - case 'HTMLImageArray': - result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`); - break; - case 'Input': - result.push(` ${variableName} = ${variableName}.value;\n`); - break; - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'NumberTexture': - case 'MemoryOptimizedNumberTexture': - result.push(` - if (${variableName}.toArray) { - if (!_this.textureCache) { - _this.textureCache = []; - _this.arrayCache = []; - } - const textureIndex = _this.textureCache.indexOf(${variableName}); - if (textureIndex !== -1) { - ${variableName} = _this.arrayCache[textureIndex]; + setConstantTypes(constantTypes) { + this.constantTypes = constantTypes; + return this; + } + setFunctions(functions) { + if (typeof functions[0] === 'function') { + this.functions = functions.map(source => functionToIFunction(source)); } else { - _this.textureCache.push(${variableName}); - ${variableName} = ${variableName}.toArray(); - _this.arrayCache.push(${variableName}); - } - }`); - break; + this.functions = functions; } + return this; } - return result.join(''); - } - - _mediaTo2DArray(media) { - const canvas = this.canvas; - const width = media.width > 0 ? media.width : media.videoWidth; - const height = media.height > 0 ? media.height : media.videoHeight; - if (canvas.width < width) { - canvas.width = width; - } - if (canvas.height < height) { - canvas.height = height; - } - const ctx = this.context; - ctx.drawImage(media, 0, 0, width, height); - const pixelsData = ctx.getImageData(0, 0, width, height).data; - const imageArray = new Array(height); - let index = 0; - for (let y = height - 1; y >= 0; y--) { - const row = imageArray[y] = new Array(width); - for (let x = 0; x < width; x++) { - const pixel = new Float32Array(4); - pixel[0] = pixelsData[index++] / 255; - pixel[1] = pixelsData[index++] / 255; - pixel[2] = pixelsData[index++] / 255; - pixel[3] = pixelsData[index++] / 255; - row[x] = pixel; - } + setNativeFunctions(nativeFunctions) { + this.nativeFunctions = nativeFunctions; + return this; } - return imageArray; - } - - getPixels(flip) { - const [width, height] = this.output; - return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0); - } - - _imageTo3DArray(images) { - const imagesArray = new Array(images.length); - for (let i = 0; i < images.length; i++) { - imagesArray[i] = this._mediaTo2DArray(images[i]); + setInjectedNative(injectedNative) { + this.injectedNative = injectedNative; + return this; } - return imagesArray; - } - - _resultKernelBody(kernelString) { - switch (this.output.length) { - case 1: - return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); - case 2: - return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); - case 3: - return this._resultKernel3DLoop(kernelString) + this._kernelOutput(); - default: - throw new Error('unsupported size kernel'); + setPipeline(flag) { + this.pipeline = flag; + return this; } - } - - _graphicalKernelBody(kernelThreadString) { - switch (this.output.length) { - case 2: - return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput(); - default: - throw new Error('unsupported size kernel'); + setPrecision(flag) { + this.precision = flag; + return this; } - } - - _graphicalOutput() { - return ` - this._imageData.data.set(this._colorData); - this.context.putImageData(this._imageData, 0, 0); - return;` - } - - _getKernelResultTypeConstructorString() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return 'Float32Array'; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return 'Array'; - default: - if (this.graphical) { - return 'Float32Array'; - } - throw new Error(`unhandled returnType ${ this.returnType }`); + setOutputToTexture(flag) { + warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); + this.pipeline = flag; + return this; } - } - - _resultKernel1DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const result = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - ${ kernelString } - }`; - } - - _resultKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const result = new Array(outputY); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - const resultX = result[y] = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } - } - }`; - } - - _graphicalKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } - } - }`; - } - - _resultKernel3DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - const result = new Array(outputZ); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let z = 0; z < outputZ; z++) { - this.thread.z = z; - const resultY = result[z] = new Array(outputY); - ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.y = y; - const resultX = resultY[y] = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } - } - } - }`; - } - - _kernelOutput() { - if (!this.subKernels) { - return '\n return result;'; + setImmutable(flag) { + this.immutable = flag; + return this; } - return `\n return { - result: result, - ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') } - };`; - } - - _mapSubKernels(fn) { - return this.subKernels === null ? [''] : - this.subKernels.map(fn); - } - - - - destroy(removeCanvasReference) { - if (removeCanvasReference) { - delete this.canvas; + setCanvas(canvas) { + this.canvas = canvas; + return this; } - } - - static destroyContext(context) {} - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON(); - return json; - } - - setOutput(output) { - super.setOutput(output); - const [width, height] = this.output; - if (this.graphical) { - this._imageData = this.context.createImageData(width, height); - this._colorData = new Uint8ClampedArray(width * height * 4); + setStrictIntegers(flag) { + this.strictIntegers = flag; + return this; } - } -} - -module.exports = { - CPUKernel -}; -},{"../../utils":111,"../function-builder":8,"../kernel":34,"./function-node":5,"./kernel-string":6}],8:[function(require,module,exports){ -class FunctionBuilder { - static fromKernel(kernel, FunctionNode, extraNodeOptions) { - const { - kernelArguments, - kernelConstants, - argumentNames, - argumentSizes, - argumentBitRatios, - constants, - constantBitRatios, - debug, - loopMaxIterations, - nativeFunctions, - output, - optimizeFloatMemory, - precision, - plugins, - source, - subKernels, - functions, - leadingReturnStatement, - followingReturnStatement, - dynamicArguments, - dynamicOutput, - warnVarUsage, - } = kernel; - - const argumentTypes = new Array(kernelArguments.length); - const constantTypes = {}; - - for (let i = 0; i < kernelArguments.length; i++) { - argumentTypes[i] = kernelArguments[i].type; + setDynamicOutput(flag) { + this.dynamicOutput = flag; + return this; } - - for (let i = 0; i < kernelConstants.length; i++) { - const kernelConstant = kernelConstants[i]; - constantTypes[kernelConstant.name] = kernelConstant.type; + setHardcodeConstants(flag) { + warnDeprecated('method', 'setHardcodeConstants'); + this.setDynamicOutput(flag); + this.setDynamicArguments(flag); + return this; } - - const needsArgumentType = (functionName, index) => { - return functionBuilder.needsArgumentType(functionName, index); - }; - - const assignArgumentType = (functionName, index, type) => { - functionBuilder.assignArgumentType(functionName, index, type); - }; - - const lookupReturnType = (functionName, ast, requestingNode) => { - return functionBuilder.lookupReturnType(functionName, ast, requestingNode); - }; - - const lookupFunctionArgumentTypes = (functionName) => { - return functionBuilder.lookupFunctionArgumentTypes(functionName); - }; - - const lookupFunctionArgumentName = (functionName, argumentIndex) => { - return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex); - }; - - const lookupFunctionArgumentBitRatio = (functionName, argumentName) => { - return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName); - }; - - const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => { - functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode); - }; - - const triggerImplyArgumentBitRatio = (functionName, argumentName, calleeFunctionName, argumentIndex) => { - functionBuilder.assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex); - }; - - const onFunctionCall = (functionName, calleeFunctionName, args) => { - functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); - }; - - const onNestedFunction = (ast, returnType) => { - const argumentNames = []; - for (let i = 0; i < ast.params.length; i++) { - argumentNames.push(ast.params[i].name); - } - const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { - returnType: null, - ast, - name: ast.id.name, - argumentNames, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - warnVarUsage, - })); - nestedFunction.traceFunctionAST(ast); - functionBuilder.addFunctionNode(nestedFunction); - }; - - const nodeOptions = Object.assign({ - isRootKernel: false, - onNestedFunction, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - optimizeFloatMemory, - precision, - constants, - constantTypes, - constantBitRatios, - debug, - loopMaxIterations, - output, - plugins, - dynamicArguments, - dynamicOutput, - }, extraNodeOptions || {}); - - const rootNodeOptions = Object.assign({}, nodeOptions, { - isRootKernel: true, - name: 'kernel', - argumentNames, - argumentTypes, - argumentSizes, - argumentBitRatios, - leadingReturnStatement, - followingReturnStatement, - }); - - if (typeof source === 'object' && source.functionNodes) { - return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode); + setDynamicArguments(flag) { + this.dynamicArguments = flag; + return this; } - - const rootNode = new FunctionNode(source, rootNodeOptions); - - let functionNodes = null; - if (functions) { - functionNodes = functions.map((fn) => new FunctionNode(fn.source, { - returnType: fn.returnType, - argumentTypes: fn.argumentTypes, - output, - plugins, - constants, - constantTypes, - constantBitRatios, - optimizeFloatMemory, - precision, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - onNestedFunction, - })); + setUseLegacyEncoder(flag) { + this.useLegacyEncoder = flag; + return this; } - - let subKernelNodes = null; - if (subKernels) { - subKernelNodes = subKernels.map((subKernel) => { - const { name, source } = subKernel; - return new FunctionNode(source, Object.assign({}, nodeOptions, { - name, - isSubKernel: true, - isRootKernel: false, - })); - }); + setWarnVarUsage(flag) { + this.warnVarUsage = flag; + return this; } - - const functionBuilder = new FunctionBuilder({ - kernel, - rootNode, - functionNodes, - nativeFunctions, - subKernelNodes - }); - - return functionBuilder; - } - - constructor(settings) { - settings = settings || {}; - this.kernel = settings.kernel; - this.rootNode = settings.rootNode; - this.functionNodes = settings.functionNodes || []; - this.subKernelNodes = settings.subKernelNodes || []; - this.nativeFunctions = settings.nativeFunctions || []; - this.functionMap = {}; - this.nativeFunctionNames = []; - this.lookupChain = []; - this.argumentChain = []; - this.functionNodeDependencies = {}; - this.functionCalls = {}; - - if (this.rootNode) { - this.functionMap['kernel'] = this.rootNode; + getCanvas() { + warnDeprecated('method', 'getCanvas'); + return this.canvas; } - - if (this.functionNodes) { - for (let i = 0; i < this.functionNodes.length; i++) { - this.functionMap[this.functionNodes[i].name] = this.functionNodes[i]; - } + getWebGl() { + warnDeprecated('method', 'getWebGl'); + return this.context; } - - if (this.subKernelNodes) { - for (let i = 0; i < this.subKernelNodes.length; i++) { - this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i]; - } + setContext(context) { + this.context = context; + return this; } - - if (this.nativeFunctions) { - for (let i = 0; i < this.nativeFunctions.length; i++) { - const nativeFunction = this.nativeFunctions[i]; - this.nativeFunctionNames.push(nativeFunction.name); + setArgumentTypes(argumentTypes) { + if (Array.isArray(argumentTypes)) { + this.argumentTypes = argumentTypes; + } else { + this.argumentTypes = []; + for (const p in argumentTypes) { + const argumentIndex = this.argumentNames.indexOf(p); + if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); + this.argumentTypes[argumentIndex] = argumentTypes[p]; + } } + return this; } - } - - addFunctionNode(functionNode) { - if (!functionNode.name) throw new Error('functionNode.name needs set'); - this.functionMap[functionNode.name] = functionNode; - if (functionNode.isRootKernel) { - this.rootNode = functionNode; + setTactic(tactic) { + this.tactic = tactic; + return this; } - } - - traceFunctionCalls(functionName, retList) { - functionName = functionName || 'kernel'; - retList = retList || []; - - if (this.nativeFunctionNames.indexOf(functionName) > -1) { - if (retList.indexOf(functionName) === -1) { - retList.push(functionName); + requestFallback(args) { + if (!this.onRequestFallback) { + throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); } - return retList; + this.fallbackRequested = true; + return this.onRequestFallback(args); } - - const functionNode = this.functionMap[functionName]; - if (functionNode) { - const functionIndex = retList.indexOf(functionName); - if (functionIndex === -1) { - retList.push(functionName); - functionNode.toString(); - for (let i = 0; i < functionNode.calledFunctions.length; ++i) { - this.traceFunctionCalls(functionNode.calledFunctions[i], retList); - } - } else { - const dependantFunctionName = retList.splice(functionIndex, 1)[0]; - retList.push(dependantFunctionName); + validateSettings() { + throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`); + } + addSubKernel(subKernel) { + if (this.subKernels === null) { + this.subKernels = []; } + if (!subKernel.source) throw new Error('subKernel missing "source" property'); + if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property'); + if (!subKernel.name) throw new Error('subKernel missing "name" property'); + this.subKernels.push(subKernel); + return this; } - - return retList; - } - - getPrototypeString(functionName) { - return this.getPrototypes(functionName).join('\n'); - } - - getPrototypes(functionName) { - if (this.rootNode) { - this.rootNode.toString(); + destroy(removeCanvasReferences) { + throw new Error(`"destroy" called on ${ this.constructor.name }`); + } + getBitRatio(value) { + if (this.precision === 'single') { + return 4; + } else if (Array.isArray(value[0])) { + return this.getBitRatio(value[0]); + } else if (value.constructor === Input) { + return this.getBitRatio(value.value); + } + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + return 1; + case Uint16Array: + case Int16Array: + return 2; + case Float32Array: + case Int32Array: + default: + return 4; + } } - if (functionName) { - return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + getPixels() { + throw new Error(`"getPixels" called on ${ this.constructor.name }`); } - return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); - } - - getStringFromFunctionNames(functionList) { - const ret = []; - for (let i = 0; i < functionList.length; ++i) { - const node = this.functionMap[functionList[i]]; - if (node) { - ret.push(this.functionMap[functionList[i]].toString()); + checkOutput() { + if (!this.output || !isArray(this.output)) throw new Error('kernel.output not an array'); + if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value'); + for (let i = 0; i < this.output.length; i++) { + if (isNaN(this.output[i]) || this.output[i] < 1) { + throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`); + } } } - return ret.join('\n'); + toJSON() { + const settings = { + output: this.output, + threadDim: this.threadDim, + pipeline: this.pipeline, + argumentNames: this.argumentNames, + argumentsTypes: this.argumentTypes, + constants: this.constants, + pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null, + returnType: this.returnType, + }; + return { + settings + }; + } } - getPrototypesFromFunctionNames(functionList) { - const ret = []; - for (let i = 0; i < functionList.length; ++i) { - const functionName = functionList[i]; - const functionIndex = this.nativeFunctionNames.indexOf(functionName); - if (functionIndex > -1) { - ret.push(this.nativeFunctions[functionIndex].source); - continue; + class FunctionBuilder { + static fromKernel(kernel, FunctionNode, extraNodeOptions) { + const { + kernelArguments, + kernelConstants, + argumentNames, + argumentSizes, + argumentBitRatios, + constants, + constantBitRatios, + debug, + loopMaxIterations, + nativeFunctions, + output, + optimizeFloatMemory, + precision, + plugins, + source, + subKernels, + functions, + leadingReturnStatement, + followingReturnStatement, + dynamicArguments, + dynamicOutput, + warnVarUsage, + } = kernel; + const argumentTypes = new Array(kernelArguments.length); + const constantTypes = {}; + for (let i = 0; i < kernelArguments.length; i++) { + argumentTypes[i] = kernelArguments[i].type; + } + for (let i = 0; i < kernelConstants.length; i++) { + const kernelConstant = kernelConstants[i]; + constantTypes[kernelConstant.name] = kernelConstant.type; + } + const needsArgumentType = (functionName, index) => { + return functionBuilder.needsArgumentType(functionName, index); + }; + const assignArgumentType = (functionName, index, type) => { + functionBuilder.assignArgumentType(functionName, index, type); + }; + const lookupReturnType = (functionName, ast, requestingNode) => { + return functionBuilder.lookupReturnType(functionName, ast, requestingNode); + }; + const lookupFunctionArgumentTypes = (functionName) => { + return functionBuilder.lookupFunctionArgumentTypes(functionName); + }; + const lookupFunctionArgumentName = (functionName, argumentIndex) => { + return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex); + }; + const lookupFunctionArgumentBitRatio = (functionName, argumentName) => { + return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName); + }; + const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => { + functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode); + }; + const triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => { + functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex); + }; + const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => { + return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName); + }; + const onFunctionCall = (functionName, calleeFunctionName, args) => { + functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); + }; + const onNestedFunction = (ast, returnType) => { + const argumentNames = []; + for (let i = 0; i < ast.params.length; i++) { + argumentNames.push(ast.params[i].name); + } + const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { + returnType: null, + ast, + name: ast.id.name, + argumentNames, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + warnVarUsage, + })); + nestedFunction.traceFunctionAST(ast); + functionBuilder.addFunctionNode(nestedFunction); + }; + const nodeOptions = Object.assign({ + isRootKernel: false, + onNestedFunction, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + optimizeFloatMemory, + precision, + constants, + constantTypes, + constantBitRatios, + debug, + loopMaxIterations, + output, + plugins, + dynamicArguments, + dynamicOutput, + }, extraNodeOptions || {}); + const rootNodeOptions = Object.assign({}, nodeOptions, { + isRootKernel: true, + name: 'kernel', + argumentNames, + argumentTypes, + argumentSizes, + argumentBitRatios, + leadingReturnStatement, + followingReturnStatement, + }); + if (typeof source === 'object' && source.functionNodes) { + return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode); + } + const rootNode = new FunctionNode(source, rootNodeOptions); + let functionNodes = null; + if (functions) { + functionNodes = functions.map((fn) => new FunctionNode(fn.source, { + returnType: fn.returnType, + argumentTypes: fn.argumentTypes, + output, + plugins, + constants, + constantTypes, + constantBitRatios, + optimizeFloatMemory, + precision, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + })); } - const node = this.functionMap[functionName]; - if (node) { - ret.push(node.toString()); + let subKernelNodes = null; + if (subKernels) { + subKernelNodes = subKernels.map((subKernel) => { + const { name, source } = subKernel; + return new FunctionNode(source, Object.assign({}, nodeOptions, { + name, + isSubKernel: true, + isRootKernel: false, + })); + }); } + const functionBuilder = new FunctionBuilder({ + kernel, + rootNode, + functionNodes, + nativeFunctions, + subKernelNodes + }); + return functionBuilder; } - return ret; - } - - toJSON() { - return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => { - const nativeIndex = this.nativeFunctions.indexOf(name); - if (nativeIndex > -1) { - return { - name, - source: this.nativeFunctions[nativeIndex].source - }; - } else if (this.functionMap[name]) { - return this.functionMap[name].toJSON(); - } else { - throw new Error(`function ${ name } not found`); + constructor(settings) { + settings = settings || {}; + this.kernel = settings.kernel; + this.rootNode = settings.rootNode; + this.functionNodes = settings.functionNodes || []; + this.subKernelNodes = settings.subKernelNodes || []; + this.nativeFunctions = settings.nativeFunctions || []; + this.functionMap = {}; + this.nativeFunctionNames = []; + this.lookupChain = []; + this.argumentChain = []; + this.functionNodeDependencies = {}; + this.functionCalls = {}; + if (this.rootNode) { + this.functionMap['kernel'] = this.rootNode; + } + if (this.functionNodes) { + for (let i = 0; i < this.functionNodes.length; i++) { + this.functionMap[this.functionNodes[i].name] = this.functionNodes[i]; + } + } + if (this.subKernelNodes) { + for (let i = 0; i < this.subKernelNodes.length; i++) { + this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i]; + } + } + if (this.nativeFunctions) { + for (let i = 0; i < this.nativeFunctions.length; i++) { + const nativeFunction = this.nativeFunctions[i]; + this.nativeFunctionNames.push(nativeFunction.name); + } } - }); - } - - fromJSON(jsonFunctionNodes, FunctionNode) { - this.functionMap = {}; - for (let i = 0; i < jsonFunctionNodes.length; i++) { - const jsonFunctionNode = jsonFunctionNodes[i]; - this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings); - } - return this; - } - - getString(functionName) { - if (functionName) { - return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse()); } - return this.getStringFromFunctionNames(Object.keys(this.functionMap)); - } - - lookupReturnType(functionName, ast, requestingNode) { - if (ast.type !== 'CallExpression') { - throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`); + addFunctionNode(functionNode) { + if (!functionNode.name) throw new Error('functionNode.name needs set'); + this.functionMap[functionNode.name] = functionNode; + if (functionNode.isRootKernel) { + this.rootNode = functionNode; + } } - if (this._isNativeFunction(functionName)) { - return this._lookupNativeFunctionReturnType(functionName); - } else if (this._isFunction(functionName)) { - const node = this._getFunction(functionName); - if (node.returnType) { - return node.returnType; - } else { - for (let i = 0; i < this.lookupChain.length; i++) { - if (this.lookupChain[i].ast === ast) { - if (node.argumentTypes.length === 0 && ast.arguments.length > 0) { - const args = ast.arguments; - for (let j = 0; j < args.length; j++) { - this.lookupChain.push({ - name: requestingNode.name, - ast: args[i], - requestingNode - }); - node.argumentTypes[j] = requestingNode.getType(args[j]); - this.lookupChain.pop(); - } - return node.returnType = node.getType(node.getJsAST()); - } - - throw new Error('circlical logic detected!'); + traceFunctionCalls(functionName, retList) { + functionName = functionName || 'kernel'; + retList = retList || []; + if (this.nativeFunctionNames.indexOf(functionName) > -1) { + if (retList.indexOf(functionName) === -1) { + retList.push(functionName); + } + return retList; + } + const functionNode = this.functionMap[functionName]; + if (functionNode) { + const functionIndex = retList.indexOf(functionName); + if (functionIndex === -1) { + retList.push(functionName); + functionNode.toString(); + for (let i = 0; i < functionNode.calledFunctions.length; ++i) { + this.traceFunctionCalls(functionNode.calledFunctions[i], retList); } + } else { + const dependantFunctionName = retList.splice(functionIndex, 1)[0]; + retList.push(dependantFunctionName); } - this.lookupChain.push({ - name: requestingNode.name, - ast, - requestingNode - }); - const type = node.getType(node.getJsAST()); - this.lookupChain.pop(); - return node.returnType = type; } + return retList; } - - return null; - } - - _getFunction(functionName) { - if (!this._isFunction(functionName)) { - new Error(`Function ${functionName} not found`); - } - return this.functionMap[functionName]; - } - - _isFunction(functionName) { - return Boolean(this.functionMap[functionName]); - } - - _getNativeFunction(functionName) { - for (let i = 0; i < this.nativeFunctions.length; i++) { - if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i]; - } - return null; - } - - _isNativeFunction(functionName) { - return Boolean(this._getNativeFunction(functionName)); - } - - _lookupNativeFunctionReturnType(functionName) { - let nativeFunction = this._getNativeFunction(functionName); - if (nativeFunction) { - return nativeFunction.returnType; - } - throw new Error(`Native function ${ functionName } not found`); - } - - lookupFunctionArgumentTypes(functionName) { - if (this._isNativeFunction(functionName)) { - return this._getNativeFunction(functionName).argumentTypes; - } else if (this._isFunction(functionName)) { - return this._getFunction(functionName).argumentTypes; - } - return null; - } - - lookupFunctionArgumentName(functionName, argumentIndex) { - return this._getFunction(functionName).argumentNames[argumentIndex]; - } - - lookupFunctionArgumentBitRatio(functionName, argumentName) { - if (!this._isFunction(functionName)) { - throw new Error('function not found'); + getPrototypeString(functionName) { + return this.getPrototypes(functionName).join('\n'); } - if (this.rootNode.name === functionName) { - const i = this.rootNode.argumentNames.indexOf(argumentName); - if (i !== -1) { - return this.rootNode.argumentBitRatios[i]; + getPrototypes(functionName) { + if (this.rootNode) { + this.rootNode.toString(); } + if (functionName) { + return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + } + return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); } - const node = this._getFunction(functionName); - const i = node.argumentNames.indexOf(argumentName); - if (i === -1) { - throw new Error('argument not found'); - } - const bitRatio = node.argumentBitRatios[i]; - if (typeof bitRatio !== 'number') { - throw new Error('argument bit ratio not found'); - } - return bitRatio; - } - - needsArgumentType(functionName, i) { - if (!this._isFunction(functionName)) return false; - const fnNode = this._getFunction(functionName); - return !fnNode.argumentTypes[i]; - } - - assignArgumentType(functionName, i, argumentType, requestingNode) { - if (!this._isFunction(functionName)) return; - const fnNode = this._getFunction(functionName); - if (!fnNode.argumentTypes[i]) { - fnNode.argumentTypes[i] = argumentType; - } - } - - assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex) { - const node = this._getFunction(functionName); - if (this._isNativeFunction(calleeFunctionName)) return null; - const calleeNode = this._getFunction(calleeFunctionName); - const i = node.argumentNames.indexOf(argumentName); - if (i === -1) { - throw new Error(`Argument ${argumentName} not found in arguments from function ${functionName}`); - } - const bitRatio = node.argumentBitRatios[i]; - if (typeof bitRatio !== 'number') { - throw new Error(`Bit ratio for argument ${argumentName} not found in function ${functionName}`); - } - if (!calleeNode.argumentBitRatios) { - calleeNode.argumentBitRatios = new Array(calleeNode.argumentNames.length); - } - const calleeBitRatio = calleeNode.argumentBitRatios[i]; - if (typeof calleeBitRatio === 'number') { - if (calleeBitRatio !== bitRatio) { - throw new Error(`Incompatible bit ratio found at function ${functionName} at argument ${argumentName}`); - } - return calleeBitRatio; - } - calleeNode.argumentBitRatios[i] = bitRatio; - return bitRatio; - } - - trackFunctionCall(functionName, calleeFunctionName, args) { - if (!this.functionNodeDependencies[functionName]) { - this.functionNodeDependencies[functionName] = new Set(); - this.functionCalls[functionName] = []; + getStringFromFunctionNames(functionList) { + const ret = []; + for (let i = 0; i < functionList.length; ++i) { + const node = this.functionMap[functionList[i]]; + if (node) { + ret.push(this.functionMap[functionList[i]].toString()); + } + } + return ret.join('\n'); } - this.functionNodeDependencies[functionName].add(calleeFunctionName); - this.functionCalls[functionName].push(args); - } - - getKernelResultType() { - return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast); - } - - getSubKernelResultType(index) { - const subKernelNode = this.subKernelNodes[index]; - let called = false; - for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) { - const functionCall = this.rootNode.functionCalls[functionCallIndex]; - if (functionCall.ast.callee.name === subKernelNode.name) { - called = true; + getPrototypesFromFunctionNames(functionList) { + const ret = []; + for (let i = 0; i < functionList.length; ++i) { + const functionName = functionList[i]; + const functionIndex = this.nativeFunctionNames.indexOf(functionName); + if (functionIndex > -1) { + ret.push(this.nativeFunctions[functionIndex].source); + continue; + } + const node = this.functionMap[functionName]; + if (node) { + ret.push(node.toString()); + } } + return ret; } - if (!called) { - throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); + toJSON() { + return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => { + const nativeIndex = this.nativeFunctions.indexOf(name); + if (nativeIndex > -1) { + return { + name, + source: this.nativeFunctions[nativeIndex].source + }; + } else if (this.functionMap[name]) { + return this.functionMap[name].toJSON(); + } else { + throw new Error(`function ${ name } not found`); + } + }); } - return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST()); - } - - getReturnTypes() { - const result = { - [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast), - }; - const list = this.traceFunctionCalls(this.rootNode.name); - for (let i = 0; i < list.length; i++) { - const functionName = list[i]; - const functionNode = this.functionMap[functionName]; - result[functionName] = functionNode.getType(functionNode.ast); + fromJSON(jsonFunctionNodes, FunctionNode) { + this.functionMap = {}; + for (let i = 0; i < jsonFunctionNodes.length; i++) { + const jsonFunctionNode = jsonFunctionNodes[i]; + this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings); + } + return this; } - return result; - } -} - -module.exports = { - FunctionBuilder -}; - -},{}],9:[function(require,module,exports){ -const acorn = require('acorn'); -const { utils } = require('../utils'); -const { FunctionTracer } = require('./function-tracer'); - -class FunctionNode { - constructor(source, settings) { - if (!source && !settings.ast) { - throw new Error('source parameter is missing'); + getString(functionName) { + if (functionName) { + return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse()); + } + return this.getStringFromFunctionNames(Object.keys(this.functionMap)); } - settings = settings || {}; - this.source = source; - this.ast = null; - this.name = typeof source === 'string' ? settings.isRootKernel ? - 'kernel' : - (settings.name || utils.getFunctionNameFromString(source)) : null; - this.calledFunctions = []; - this.constants = {}; - this.constantTypes = {}; - this.constantBitRatios = {}; - this.isRootKernel = false; - this.isSubKernel = false; - this.debug = null; - this.declarations = null; - this.functions = null; - this.identifiers = null; - this.contexts = null; - this.functionCalls = null; - this.states = []; - this.needsArgumentType = null; - this.assignArgumentType = null; - this.lookupReturnType = null; - this.lookupFunctionArgumentTypes = null; - this.lookupFunctionArgumentBitRatio = null; - this.triggerImplyArgumentType = null; - this.triggerImplyArgumentBitRatio = null; - this.onNestedFunction = null; - this.onFunctionCall = null; - this.optimizeFloatMemory = null; - this.precision = null; - this.loopMaxIterations = null; - this.argumentNames = (typeof this.source === 'string' ? utils.getArgumentNamesFromString(this.source) : null); - this.argumentTypes = []; - this.argumentSizes = []; - this.argumentBitRatios = null; - this.returnType = null; - this.output = []; - this.plugins = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.dynamicOutput = null; - this.dynamicArguments = null; - this.strictTypingChecking = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - - if (settings) { - for (const p in settings) { - if (!settings.hasOwnProperty(p)) continue; - if (!this.hasOwnProperty(p)) continue; - this[p] = settings[p]; + lookupReturnType(functionName, ast, requestingNode) { + if (ast.type !== 'CallExpression') { + throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`); + } + if (this._isNativeFunction(functionName)) { + return this._lookupNativeFunctionReturnType(functionName); + } else if (this._isFunction(functionName)) { + const node = this._getFunction(functionName); + if (node.returnType) { + return node.returnType; + } else { + for (let i = 0; i < this.lookupChain.length; i++) { + if (this.lookupChain[i].ast === ast) { + if (node.argumentTypes.length === 0 && ast.arguments.length > 0) { + const args = ast.arguments; + for (let j = 0; j < args.length; j++) { + this.lookupChain.push({ + name: requestingNode.name, + ast: args[i], + requestingNode + }); + node.argumentTypes[j] = requestingNode.getType(args[j]); + this.lookupChain.pop(); + } + return node.returnType = node.getType(node.getJsAST()); + } + throw new Error('circlical logic detected!'); + } + } + this.lookupChain.push({ + name: requestingNode.name, + ast, + requestingNode + }); + const type = node.getType(node.getJsAST()); + this.lookupChain.pop(); + return node.returnType = type; + } } + return null; } - - this.literalTypes = {}; - - this.validate(); - this._string = null; - this._internalVariableNames = {}; - } - - validate() { - if (typeof this.source !== 'string' && !this.ast) { - throw new Error('this.source not a string'); + _getFunction(functionName) { + if (!this._isFunction(functionName)) ; + return this.functionMap[functionName]; } - - if (!this.ast && !utils.isFunctionString(this.source)) { - throw new Error('this.source not a function string'); + _isFunction(functionName) { + return Boolean(this.functionMap[functionName]); } - - if (!this.name) { - throw new Error('this.name could not be set'); + _getNativeFunction(functionName) { + for (let i = 0; i < this.nativeFunctions.length; i++) { + if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i]; + } + return null; } - - if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) { - throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`); + _isNativeFunction(functionName) { + return Boolean(this._getNativeFunction(functionName)); } - - if (this.output.length < 1) { - throw new Error('this.output is not big enough'); + _lookupNativeFunctionReturnType(functionName) { + let nativeFunction = this._getNativeFunction(functionName); + if (nativeFunction) { + return nativeFunction.returnType; + } + throw new Error(`Native function ${ functionName } not found`); } - } - - isIdentifierConstant(name) { - if (!this.constants) return false; - return this.constants.hasOwnProperty(name); - } - - isInput(argumentName) { - return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input'; - } - - pushState(state) { - this.states.push(state); - } - - popState(state) { - if (this.state !== state) { - throw new Error(`Cannot popState ${ state } when in ${ this.state }`); + lookupFunctionArgumentTypes(functionName) { + if (this._isNativeFunction(functionName)) { + return this._getNativeFunction(functionName).argumentTypes; + } else if (this._isFunction(functionName)) { + return this._getFunction(functionName).argumentTypes; + } + return null; } - this.states.pop(); - } - - isState(state) { - return this.state === state; - } - - get state() { - return this.states[this.states.length - 1]; - } - - astMemberExpressionUnroll(ast) { - if (ast.type === 'Identifier') { - return ast.name; - } else if (ast.type === 'ThisExpression') { - return 'this'; + lookupFunctionArgumentName(functionName, argumentIndex) { + return this._getFunction(functionName).argumentNames[argumentIndex]; } - - if (ast.type === 'MemberExpression') { - if (ast.object && ast.property) { - if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { - return this.astMemberExpressionUnroll(ast.property); - } - - return ( - this.astMemberExpressionUnroll(ast.object) + - '.' + - this.astMemberExpressionUnroll(ast.property) - ); + lookupFunctionArgumentBitRatio(functionName, argumentName) { + if (!this._isFunction(functionName)) { + throw new Error('function not found'); } + if (this.rootNode.name === functionName) { + const i = this.rootNode.argumentNames.indexOf(argumentName); + if (i !== -1) { + return this.rootNode.argumentBitRatios[i]; + } else { + throw new Error('argument bit ratio not found'); + } + } else { + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymIndex]; + if (!argumentSynonym) { + throw new Error('argument synonym not found'); + } + return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName); + } + } + needsArgumentType(functionName, i) { + if (!this._isFunction(functionName)) return false; + const fnNode = this._getFunction(functionName); + return !fnNode.argumentTypes[i]; + } + assignArgumentType(functionName, i, argumentType, requestingNode) { + if (!this._isFunction(functionName)) return; + const fnNode = this._getFunction(functionName); + if (!fnNode.argumentTypes[i]) { + fnNode.argumentTypes[i] = argumentType; + } + } + trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) { + if (!this._isFunction(calleeFunctionName)) return; + const node = this._getFunction(calleeFunctionName); + if (!node.argumentSynonym) { + node.argumentSynonym = {}; + } + const calleeArgumentName = node.argumentNames[argumentIndex]; + if (!node.argumentSynonym[calleeArgumentName]) { + node.argumentSynonym[calleeArgumentName] = {}; + } + node.synonymIndex++; + node.argumentSynonym[node.synonymIndex] = { + functionName, + argumentName, + calleeArgumentName, + calleeFunctionName, + }; } - - if (ast.hasOwnProperty('expressions')) { - const firstExpression = ast.expressions[0]; - if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) { - return this.astMemberExpressionUnroll(ast.expressions[1]); + lookupArgumentSynonym(originFunctionName, functionName, argumentName) { + if (originFunctionName === functionName) return argumentName; + if (!this._isFunction(functionName)) return null; + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymUseIndex]; + if (!argumentSynonym) return null; + if (argumentSynonym.calleeArgumentName !== argumentName) return null; + node.synonymUseIndex++; + if (originFunctionName !== functionName) { + return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName); } + return argumentSynonym.argumentName; } - - throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast); - } - - getJsAST(inParser) { - if (this.ast) { - return this.ast; - } - if (typeof this.source === 'object') { - this.traceFunctionAST(this.source); - return this.ast = this.source; - } - - inParser = inParser || acorn; - if (inParser === null) { - throw new Error('Missing JS to AST parser'); + trackFunctionCall(functionName, calleeFunctionName, args) { + if (!this.functionNodeDependencies[functionName]) { + this.functionNodeDependencies[functionName] = new Set(); + this.functionCalls[functionName] = []; + } + this.functionNodeDependencies[functionName].add(calleeFunctionName); + this.functionCalls[functionName].push(args); } - - const ast = Object.freeze(inParser.parse(`const parser_${ this.name } = ${ this.source };`, { - locations: true - })); - const functionAST = ast.body[0].declarations[0].init; - this.traceFunctionAST(functionAST); - - if (!ast) { - throw new Error('Failed to parse JS code'); + getKernelResultType() { + return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast); } - - return this.ast = functionAST; - } - - traceFunctionAST(ast) { - const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast); - this.contexts = contexts; - this.identifiers = identifiers; - this.functionCalls = functionCalls; - this.declarations = []; - this.functions = functions; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - const { ast, context, name, origin, forceInteger, assignable } = declaration; - const { init } = ast; - const dependencies = this.getDependencies(init); - let valueType = null; - - if (forceInteger) { - valueType = 'Integer'; - } else { - if (init) { - const realType = this.getType(init); - switch (realType) { - case 'Integer': - case 'Float': - case 'Number': - if (init.type === 'MemberExpression') { - valueType = realType; - } else { - valueType = 'Number'; - } - break; - case 'LiteralInteger': - valueType = 'Number'; - break; - default: - valueType = realType; - } + getSubKernelResultType(index) { + const subKernelNode = this.subKernelNodes[index]; + let called = false; + for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) { + const functionCall = this.rootNode.functionCalls[functionCallIndex]; + if (functionCall.ast.callee.name === subKernelNode.name) { + called = true; } } - this.declarations.push({ - valueType, - dependencies, - isSafe: this.isSafeDependencies(dependencies), - ast, - name, - context, - origin, - assignable, - }); - } - - for (let i = 0; i < functions.length; i++) { - this.onNestedFunction(functions[i]); + if (!called) { + throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); + } + return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST()); } - } - - getDeclaration(ast) { - for (let i = 0; i < this.identifiers.length; i++) { - const identifier = this.identifiers[i]; - if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { - for (let j = 0; j < this.declarations.length; j++) { - const declaration = this.declarations[j]; - if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { - return declaration; - } - } + getReturnTypes() { + const result = { + [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast), + }; + const list = this.traceFunctionCalls(this.rootNode.name); + for (let i = 0; i < list.length; i++) { + const functionName = list[i]; + const functionNode = this.functionMap[functionName]; + result[functionName] = functionNode.getType(functionNode.ast); } + return result; } - return null; } - getVariableType(ast) { - if (ast.type !== 'Identifier') { - throw new Error(`ast of ${ast.type} not "Identifier"`); - } - let type = null; - const argumentIndex = this.argumentNames.indexOf(ast.name); - if (argumentIndex === -1) { - const declaration = this.getDeclaration(ast); - if (declaration) { - return declaration.valueType; - } - } else { - const argumentType = this.argumentTypes[argumentIndex]; - if (argumentType) { - type = argumentType; - } + class FunctionTracer { + constructor(ast) { + this.runningContexts = []; + this.contexts = []; + this.functionCalls = []; + this.declarations = []; + this.identifiers = []; + this.functions = []; + this.returnStatements = []; + this.inLoopInit = false; + this.scan(ast); } - if (!type && this.strictTypingChecking) { - throw new Error(`Declaration of ${name} not found`); + get currentContext() { + return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; } - return type; - } - - getLookupType(type) { - if (!typeLookupMap.hasOwnProperty(type)) { - throw new Error(`unknown typeLookupMap ${ type }`); + newContext(run) { + const newContext = Object.assign({}, this.currentContext); + this.contexts.push(newContext); + this.runningContexts.push(newContext); + run(); + this.runningContexts.pop(); } - return typeLookupMap[type]; - } - - getConstantType(constantName) { - if (this.constantTypes[constantName]) { - const type = this.constantTypes[constantName]; - if (type === 'Float') { - return 'Number'; - } else { - return type; + scan(ast) { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.scan(ast[i]); + } + return; } - } - throw new Error(`Type for constant "${ constantName }" not declared`); - } - - toString() { - if (this._string) return this._string; - return this._string = this.astGeneric(this.getJsAST(), []).join('').trim(); - } - - toJSON() { - const settings = { - source: this.source, - name: this.name, - constants: this.constants, - constantTypes: this.constantTypes, - isRootKernel: this.isRootKernel, - isSubKernel: this.isSubKernel, - debug: this.debug, - output: this.output, - loopMaxIterations: this.loopMaxIterations, - argumentNames: this.argumentNames, - argumentTypes: this.argumentTypes, - argumentSizes: this.argumentSizes, - returnType: this.returnType, - leadingReturnStatement: this.leadingReturnStatement, - followingReturnStatement: this.followingReturnStatement, - }; - - return { - ast: this.ast, - settings - }; - } - - getType(ast) { - if (Array.isArray(ast)) { - return this.getType(ast[ast.length - 1]); - } - switch (ast.type) { - case 'BlockStatement': - return this.getType(ast.body); - case 'ArrayExpression': - return `Array(${ ast.elements.length })`; - case 'Literal': - const literalKey = `${ast.start},${ast.end}`; - if (this.literalTypes[literalKey]) { - return this.literalTypes[literalKey]; - } - if (Number.isInteger(ast.value)) { - return 'LiteralInteger'; - } else if (ast.value === true || ast.value === false) { - return 'Boolean'; - } else { - return 'Number'; - } + switch (ast.type) { + case 'Program': + this.scan(ast.body); + break; + case 'BlockStatement': + this.newContext(() => { + this.scan(ast.body); + }); + break; case 'AssignmentExpression': - return this.getType(ast.left); - case 'CallExpression': - if (this.isAstMathFunction(ast)) { - return 'Number'; - } - if (!ast.callee || !ast.callee.name) { - if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) { - const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name; - this.inferArgumentTypesIfNeeded(functionName, ast.arguments); - return this.lookupReturnType(functionName, ast, this); - } - throw this.astErrorOutput('Unknown call expression', ast); - } - if (ast.callee && ast.callee.name) { - const functionName = ast.callee.name; - this.inferArgumentTypesIfNeeded(functionName, ast.arguments); - return this.lookupReturnType(functionName, ast, this); - } - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + case 'LogicalExpression': + this.scan(ast.left); + this.scan(ast.right); + break; case 'BinaryExpression': - switch (ast.operator) { - case '%': - case '/': - if (this.fixIntegerDivisionAccuracy) { - return 'Number'; - } else { - break; - } - case '>': - case '<': - return 'Boolean'; - case '&': - case '|': - case '^': - case '<<': - case '>>': - case '>>>': - return 'Integer'; - } - const type = this.getType(ast.left); - if (this.isState('skip-literal-correction')) return type; - if (type === 'LiteralInteger') { - const rightType = this.getType(ast.right); - if (rightType === 'LiteralInteger') { - if (ast.left.value % 1 === 0) { - return 'Integer'; - } else { - return 'Float'; - } - } - return rightType; - } - return typeLookupMap[type] || type; + this.scan(ast.left); + this.scan(ast.right); + break; case 'UpdateExpression': - return this.getType(ast.argument); case 'UnaryExpression': - if (ast.operator === '~') { - return 'Integer'; - } - return this.getType(ast.argument); - case 'VariableDeclaration': { - const declarations = ast.declarations; - let lastType; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - lastType = this.getType(declaration); - } - if (!lastType) { - throw this.astErrorOutput(`Unable to find type for declaration`, ast); - } - return lastType; - } + this.scan(ast.argument); + break; + case 'VariableDeclaration': + this.scan(ast.declarations); + break; case 'VariableDeclarator': - const declaration = this.getDeclaration(ast.id); - if (!declaration) { - throw this.astErrorOutput(`Unable to find declarator`, ast); - } - - if (!declaration.valueType) { - throw this.astErrorOutput(`Unable to find declarator valueType`, ast); + const { currentContext } = this; + const declaration = { + ast: ast, + context: currentContext, + name: ast.id.name, + origin: 'declaration', + forceInteger: this.inLoopInit, + assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name), + }; + currentContext[ast.id.name] = declaration; + this.declarations.push(declaration); + this.scan(ast.id); + this.scan(ast.init); + break; + case 'FunctionExpression': + case 'FunctionDeclaration': + if (this.runningContexts.length === 0) { + this.scan(ast.body); + } else { + this.functions.push(ast); } - - return declaration.valueType; + break; + case 'IfStatement': + this.scan(ast.test); + this.scan(ast.consequent); + if (ast.alternate) this.scan(ast.alternate); + break; + case 'ForStatement': + this.newContext(() => { + this.inLoopInit = true; + this.scan(ast.init); + this.inLoopInit = false; + this.scan(ast.test); + this.scan(ast.update); + this.newContext(() => { + this.scan(ast.body); + }); + }); + break; + case 'DoWhileStatement': + case 'WhileStatement': + this.newContext(() => { + this.scan(ast.body); + this.scan(ast.test); + }); + break; case 'Identifier': - if (ast.name === 'Infinity') { - return 'Number'; - } - if (this.isAstVariable(ast)) { - const signature = this.getVariableSignature(ast); - if (signature === 'value') { - const type = this.getVariableType(ast); - if (!type) { - throw this.astErrorOutput(`Unable to find identifier valueType`, ast); - } - return type; - } - } - const origin = this.findIdentifierOrigin(ast); - if (origin && origin.init) { - return this.getType(origin.init); - } - return null; + this.identifiers.push({ + context: this.currentContext, + ast, + }); + break; case 'ReturnStatement': - return this.getType(ast.argument); + this.returnStatements.push(ast); + this.scan(ast.argument); + break; case 'MemberExpression': - if (this.isAstMathFunction(ast)) { - switch (ast.property.name) { - case 'ceil': - return 'Integer'; - case 'floor': - return 'Integer'; - case 'round': - return 'Integer'; - } - return 'Number'; - } - if (this.isAstVariable(ast)) { - const variableSignature = this.getVariableSignature(ast); - switch (variableSignature) { - case 'value[]': - return this.getLookupType(this.getVariableType(ast.object)); - case 'value[][]': - return this.getLookupType(this.getVariableType(ast.object.object)); - case 'value[][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object)); - case 'value[][][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object.object)); - case 'value.thread.value': - case 'this.thread.value': - return 'Integer'; - case 'this.output.value': - return this.dynamicOutput ? 'Integer' : 'LiteralInteger'; - case 'this.constants.value': - return this.getConstantType(ast.property.name); - case 'this.constants.value[]': - return this.getLookupType(this.getConstantType(ast.object.property.name)); - case 'this.constants.value[][]': - return this.getLookupType(this.getConstantType(ast.object.object.property.name)); - case 'this.constants.value[][][]': - return this.getLookupType(this.getConstantType(ast.object.object.object.property.name)); - case 'this.constants.value[][][][]': - return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name)); - case 'fn()[]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][][]': - return this.getLookupType(this.getType(ast.object)); - case 'value.value': - if (this.isAstMathVariable(ast)) { - return 'Number'; - } - switch (ast.property.name) { - case 'r': - return this.getLookupType(this.getVariableType(ast.object)); - case 'g': - return this.getLookupType(this.getVariableType(ast.object)); - case 'b': - return this.getLookupType(this.getVariableType(ast.object)); - case 'a': - return this.getLookupType(this.getVariableType(ast.object)); - } - case '[][]': - return 'Number'; - } - throw this.astErrorOutput('Unhandled getType MemberExpression', ast); - } - throw this.astErrorOutput('Unhandled getType MemberExpression', ast); + this.scan(ast.object); + this.scan(ast.property); + break; + case 'ExpressionStatement': + this.scan(ast.expression); + break; + case 'CallExpression': + this.functionCalls.push({ + context: this.currentContext, + ast, + }); + this.scan(ast.arguments); + break; + case 'ArrayExpression': + this.scan(ast.elements); + break; case 'ConditionalExpression': - return this.getType(ast.consequent); - case 'FunctionDeclaration': - case 'FunctionExpression': - const lastReturn = this.findLastReturn(ast.body); - if (lastReturn) { - return this.getType(lastReturn); - } - return null; - case 'IfStatement': - return this.getType(ast.consequent); + this.scan(ast.test); + this.scan(ast.alternate); + this.scan(ast.consequent); + break; + case 'SwitchStatement': + this.scan(ast.discriminant); + this.scan(ast.cases); + break; + case 'SwitchCase': + this.scan(ast.test); + this.scan(ast.consequent); + break; + case 'ThisExpression': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'Literal': + case 'DebuggerStatement': + case 'EmptyStatement': + case 'BreakStatement': + case 'ContinueStatement': + break; default: - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + throw new Error(`unhandled type "${ast.type}"`); + } } } - inferArgumentTypesIfNeeded(functionName, args) { - for (let i = 0; i < args.length; i++) { - if (!this.needsArgumentType(functionName, i)) continue; - const type = this.getType(args[i]); - if (!type) { - throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]); + class FunctionNode { + constructor(source, settings) { + if (!source && !settings.ast) { + throw new Error('source parameter is missing'); + } + settings = settings || {}; + this.source = source; + this.ast = null; + this.name = typeof source === 'string' ? settings.isRootKernel ? + 'kernel' : + (settings.name || getFunctionNameFromString(source)) : null; + this.calledFunctions = []; + this.constants = {}; + this.constantTypes = {}; + this.constantBitRatios = {}; + this.isRootKernel = false; + this.isSubKernel = false; + this.debug = null; + this.declarations = null; + this.functions = null; + this.identifiers = null; + this.contexts = null; + this.functionCalls = null; + this.states = []; + this.needsArgumentType = null; + this.assignArgumentType = null; + this.lookupReturnType = null; + this.lookupFunctionArgumentTypes = null; + this.lookupFunctionArgumentBitRatio = null; + this.triggerImplyArgumentType = null; + this.triggerImplyArgumentBitRatio = null; + this.onNestedFunction = null; + this.onFunctionCall = null; + this.optimizeFloatMemory = null; + this.precision = null; + this.loopMaxIterations = null; + this.argumentNames = (typeof this.source === 'string' ? getArgumentNamesFromString(this.source) : null); + this.argumentTypes = []; + this.argumentSizes = []; + this.argumentBitRatios = null; + this.returnType = null; + this.output = []; + this.plugins = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.dynamicOutput = null; + this.dynamicArguments = null; + this.strictTypingChecking = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + if (settings) { + for (const p in settings) { + if (!settings.hasOwnProperty(p)) continue; + if (!this.hasOwnProperty(p)) continue; + this[p] = settings[p]; + } } - this.assignArgumentType(functionName, i, type); + this.literalTypes = {}; + this.validate(); + this._string = null; + this._internalVariableNames = {}; } - } - - isAstMathVariable(ast) { - const mathProperties = [ - 'E', - 'PI', - 'SQRT2', - 'SQRT1_2', - 'LN2', - 'LN10', - 'LOG2E', - 'LOG10E', - ]; - return ast.type === 'MemberExpression' && - ast.object && ast.object.type === 'Identifier' && - ast.object.name === 'Math' && - ast.property && - ast.property.type === 'Identifier' && - mathProperties.indexOf(ast.property.name) > -1; - } - - isAstMathFunction(ast) { - const mathFunctions = [ - 'abs', - 'acos', - 'asin', - 'atan', - 'atan2', - 'ceil', - 'cos', - 'exp', - 'floor', - 'log', - 'log2', - 'max', - 'min', - 'pow', - 'random', - 'round', - 'sign', - 'sin', - 'sqrt', - 'tan', - ]; - return ast.type === 'CallExpression' && - ast.callee && - ast.callee.type === 'MemberExpression' && - ast.callee.object && - ast.callee.object.type === 'Identifier' && - ast.callee.object.name === 'Math' && - ast.callee.property && - ast.callee.property.type === 'Identifier' && - mathFunctions.indexOf(ast.callee.property.name) > -1; - } - - isAstVariable(ast) { - return ast.type === 'Identifier' || ast.type === 'MemberExpression'; - } - - isSafe(ast) { - return this.isSafeDependencies(this.getDependencies(ast)); - } - - isSafeDependencies(dependencies) { - return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true; - } - - getDependencies(ast, dependencies, isNotSafe) { - if (!dependencies) { - dependencies = []; + validate() { + if (typeof this.source !== 'string' && !this.ast) { + throw new Error('this.source not a string'); + } + if (!this.ast && !isFunctionString(this.source)) { + throw new Error('this.source not a function string'); + } + if (!this.name) { + throw new Error('this.name could not be set'); + } + if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) { + throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`); + } + if (this.output.length < 1) { + throw new Error('this.output is not big enough'); + } + } + isIdentifierConstant(name) { + if (!this.constants) return false; + return this.constants.hasOwnProperty(name); + } + isInput(argumentName) { + return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input'; } - if (!ast) return null; - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.getDependencies(ast[i], dependencies, isNotSafe); + pushState(state) { + this.states.push(state); + } + popState(state) { + if (this.state !== state) { + throw new Error(`Cannot popState ${ state } when in ${ this.state }`); } - return dependencies; + this.states.pop(); } - switch (ast.type) { - case 'AssignmentExpression': - this.getDependencies(ast.left, dependencies, isNotSafe); - this.getDependencies(ast.right, dependencies, isNotSafe); - return dependencies; - case 'ConditionalExpression': - this.getDependencies(ast.test, dependencies, isNotSafe); - this.getDependencies(ast.alternate, dependencies, isNotSafe); - this.getDependencies(ast.consequent, dependencies, isNotSafe); - return dependencies; - case 'Literal': - dependencies.push({ - origin: 'literal', - value: ast.value, - isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value) + isState(state) { + return this.state === state; + } + get state() { + return this.states[this.states.length - 1]; + } + astMemberExpressionUnroll(ast) { + if (ast.type === 'Identifier') { + return ast.name; + } else if (ast.type === 'ThisExpression') { + return 'this'; + } + if (ast.type === 'MemberExpression') { + if (ast.object && ast.property) { + if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { + return this.astMemberExpressionUnroll(ast.property); + } + return ( + this.astMemberExpressionUnroll(ast.object) + + '.' + + this.astMemberExpressionUnroll(ast.property) + ); + } + } + if (ast.hasOwnProperty('expressions')) { + const firstExpression = ast.expressions[0]; + if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) { + return this.astMemberExpressionUnroll(ast.expressions[1]); + } + } + throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast); + } + getJsAST(inParser) { + if (this.ast) { + return this.ast; + } + if (typeof this.source === 'object') { + this.traceFunctionAST(this.source); + return this.ast = this.source; + } + const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : acorn.parse; + if (inParser === null) { + throw new Error('Missing JS to AST parser'); + } + const ast = Object.freeze(parser(`const parser_${ this.name } = ${ this.source };`, { + locations: true + })); + const functionAST = ast.body[0].declarations[0].init; + this.traceFunctionAST(functionAST); + if (!ast) { + throw new Error('Failed to parse JS code'); + } + return this.ast = functionAST; + } + traceFunctionAST(ast) { + const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast); + this.contexts = contexts; + this.identifiers = identifiers; + this.functionCalls = functionCalls; + this.declarations = []; + this.functions = functions; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + const { ast, context, name, origin, forceInteger, assignable } = declaration; + const { init } = ast; + const dependencies = this.getDependencies(init); + let valueType = null; + if (forceInteger) { + valueType = 'Integer'; + } else { + if (init) { + const realType = this.getType(init); + switch (realType) { + case 'Integer': + case 'Float': + case 'Number': + if (init.type === 'MemberExpression') { + valueType = realType; + } else { + valueType = 'Number'; + } + break; + case 'LiteralInteger': + valueType = 'Number'; + break; + default: + valueType = realType; + } + } + } + this.declarations.push({ + valueType, + dependencies, + isSafe: this.isSafeDependencies(dependencies), + ast, + name, + context, + origin, + assignable, }); - break; - case 'VariableDeclarator': - return this.getDependencies(ast.init, dependencies, isNotSafe); - case 'Identifier': + } + for (let i = 0; i < functions.length; i++) { + this.onNestedFunction(functions[i]); + } + } + getDeclaration(ast) { + for (let i = 0; i < this.identifiers.length; i++) { + const identifier = this.identifiers[i]; + if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { + for (let j = 0; j < this.declarations.length; j++) { + const declaration = this.declarations[j]; + if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { + return declaration; + } + } + } + } + return null; + } + getVariableType(ast) { + if (ast.type !== 'Identifier') { + throw new Error(`ast of ${ast.type} not "Identifier"`); + } + let type = null; + const argumentIndex = this.argumentNames.indexOf(ast.name); + if (argumentIndex === -1) { const declaration = this.getDeclaration(ast); if (declaration) { - dependencies.push({ - name: ast.name, - origin: 'declaration', - isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies), - }); - } else if (this.argumentNames.indexOf(ast.name) > -1) { - dependencies.push({ - name: ast.name, - origin: 'argument', - isSafe: false, - }); - } else if (this.strictTypingChecking) { - throw new Error(`Cannot find identifier origin "${ast.name}"`); - } - break; - case 'FunctionDeclaration': - return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe); - case 'ReturnStatement': - return this.getDependencies(ast.argument, dependencies); - case 'BinaryExpression': - isNotSafe = (ast.operator === '/' || ast.operator === '*'); - this.getDependencies(ast.left, dependencies, isNotSafe); - this.getDependencies(ast.right, dependencies, isNotSafe); - return dependencies; - case 'UnaryExpression': - case 'UpdateExpression': - return this.getDependencies(ast.argument, dependencies, isNotSafe); - case 'VariableDeclaration': - return this.getDependencies(ast.declarations, dependencies, isNotSafe); - case 'ArrayExpression': - dependencies.push({ - origin: 'declaration', - isSafe: true, - }); - return dependencies; - case 'CallExpression': - dependencies.push({ - origin: 'function', - isSafe: true, - }); - return dependencies; - case 'MemberExpression': - const details = this.getMemberExpressionDetails(ast); - switch (details.signature) { - case 'value[]': - this.getDependencies(ast.object, dependencies, isNotSafe); - break; - case 'value[][]': - this.getDependencies(ast.object.object, dependencies, isNotSafe); - break; - case 'value[][][]': - this.getDependencies(ast.object.object.object, dependencies, isNotSafe); - break; - case 'this.output.value': - if (this.dynamicOutput) { - dependencies.push({ - name: details.name, - origin: 'output', - isSafe: false, - }); - } - break; + return declaration.valueType; } - if (details) { - if (details.property) { - this.getDependencies(details.property, dependencies, isNotSafe); - } - if (details.xProperty) { - this.getDependencies(details.xProperty, dependencies, isNotSafe); - } - if (details.yProperty) { - this.getDependencies(details.yProperty, dependencies, isNotSafe); - } - if (details.zProperty) { - this.getDependencies(details.zProperty, dependencies, isNotSafe); - } - return dependencies; + } else { + const argumentType = this.argumentTypes[argumentIndex]; + if (argumentType) { + type = argumentType; } - default: - throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); + } + if (!type && this.strictTypingChecking) { + throw new Error(`Declaration of ${name} not found`); + } + return type; } - return dependencies; - } - - getVariableSignature(ast) { - if (!this.isAstVariable(ast)) { - throw new Error(`ast of type "${ ast.type }" is not a variable signature`); - } - if (ast.type === 'Identifier') { - return 'value'; - } - const signature = []; - while (true) { - if (!ast) break; - if (ast.computed) { - signature.push('[]'); - } else if (ast.type === 'ThisExpression') { - signature.unshift('this'); - } else if (ast.property && ast.property.name) { - if ( - ast.property.name === 'x' || - ast.property.name === 'y' || - ast.property.name === 'z' - ) { - signature.unshift('.value'); - } else if ( - ast.property.name === 'constants' || - ast.property.name === 'thread' || - ast.property.name === 'output' - ) { - signature.unshift('.' + ast.property.name); + getLookupType(type) { + if (!typeLookupMap.hasOwnProperty(type)) { + throw new Error(`unknown typeLookupMap ${ type }`); + } + return typeLookupMap[type]; + } + getConstantType(constantName) { + if (this.constantTypes[constantName]) { + const type = this.constantTypes[constantName]; + if (type === 'Float') { + return 'Number'; } else { - signature.unshift('.value'); - } - } else if (ast.name) { - signature.unshift('value'); - } else if (ast.callee && ast.callee.name) { - signature.unshift('fn()'); - } else if (ast.elements) { - signature.unshift('[]'); - } else { - signature.unshift('unknown'); + return type; + } } - ast = ast.object; + throw new Error(`Type for constant "${ constantName }" not declared`); } - - const signatureString = signature.join(''); - const allowedExpressions = [ - 'value', - 'value[]', - 'value[][]', - 'value[][][]', - 'value[][][][]', - 'value.value', - 'value.thread.value', - 'this.thread.value', - 'this.output.value', - 'this.constants.value', - 'this.constants.value[]', - 'this.constants.value[][]', - 'this.constants.value[][][]', - 'this.constants.value[][][][]', - 'fn()[]', - 'fn()[][]', - 'fn()[][][]', - '[][]', - ]; - if (allowedExpressions.indexOf(signatureString) > -1) { - return signatureString; + toString() { + if (this._string) return this._string; + return this._string = this.astGeneric(this.getJsAST(), []).join('').trim(); } - return null; - } - - build() { - return this.toString().length > 0; - } - - astGeneric(ast, retArr) { - if (ast === null) { - throw this.astErrorOutput('NULL ast', ast); - } else { + toJSON() { + const settings = { + source: this.source, + name: this.name, + constants: this.constants, + constantTypes: this.constantTypes, + isRootKernel: this.isRootKernel, + isSubKernel: this.isSubKernel, + debug: this.debug, + output: this.output, + loopMaxIterations: this.loopMaxIterations, + argumentNames: this.argumentNames, + argumentTypes: this.argumentTypes, + argumentSizes: this.argumentSizes, + returnType: this.returnType, + leadingReturnStatement: this.leadingReturnStatement, + followingReturnStatement: this.followingReturnStatement, + }; + return { + ast: this.ast, + settings + }; + } + getType(ast) { if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.astGeneric(ast[i], retArr); - } - return retArr; + return this.getType(ast[ast.length - 1]); } - switch (ast.type) { - case 'FunctionDeclaration': - return this.astFunctionDeclaration(ast, retArr); - case 'FunctionExpression': - return this.astFunctionExpression(ast, retArr); - case 'ReturnStatement': - return this.astReturnStatement(ast, retArr); - case 'Literal': - return this.astLiteral(ast, retArr); - case 'BinaryExpression': - return this.astBinaryExpression(ast, retArr); - case 'Identifier': - return this.astIdentifierExpression(ast, retArr); - case 'AssignmentExpression': - return this.astAssignmentExpression(ast, retArr); - case 'ExpressionStatement': - return this.astExpressionStatement(ast, retArr); - case 'EmptyStatement': - return this.astEmptyStatement(ast, retArr); case 'BlockStatement': - return this.astBlockStatement(ast, retArr); - case 'IfStatement': - return this.astIfStatement(ast, retArr); - case 'SwitchStatement': - return this.astSwitchStatement(ast, retArr); - case 'BreakStatement': - return this.astBreakStatement(ast, retArr); - case 'ContinueStatement': - return this.astContinueStatement(ast, retArr); - case 'ForStatement': - return this.astForStatement(ast, retArr); - case 'WhileStatement': - return this.astWhileStatement(ast, retArr); - case 'DoWhileStatement': - return this.astDoWhileStatement(ast, retArr); - case 'VariableDeclaration': - return this.astVariableDeclaration(ast, retArr); - case 'VariableDeclarator': - return this.astVariableDeclarator(ast, retArr); - case 'ThisExpression': - return this.astThisExpression(ast, retArr); - case 'SequenceExpression': - return this.astSequenceExpression(ast, retArr); - case 'UnaryExpression': - return this.astUnaryExpression(ast, retArr); - case 'UpdateExpression': - return this.astUpdateExpression(ast, retArr); - case 'LogicalExpression': - return this.astLogicalExpression(ast, retArr); - case 'MemberExpression': - return this.astMemberExpression(ast, retArr); - case 'CallExpression': - return this.astCallExpression(ast, retArr); + return this.getType(ast.body); case 'ArrayExpression': - return this.astArrayExpression(ast, retArr); - case 'DebuggerStatement': - return this.astDebuggerStatement(ast, retArr); + return `Array(${ ast.elements.length })`; + case 'Literal': + const literalKey = `${ast.start},${ast.end}`; + if (this.literalTypes[literalKey]) { + return this.literalTypes[literalKey]; + } + if (Number.isInteger(ast.value)) { + return 'LiteralInteger'; + } else if (ast.value === true || ast.value === false) { + return 'Boolean'; + } else { + return 'Number'; + } + case 'AssignmentExpression': + return this.getType(ast.left); + case 'CallExpression': + if (this.isAstMathFunction(ast)) { + return 'Number'; + } + if (!ast.callee || !ast.callee.name) { + if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) { + const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name; + this.inferArgumentTypesIfNeeded(functionName, ast.arguments); + return this.lookupReturnType(functionName, ast, this); + } + throw this.astErrorOutput('Unknown call expression', ast); + } + if (ast.callee && ast.callee.name) { + const functionName = ast.callee.name; + this.inferArgumentTypesIfNeeded(functionName, ast.arguments); + return this.lookupReturnType(functionName, ast, this); + } + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + case 'BinaryExpression': + switch (ast.operator) { + case '%': + case '/': + if (this.fixIntegerDivisionAccuracy) { + return 'Number'; + } else { + break; + } + case '>': + case '<': + return 'Boolean'; + case '&': + case '|': + case '^': + case '<<': + case '>>': + case '>>>': + return 'Integer'; + } + const type = this.getType(ast.left); + if (this.isState('skip-literal-correction')) return type; + if (type === 'LiteralInteger') { + const rightType = this.getType(ast.right); + if (rightType === 'LiteralInteger') { + if (ast.left.value % 1 === 0) { + return 'Integer'; + } else { + return 'Float'; + } + } + return rightType; + } + return typeLookupMap[type] || type; + case 'UpdateExpression': + return this.getType(ast.argument); + case 'UnaryExpression': + if (ast.operator === '~') { + return 'Integer'; + } + return this.getType(ast.argument); + case 'VariableDeclaration': { + const declarations = ast.declarations; + let lastType; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + lastType = this.getType(declaration); + } + if (!lastType) { + throw this.astErrorOutput(`Unable to find type for declaration`, ast); + } + return lastType; + } + case 'VariableDeclarator': + const declaration = this.getDeclaration(ast.id); + if (!declaration) { + throw this.astErrorOutput(`Unable to find declarator`, ast); + } + if (!declaration.valueType) { + throw this.astErrorOutput(`Unable to find declarator valueType`, ast); + } + return declaration.valueType; + case 'Identifier': + if (ast.name === 'Infinity') { + return 'Number'; + } + if (this.isAstVariable(ast)) { + const signature = this.getVariableSignature(ast); + if (signature === 'value') { + const type = this.getVariableType(ast); + if (!type) { + throw this.astErrorOutput(`Unable to find identifier valueType`, ast); + } + return type; + } + } + const origin = this.findIdentifierOrigin(ast); + if (origin && origin.init) { + return this.getType(origin.init); + } + return null; + case 'ReturnStatement': + return this.getType(ast.argument); + case 'MemberExpression': + if (this.isAstMathFunction(ast)) { + switch (ast.property.name) { + case 'ceil': + return 'Integer'; + case 'floor': + return 'Integer'; + case 'round': + return 'Integer'; + } + return 'Number'; + } + if (this.isAstVariable(ast)) { + const variableSignature = this.getVariableSignature(ast); + switch (variableSignature) { + case 'value[]': + return this.getLookupType(this.getVariableType(ast.object)); + case 'value[][]': + return this.getLookupType(this.getVariableType(ast.object.object)); + case 'value[][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object)); + case 'value[][][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object.object)); + case 'value.thread.value': + case 'this.thread.value': + return 'Integer'; + case 'this.output.value': + return this.dynamicOutput ? 'Integer' : 'LiteralInteger'; + case 'this.constants.value': + return this.getConstantType(ast.property.name); + case 'this.constants.value[]': + return this.getLookupType(this.getConstantType(ast.object.property.name)); + case 'this.constants.value[][]': + return this.getLookupType(this.getConstantType(ast.object.object.property.name)); + case 'this.constants.value[][][]': + return this.getLookupType(this.getConstantType(ast.object.object.object.property.name)); + case 'this.constants.value[][][][]': + return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name)); + case 'fn()[]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][][]': + return this.getLookupType(this.getType(ast.object)); + case 'value.value': + if (this.isAstMathVariable(ast)) { + return 'Number'; + } + switch (ast.property.name) { + case 'r': + return this.getLookupType(this.getVariableType(ast.object)); + case 'g': + return this.getLookupType(this.getVariableType(ast.object)); + case 'b': + return this.getLookupType(this.getVariableType(ast.object)); + case 'a': + return this.getLookupType(this.getVariableType(ast.object)); + } + case '[][]': + return 'Number'; + } + throw this.astErrorOutput('Unhandled getType MemberExpression', ast); + } + throw this.astErrorOutput('Unhandled getType MemberExpression', ast); + case 'ConditionalExpression': + return this.getType(ast.consequent); + case 'FunctionDeclaration': + case 'FunctionExpression': + const lastReturn = this.findLastReturn(ast.body); + if (lastReturn) { + return this.getType(lastReturn); + } + return null; + case 'IfStatement': + return this.getType(ast.consequent); + default: + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + } + } + inferArgumentTypesIfNeeded(functionName, args) { + for (let i = 0; i < args.length; i++) { + if (!this.needsArgumentType(functionName, i)) continue; + const type = this.getType(args[i]); + if (!type) { + throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]); + } + this.assignArgumentType(functionName, i, type); + } + } + isAstMathVariable(ast) { + const mathProperties = [ + 'E', + 'PI', + 'SQRT2', + 'SQRT1_2', + 'LN2', + 'LN10', + 'LOG2E', + 'LOG10E', + ]; + return ast.type === 'MemberExpression' && + ast.object && ast.object.type === 'Identifier' && + ast.object.name === 'Math' && + ast.property && + ast.property.type === 'Identifier' && + mathProperties.indexOf(ast.property.name) > -1; + } + isAstMathFunction(ast) { + const mathFunctions = [ + 'abs', + 'acos', + 'asin', + 'atan', + 'atan2', + 'ceil', + 'cos', + 'exp', + 'floor', + 'log', + 'log2', + 'max', + 'min', + 'pow', + 'random', + 'round', + 'sign', + 'sin', + 'sqrt', + 'tan', + ]; + return ast.type === 'CallExpression' && + ast.callee && + ast.callee.type === 'MemberExpression' && + ast.callee.object && + ast.callee.object.type === 'Identifier' && + ast.callee.object.name === 'Math' && + ast.callee.property && + ast.callee.property.type === 'Identifier' && + mathFunctions.indexOf(ast.callee.property.name) > -1; + } + isAstVariable(ast) { + return ast.type === 'Identifier' || ast.type === 'MemberExpression'; + } + isSafe(ast) { + return this.isSafeDependencies(this.getDependencies(ast)); + } + isSafeDependencies(dependencies) { + return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true; + } + getDependencies(ast, dependencies, isNotSafe) { + if (!dependencies) { + dependencies = []; + } + if (!ast) return null; + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.getDependencies(ast[i], dependencies, isNotSafe); + } + return dependencies; + } + switch (ast.type) { + case 'AssignmentExpression': + this.getDependencies(ast.left, dependencies, isNotSafe); + this.getDependencies(ast.right, dependencies, isNotSafe); + return dependencies; case 'ConditionalExpression': - return this.astConditionalExpression(ast, retArr); + this.getDependencies(ast.test, dependencies, isNotSafe); + this.getDependencies(ast.alternate, dependencies, isNotSafe); + this.getDependencies(ast.consequent, dependencies, isNotSafe); + return dependencies; + case 'Literal': + dependencies.push({ + origin: 'literal', + value: ast.value, + isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value) + }); + break; + case 'VariableDeclarator': + return this.getDependencies(ast.init, dependencies, isNotSafe); + case 'Identifier': + const declaration = this.getDeclaration(ast); + if (declaration) { + dependencies.push({ + name: ast.name, + origin: 'declaration', + isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies), + }); + } else if (this.argumentNames.indexOf(ast.name) > -1) { + dependencies.push({ + name: ast.name, + origin: 'argument', + isSafe: false, + }); + } else if (this.strictTypingChecking) { + throw new Error(`Cannot find identifier origin "${ast.name}"`); + } + break; + case 'FunctionDeclaration': + return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe); + case 'ReturnStatement': + return this.getDependencies(ast.argument, dependencies); + case 'BinaryExpression': + isNotSafe = (ast.operator === '/' || ast.operator === '*'); + this.getDependencies(ast.left, dependencies, isNotSafe); + this.getDependencies(ast.right, dependencies, isNotSafe); + return dependencies; + case 'UnaryExpression': + case 'UpdateExpression': + return this.getDependencies(ast.argument, dependencies, isNotSafe); + case 'VariableDeclaration': + return this.getDependencies(ast.declarations, dependencies, isNotSafe); + case 'ArrayExpression': + dependencies.push({ + origin: 'declaration', + isSafe: true, + }); + return dependencies; + case 'CallExpression': + dependencies.push({ + origin: 'function', + isSafe: true, + }); + return dependencies; + case 'MemberExpression': + const details = this.getMemberExpressionDetails(ast); + switch (details.signature) { + case 'value[]': + this.getDependencies(ast.object, dependencies, isNotSafe); + break; + case 'value[][]': + this.getDependencies(ast.object.object, dependencies, isNotSafe); + break; + case 'value[][][]': + this.getDependencies(ast.object.object.object, dependencies, isNotSafe); + break; + case 'this.output.value': + if (this.dynamicOutput) { + dependencies.push({ + name: details.name, + origin: 'output', + isSafe: false, + }); + } + break; + } + if (details) { + if (details.property) { + this.getDependencies(details.property, dependencies, isNotSafe); + } + if (details.xProperty) { + this.getDependencies(details.xProperty, dependencies, isNotSafe); + } + if (details.yProperty) { + this.getDependencies(details.yProperty, dependencies, isNotSafe); + } + if (details.zProperty) { + this.getDependencies(details.zProperty, dependencies, isNotSafe); + } + return dependencies; + } + default: + throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); } - - throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); + return dependencies; } - } - astErrorOutput(error, ast) { - if (typeof this.source !== 'string') { - return new Error(error); + getVariableSignature(ast) { + if (!this.isAstVariable(ast)) { + throw new Error(`ast of type "${ ast.type }" is not a variable signature`); + } + if (ast.type === 'Identifier') { + return 'value'; + } + const signature = []; + while (true) { + if (!ast) break; + if (ast.computed) { + signature.push('[]'); + } else if (ast.type === 'ThisExpression') { + signature.unshift('this'); + } else if (ast.property && ast.property.name) { + if ( + ast.property.name === 'x' || + ast.property.name === 'y' || + ast.property.name === 'z' + ) { + signature.unshift('.value'); + } else if ( + ast.property.name === 'constants' || + ast.property.name === 'thread' || + ast.property.name === 'output' + ) { + signature.unshift('.' + ast.property.name); + } else { + signature.unshift('.value'); + } + } else if (ast.name) { + signature.unshift('value'); + } else if (ast.callee && ast.callee.name) { + signature.unshift('fn()'); + } else if (ast.elements) { + signature.unshift('[]'); + } else { + signature.unshift('unknown'); + } + ast = ast.object; + } + const signatureString = signature.join(''); + const allowedExpressions = [ + 'value', + 'value[]', + 'value[][]', + 'value[][][]', + 'value[][][][]', + 'value.value', + 'value.thread.value', + 'this.thread.value', + 'this.output.value', + 'this.constants.value', + 'this.constants.value[]', + 'this.constants.value[][]', + 'this.constants.value[][][]', + 'this.constants.value[][][][]', + 'fn()[]', + 'fn()[][]', + 'fn()[][][]', + '[][]', + ]; + if (allowedExpressions.indexOf(signatureString) > -1) { + return signatureString; + } + return null; } - - const debugString = utils.getAstString(this.source, ast); - const leadingSource = this.source.substr(ast.start); - const splitLines = leadingSource.split(/\n/); - const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0; - return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`); - } - - astDebuggerStatement(arrNode, retArr) { - return retArr; - } - - astConditionalExpression(ast, retArr) { - if (ast.type !== 'ConditionalExpression') { - throw this.astErrorOutput('Not a conditional expression', ast); - } - retArr.push('('); - this.astGeneric(ast.test, retArr); - retArr.push('?'); - this.astGeneric(ast.consequent, retArr); - retArr.push(':'); - this.astGeneric(ast.alternate, retArr); - retArr.push(')'); - return retArr; - } - - astFunction(ast, retArr) { - throw new Error(`"astFunction" not defined on ${ this.constructor.name }`); - } - - astFunctionDeclaration(ast, retArr) { - if (this.isChildFunction(ast)) { + build() { + return this.toString().length > 0; + } + astGeneric(ast, retArr) { + if (ast === null) { + throw this.astErrorOutput('NULL ast', ast); + } else { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.astGeneric(ast[i], retArr); + } + return retArr; + } + switch (ast.type) { + case 'FunctionDeclaration': + return this.astFunctionDeclaration(ast, retArr); + case 'FunctionExpression': + return this.astFunctionExpression(ast, retArr); + case 'ReturnStatement': + return this.astReturnStatement(ast, retArr); + case 'Literal': + return this.astLiteral(ast, retArr); + case 'BinaryExpression': + return this.astBinaryExpression(ast, retArr); + case 'Identifier': + return this.astIdentifierExpression(ast, retArr); + case 'AssignmentExpression': + return this.astAssignmentExpression(ast, retArr); + case 'ExpressionStatement': + return this.astExpressionStatement(ast, retArr); + case 'EmptyStatement': + return this.astEmptyStatement(ast, retArr); + case 'BlockStatement': + return this.astBlockStatement(ast, retArr); + case 'IfStatement': + return this.astIfStatement(ast, retArr); + case 'SwitchStatement': + return this.astSwitchStatement(ast, retArr); + case 'BreakStatement': + return this.astBreakStatement(ast, retArr); + case 'ContinueStatement': + return this.astContinueStatement(ast, retArr); + case 'ForStatement': + return this.astForStatement(ast, retArr); + case 'WhileStatement': + return this.astWhileStatement(ast, retArr); + case 'DoWhileStatement': + return this.astDoWhileStatement(ast, retArr); + case 'VariableDeclaration': + return this.astVariableDeclaration(ast, retArr); + case 'VariableDeclarator': + return this.astVariableDeclarator(ast, retArr); + case 'ThisExpression': + return this.astThisExpression(ast, retArr); + case 'SequenceExpression': + return this.astSequenceExpression(ast, retArr); + case 'UnaryExpression': + return this.astUnaryExpression(ast, retArr); + case 'UpdateExpression': + return this.astUpdateExpression(ast, retArr); + case 'LogicalExpression': + return this.astLogicalExpression(ast, retArr); + case 'MemberExpression': + return this.astMemberExpression(ast, retArr); + case 'CallExpression': + return this.astCallExpression(ast, retArr); + case 'ArrayExpression': + return this.astArrayExpression(ast, retArr); + case 'DebuggerStatement': + return this.astDebuggerStatement(ast, retArr); + case 'ConditionalExpression': + return this.astConditionalExpression(ast, retArr); + } + throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); + } + } + astErrorOutput(error, ast) { + if (typeof this.source !== 'string') { + return new Error(error); + } + const debugString = getAstString(this.source, ast); + const leadingSource = this.source.substr(ast.start); + const splitLines = leadingSource.split(/\n/); + const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0; + return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`); + } + astDebuggerStatement(arrNode, retArr) { return retArr; } - return this.astFunction(ast, retArr); - } - astFunctionExpression(ast, retArr) { - if (this.isChildFunction(ast)) { + astConditionalExpression(ast, retArr) { + if (ast.type !== 'ConditionalExpression') { + throw this.astErrorOutput('Not a conditional expression', ast); + } + retArr.push('('); + this.astGeneric(ast.test, retArr); + retArr.push('?'); + this.astGeneric(ast.consequent, retArr); + retArr.push(':'); + this.astGeneric(ast.alternate, retArr); + retArr.push(')'); return retArr; } - return this.astFunction(ast, retArr); - } - isChildFunction(ast) { - for (let i = 0; i < this.functions.length; i++) { - if (this.functions[i] === ast) { - return true; + astFunction(ast, retArr) { + throw new Error(`"astFunction" not defined on ${ this.constructor.name }`); + } + astFunctionDeclaration(ast, retArr) { + if (this.isChildFunction(ast)) { + return retArr; } + return this.astFunction(ast, retArr); } - return false; - } - astReturnStatement(ast, retArr) { - return retArr; - } - astLiteral(ast, retArr) { - this.literalTypes[`${ast.start},${ast.end}`] = 'Number'; - return retArr; - } - astBinaryExpression(ast, retArr) { - return retArr; - } - astIdentifierExpression(ast, retArr) { - return retArr; - } - astAssignmentExpression(ast, retArr) { - return retArr; - } - astExpressionStatement(esNode, retArr) { - this.astGeneric(esNode.expression, retArr); - retArr.push(';'); - return retArr; - } - astEmptyStatement(eNode, retArr) { - return retArr; - } - astBlockStatement(ast, retArr) { - return retArr; - } - astIfStatement(ast, retArr) { - return retArr; - } - astSwitchStatement(ast, retArr) { - return retArr; - } - astBreakStatement(brNode, retArr) { - retArr.push('break;'); - return retArr; - } - astContinueStatement(crNode, retArr) { - retArr.push('continue;\n'); - return retArr; - } - astForStatement(ast, retArr) { - return retArr; - } - astWhileStatement(ast, retArr) { - return retArr; - } - astDoWhileStatement(ast, retArr) { - return retArr; - } - astVariableDeclaration(varDecNode, retArr) { - const declarations = varDecNode.declarations; - if (!declarations || !declarations[0] || !declarations[0].init) { - throw this.astErrorOutput('Unexpected expression', varDecNode); + astFunctionExpression(ast, retArr) { + if (this.isChildFunction(ast)) { + return retArr; + } + return this.astFunction(ast, retArr); } - const result = []; - const firstDeclaration = declarations[0]; - const init = firstDeclaration.init; - let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); - if (type === 'LiteralInteger') { - type = 'Number'; - } - const markupType = typeMap[type]; - if (!markupType) { - throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); - } - let dependencies = this.getDependencies(firstDeclaration.init); - throw new Error('remove me'); - this.declarations[firstDeclaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: dependencies.every(dependency => dependency.isSafe) - }); - const initResult = [`${type} user_${firstDeclaration.id.name}=`]; - this.astGeneric(init, initResult); - result.push(initResult.join('')); - - for (let i = 1; i < declarations.length; i++) { - const declaration = declarations[i]; - dependencies = this.getDependencies(declaration); - throw new Error('Remove me'); - this.declarations[declaration.id.name] = Object.freeze({ + isChildFunction(ast) { + for (let i = 0; i < this.functions.length; i++) { + if (this.functions[i] === ast) { + return true; + } + } + return false; + } + astReturnStatement(ast, retArr) { + return retArr; + } + astLiteral(ast, retArr) { + this.literalTypes[`${ast.start},${ast.end}`] = 'Number'; + return retArr; + } + astBinaryExpression(ast, retArr) { + return retArr; + } + astIdentifierExpression(ast, retArr) { + return retArr; + } + astAssignmentExpression(ast, retArr) { + return retArr; + } + astExpressionStatement(esNode, retArr) { + this.astGeneric(esNode.expression, retArr); + retArr.push(';'); + return retArr; + } + astEmptyStatement(eNode, retArr) { + return retArr; + } + astBlockStatement(ast, retArr) { + return retArr; + } + astIfStatement(ast, retArr) { + return retArr; + } + astSwitchStatement(ast, retArr) { + return retArr; + } + astBreakStatement(brNode, retArr) { + retArr.push('break;'); + return retArr; + } + astContinueStatement(crNode, retArr) { + retArr.push('continue;\n'); + return retArr; + } + astForStatement(ast, retArr) { + return retArr; + } + astWhileStatement(ast, retArr) { + return retArr; + } + astDoWhileStatement(ast, retArr) { + return retArr; + } + astVariableDeclaration(varDecNode, retArr) { + const declarations = varDecNode.declarations; + if (!declarations || !declarations[0] || !declarations[0].init) { + throw this.astErrorOutput('Unexpected expression', varDecNode); + } + const result = []; + const firstDeclaration = declarations[0]; + const init = firstDeclaration.init; + let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); + if (type === 'LiteralInteger') { + type = 'Number'; + } + const markupType = typeMap[type]; + if (!markupType) { + throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); + } + let dependencies = this.getDependencies(firstDeclaration.init); + throw new Error('remove me'); + this.declarations[firstDeclaration.id.name] = Object.freeze({ type, dependencies, - isSafe: false + isSafe: dependencies.every(dependency => dependency.isSafe) }); - this.astGeneric(declaration, result); + const initResult = [`${type} user_${firstDeclaration.id.name}=`]; + this.astGeneric(init, initResult); + result.push(initResult.join('')); + for (let i = 1; i < declarations.length; i++) { + const declaration = declarations[i]; + dependencies = this.getDependencies(declaration); + throw new Error('Remove me'); + this.declarations[declaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: false + }); + this.astGeneric(declaration, result); + } + retArr.push(retArr, result.join(',')); + retArr.push(';'); + return retArr; } - - retArr.push(retArr, result.join(',')); - retArr.push(';'); - return retArr; - } - astVariableDeclarator(iVarDecNode, retArr) { - this.astGeneric(iVarDecNode.id, retArr); - if (iVarDecNode.init !== null) { - retArr.push('='); - this.astGeneric(iVarDecNode.init, retArr); + astVariableDeclarator(iVarDecNode, retArr) { + this.astGeneric(iVarDecNode.id, retArr); + if (iVarDecNode.init !== null) { + retArr.push('='); + this.astGeneric(iVarDecNode.init, retArr); + } + return retArr; } - return retArr; - } - astThisExpression(ast, retArr) { - return retArr; - } - astSequenceExpression(sNode, retArr) { - for (let i = 0; i < sNode.expressions.length; i++) { - if (i > 0) { - retArr.push(','); + astThisExpression(ast, retArr) { + return retArr; + } + astSequenceExpression(sNode, retArr) { + for (let i = 0; i < sNode.expressions.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(sNode.expressions, retArr); } - this.astGeneric(sNode.expressions, retArr); + return retArr; } - return retArr; - } - astUnaryExpression(uNode, retArr) { - const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); - if (unaryResult) { + astUnaryExpression(uNode, retArr) { + const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); + if (unaryResult) { + return retArr; + } + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } return retArr; } - - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); + checkAndUpconvertBitwiseUnary(uNode, retArr) {} + astUpdateExpression(uNode, retArr) { + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } + return retArr; } - - return retArr; - } - - checkAndUpconvertBitwiseUnary(uNode, retArr) {} - - astUpdateExpression(uNode, retArr) { - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); + astLogicalExpression(logNode, retArr) { + retArr.push('('); + this.astGeneric(logNode.left, retArr); + retArr.push(logNode.operator); + this.astGeneric(logNode.right, retArr); + retArr.push(')'); + return retArr; } - - return retArr; - } - astLogicalExpression(logNode, retArr) { - retArr.push('('); - this.astGeneric(logNode.left, retArr); - retArr.push(logNode.operator); - this.astGeneric(logNode.right, retArr); - retArr.push(')'); - return retArr; - } - astMemberExpression(ast, retArr) { - return retArr; - } - astCallExpression(ast, retArr) { - return retArr; - } - astArrayExpression(ast, retArr) { - return retArr; - } - - getMemberExpressionDetails(ast) { - if (ast.type !== 'MemberExpression') { - throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast); - } - let name = null; - let type = null; - const variableSignature = this.getVariableSignature(ast); - switch (variableSignature) { - case 'value': - return null; - case 'value.thread.value': - case 'this.thread.value': - case 'this.output.value': - return { - signature: variableSignature, - type: 'Integer', - name: ast.property.name - }; - case 'value[]': - if (typeof ast.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object), - xProperty: ast.property - }; - case 'value[][]': - if (typeof ast.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object), - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value[][][]': - if (typeof ast.object.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object.object), - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value[][][][]': - if (typeof ast.object.object.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object.object.object), - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value.value': - if (typeof ast.property.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - if (this.isAstMathVariable(ast)) { - name = ast.property.name; + astMemberExpression(ast, retArr) { + return retArr; + } + astCallExpression(ast, retArr) { + return retArr; + } + astArrayExpression(ast, retArr) { + return retArr; + } + getMemberExpressionDetails(ast) { + if (ast.type !== 'MemberExpression') { + throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast); + } + let name = null; + let type = null; + const variableSignature = this.getVariableSignature(ast); + switch (variableSignature) { + case 'value': + return null; + case 'value.thread.value': + case 'this.thread.value': + case 'this.output.value': return { - name, - origin: 'Math', - type: 'Number', signature: variableSignature, + type: 'Integer', + name: ast.property.name }; - } - switch (ast.property.name) { - case 'r': - case 'g': - case 'b': - case 'a': - name = ast.object.name; - return { - name, - property: ast.property.name, - origin: 'user', - signature: variableSignature, - type: 'Number' - }; - default: - throw this.astErrorOutput('Unexpected expression', ast); - } - case 'this.constants.value': - if (typeof ast.property.name !== 'string') { + case 'value[]': + if (typeof ast.object.name !== 'string') { throw this.astErrorOutput('Unexpected expression', ast); } - name = ast.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } + name = ast.object.name; return { name, - type, - origin: 'constants', + origin: 'user', signature: variableSignature, + type: this.getVariableType(ast.object), + xProperty: ast.property }; - case 'this.constants.value[]': - if (typeof ast.object.property.name !== 'string') { + case 'value[][]': + if (typeof ast.object.object.name !== 'string') { throw this.astErrorOutput('Unexpected expression', ast); } - name = ast.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } + name = ast.object.object.name; return { name, - type, - origin: 'constants', + origin: 'user', signature: variableSignature, + type: this.getVariableType(ast.object.object), + yProperty: ast.object.property, xProperty: ast.property, }; - case 'this.constants.value[][]': { - if (typeof ast.object.object.property.name !== 'string') { + case 'value[][][]': + if (typeof ast.object.object.object.name !== 'string') { throw this.astErrorOutput('Unexpected expression', ast); } - name = ast.object.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } + name = ast.object.object.object.name; return { name, - type, - origin: 'constants', - signature: variableSignature, - yProperty: ast.object.property, - xProperty: ast.property, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, }; - } - case 'this.constants.value[][][]': { - if (typeof ast.object.object.object.property.name !== 'string') { + case 'value[][][][]': + if (typeof ast.object.object.object.object.name !== 'string') { throw this.astErrorOutput('Unexpected expression', ast); } - name = ast.object.object.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } + name = ast.object.object.object.object.name; return { name, - type, - origin: 'constants', - signature: variableSignature, - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - } - case 'fn()[]': - case '[][]': - return { - signature: variableSignature, - property: ast.property, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, }; - default: - throw this.astErrorOutput('Unexpected expression', ast); - } - } - - findIdentifierOrigin(astToFind) { - const stack = [this.ast]; - - while (stack.length > 0) { - const atNode = stack[0]; - if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) { - return atNode; + case 'value.value': + if (typeof ast.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + if (this.isAstMathVariable(ast)) { + name = ast.property.name; + return { + name, + origin: 'Math', + type: 'Number', + signature: variableSignature, + }; + } + switch (ast.property.name) { + case 'r': + case 'g': + case 'b': + case 'a': + name = ast.object.name; + return { + name, + property: ast.property.name, + origin: 'user', + signature: variableSignature, + type: 'Number' + }; + default: + throw this.astErrorOutput('Unexpected expression', ast); + } + case 'this.constants.value': + if (typeof ast.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + }; + case 'this.constants.value[]': + if (typeof ast.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + xProperty: ast.property, + }; + case 'this.constants.value[][]': { + if (typeof ast.object.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + yProperty: ast.object.property, + xProperty: ast.property, + }; + } + case 'this.constants.value[][][]': { + if (typeof ast.object.object.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, + }; + } + case 'fn()[]': + case '[][]': + return { + signature: variableSignature, + property: ast.property, + }; + default: + throw this.astErrorOutput('Unexpected expression', ast); } - stack.shift(); - if (atNode.argument) { - stack.push(atNode.argument); - } else if (atNode.body) { - stack.push(atNode.body); - } else if (atNode.declarations) { - stack.push(atNode.declarations); - } else if (Array.isArray(atNode)) { - for (let i = 0; i < atNode.length; i++) { - stack.push(atNode[i]); + } + findIdentifierOrigin(astToFind) { + const stack = [this.ast]; + while (stack.length > 0) { + const atNode = stack[0]; + if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) { + return atNode; + } + stack.shift(); + if (atNode.argument) { + stack.push(atNode.argument); + } else if (atNode.body) { + stack.push(atNode.body); + } else if (atNode.declarations) { + stack.push(atNode.declarations); + } else if (Array.isArray(atNode)) { + for (let i = 0; i < atNode.length; i++) { + stack.push(atNode[i]); + } } } + return null; } - return null; - } - - findLastReturn(ast) { - const stack = [ast || this.ast]; - - while (stack.length > 0) { - const atNode = stack.pop(); - if (atNode.type === 'ReturnStatement') { - return atNode; - } - if (atNode.type === 'FunctionDeclaration') { - continue; - } - if (atNode.argument) { - stack.push(atNode.argument); - } else if (atNode.body) { - stack.push(atNode.body); - } else if (atNode.declarations) { - stack.push(atNode.declarations); - } else if (Array.isArray(atNode)) { - for (let i = 0; i < atNode.length; i++) { - stack.push(atNode[i]); - } - } else if (atNode.consequent) { - stack.push(atNode.consequent); - } else if (atNode.cases) { - stack.push(atNode.cases); + findLastReturn(ast) { + const stack = [ast || this.ast]; + while (stack.length > 0) { + const atNode = stack.pop(); + if (atNode.type === 'ReturnStatement') { + return atNode; + } + if (atNode.type === 'FunctionDeclaration') { + continue; + } + if (atNode.argument) { + stack.push(atNode.argument); + } else if (atNode.body) { + stack.push(atNode.body); + } else if (atNode.declarations) { + stack.push(atNode.declarations); + } else if (Array.isArray(atNode)) { + for (let i = 0; i < atNode.length; i++) { + stack.push(atNode[i]); + } + } else if (atNode.consequent) { + stack.push(atNode.consequent); + } else if (atNode.cases) { + stack.push(atNode.cases); + } } + return null; } - return null; - } - - getInternalVariableName(name) { - if (!this._internalVariableNames.hasOwnProperty(name)) { - this._internalVariableNames[name] = 0; - } - this._internalVariableNames[name]++; - if (this._internalVariableNames[name] === 1) { - return name; - } - return name + this._internalVariableNames[name]; - } - - varWarn() { - console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); - } -} - -const typeLookupMap = { - 'Number': 'Number', - 'Float': 'Float', - 'Integer': 'Integer', - 'Array': 'Number', - 'Array(2)': 'Number', - 'Array(3)': 'Number', - 'Array(4)': 'Number', - 'Array2D': 'Number', - 'Array3D': 'Number', - 'Input': 'Number', - 'HTMLImage': 'Array(4)', - 'HTMLVideo': 'Array(4)', - 'HTMLImageArray': 'Array(4)', - 'NumberTexture': 'Number', - 'MemoryOptimizedNumberTexture': 'Number', - 'Array1D(2)': 'Array(2)', - 'Array1D(3)': 'Array(3)', - 'Array1D(4)': 'Array(4)', - 'Array2D(2)': 'Array(2)', - 'Array2D(3)': 'Array(3)', - 'Array2D(4)': 'Array(4)', - 'Array3D(2)': 'Array(2)', - 'Array3D(3)': 'Array(3)', - 'Array3D(4)': 'Array(4)', - 'ArrayTexture(1)': 'Number', - 'ArrayTexture(2)': 'Array(2)', - 'ArrayTexture(3)': 'Array(3)', - 'ArrayTexture(4)': 'Array(4)', -}; - -module.exports = { - FunctionNode -}; -},{"../utils":111,"./function-tracer":10,"acorn":1}],10:[function(require,module,exports){ -class FunctionTracer { - constructor(ast) { - this.runningContexts = []; - this.contexts = []; - this.functionCalls = []; - this.declarations = []; - this.identifiers = []; - this.functions = []; - this.returnStatements = []; - this.inLoopInit = false; - this.scan(ast); - } - - get currentContext() { - return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; - } - - newContext(run) { - const newContext = Object.assign({}, this.currentContext); - this.contexts.push(newContext); - this.runningContexts.push(newContext); - run(); - this.runningContexts.pop(); - } - - scan(ast) { - if (!ast) return; - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.scan(ast[i]); - } - return; - } - switch (ast.type) { - case 'Program': - this.scan(ast.body); - break; - case 'BlockStatement': - this.newContext(() => { - this.scan(ast.body); - }); - break; - case 'AssignmentExpression': - case 'LogicalExpression': - this.scan(ast.left); - this.scan(ast.right); - break; - case 'BinaryExpression': - this.scan(ast.left); - this.scan(ast.right); - break; - case 'UpdateExpression': - case 'UnaryExpression': - this.scan(ast.argument); - break; - case 'VariableDeclaration': - this.scan(ast.declarations); - break; - case 'VariableDeclarator': - const { currentContext } = this; - const declaration = { - ast: ast, - context: currentContext, - name: ast.id.name, - origin: 'declaration', - forceInteger: this.inLoopInit, - assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name), - }; - currentContext[ast.id.name] = declaration; - this.declarations.push(declaration); - this.scan(ast.id); - this.scan(ast.init); - break; - case 'FunctionExpression': - case 'FunctionDeclaration': - if (this.runningContexts.length === 0) { - this.scan(ast.body); - } else { - this.functions.push(ast); - } - break; - case 'IfStatement': - this.scan(ast.test); - this.scan(ast.consequent); - if (ast.alternate) this.scan(ast.alternate); - break; - case 'ForStatement': - this.newContext(() => { - this.inLoopInit = true; - this.scan(ast.init); - this.inLoopInit = false; - this.scan(ast.test); - this.scan(ast.update); - this.newContext(() => { - this.scan(ast.body); - }); - }); - break; - case 'DoWhileStatement': - case 'WhileStatement': - this.newContext(() => { - this.scan(ast.body); - this.scan(ast.test); - }); - break; - case 'Identifier': - this.identifiers.push({ - context: this.currentContext, - ast, - }); - break; - case 'ReturnStatement': - this.returnStatements.push(ast); - this.scan(ast.argument); - break; - case 'MemberExpression': - this.scan(ast.object); - this.scan(ast.property); - break; - case 'ExpressionStatement': - this.scan(ast.expression); - break; - case 'CallExpression': - this.functionCalls.push({ - context: this.currentContext, - ast, - }); - this.scan(ast.arguments); - break; - case 'ArrayExpression': - this.scan(ast.elements); - break; - case 'ConditionalExpression': - this.scan(ast.test); - this.scan(ast.alternate); - this.scan(ast.consequent); - break; - case 'SwitchStatement': - this.scan(ast.discriminant); - this.scan(ast.cases); - break; - case 'SwitchCase': - this.scan(ast.test); - this.scan(ast.consequent); - break; - - case 'ThisExpression': - case 'Literal': - case 'DebuggerStatement': - case 'EmptyStatement': - case 'BreakStatement': - case 'ContinueStatement': - break; - - default: - throw new Error(`unhandled type "${ast.type}"`); - } - } -} - -module.exports = { - FunctionTracer, -}; -},{}],11:[function(require,module,exports){ -const { glWiretap } = require('gl-wiretap'); -const { utils } = require('../../utils'); - -function toStringWithoutUtils(fn) { - return fn.toString() - .replace('=>', '') - .replace(/^function /, '') - .replace(/utils[.]/g, '/*utils.*/'); -} + getInternalVariableName(name) { + if (!this._internalVariableNames.hasOwnProperty(name)) { + this._internalVariableNames[name] = 0; + } + this._internalVariableNames[name]++; + if (this._internalVariableNames[name] === 1) { + return name; + } + return name + this._internalVariableNames[name]; + } + varWarn() { + console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); + } + } + const typeLookupMap = { + 'Number': 'Number', + 'Float': 'Float', + 'Integer': 'Integer', + 'Array': 'Number', + 'Array(2)': 'Number', + 'Array(3)': 'Number', + 'Array(4)': 'Number', + 'Array2D': 'Number', + 'Array3D': 'Number', + 'Input': 'Number', + 'HTMLImage': 'Array(4)', + 'HTMLVideo': 'Array(4)', + 'HTMLImageArray': 'Array(4)', + 'NumberTexture': 'Number', + 'MemoryOptimizedNumberTexture': 'Number', + 'Array1D(2)': 'Array(2)', + 'Array1D(3)': 'Array(3)', + 'Array1D(4)': 'Array(4)', + 'Array2D(2)': 'Array(2)', + 'Array2D(3)': 'Array(3)', + 'Array2D(4)': 'Array(4)', + 'Array3D(2)': 'Array(2)', + 'Array3D(3)': 'Array(3)', + 'Array3D(4)': 'Array(4)', + 'ArrayTexture(1)': 'Number', + 'ArrayTexture(2)': 'Array(2)', + 'ArrayTexture(3)': 'Array(3)', + 'ArrayTexture(4)': 'Array(4)', + }; -function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { - args = args ? Array.from(args).map(arg => { - switch (typeof arg) { - case 'boolean': - return new Boolean(arg); - case 'number': - return new Number(arg); - default: - return arg; - } - }) : null; - const uploadedValues = []; - const postResult = []; - const context = glWiretap(originKernel.context, { - useTrackablePrimitives: true, - onReadPixels: (targetName) => { - if (kernel.subKernels) { - if (!subKernelsResultVariableSetup) { - postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`); - subKernelsResultVariableSetup = true; - } else { - const property = kernel.subKernels[subKernelsResultIndex++].property; - postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`); - } - if (subKernelsResultIndex === kernel.subKernels.length) { - postResult.push(' return result;'); + class CPUFunctionNode extends FunctionNode { + astFunction(ast, retArr) { + if (!this.isRootKernel) { + retArr.push('function'); + retArr.push(' '); + retArr.push(this.name); + retArr.push('('); + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + if (i > 0) { + retArr.push(', '); + } + retArr.push('user_'); + retArr.push(argumentName); } - return; + retArr.push(') {\n'); } - if (targetName) { - postResult.push(` return ${getRenderString(targetName, kernel)};`); - } else { - postResult.push(` return null;`); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); } - }, - onUnrecognizedArgumentLookup: (argument) => { - const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues); - if (argumentName) { - return argumentName; + if (!this.isRootKernel) { + retArr.push('}\n'); } - const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues); - if (constantName) { - return constantName; + return retArr; + } + astReturnStatement(ast, retArr) { + const type = this.returnType || this.getType(ast.argument); + if (!this.returnType) { + this.returnType = type; } - return null; + if (this.isRootKernel) { + retArr.push(this.leadingReturnStatement); + this.astGeneric(ast.argument, retArr); + retArr.push(';\n'); + retArr.push(this.followingReturnStatement); + retArr.push('continue;\n'); + } else if (this.isSubKernel) { + retArr.push(`subKernelResult_${ this.name } = `); + this.astGeneric(ast.argument, retArr); + retArr.push(';'); + retArr.push(`return subKernelResult_${ this.name };`); + } else { + retArr.push('return '); + this.astGeneric(ast.argument, retArr); + retArr.push(';'); + } + return retArr; } - }); - let subKernelsResultVariableSetup = false; - let subKernelsResultIndex = 0; - const { - source, - canvas, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - kernelArguments, - kernelConstants, - } = originKernel; - const kernel = new Kernel(source, { - canvas, - context, - checkContext: false, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - }); - let result = []; - context.setIndent(2); - kernel.build.apply(kernel, args); - result.push(context.toString()); - context.reset(); - - kernel.kernelArguments.forEach((kernelArgument, i) => { - switch (kernelArgument.type) { - case 'Integer': - case 'Boolean': - case 'Number': - case 'Float': - case 'Array': - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - case 'HTMLImage': - case 'HTMLVideo': - context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); - break; - case 'HTMLImageArray': - for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) { - const arg = args[i]; - context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]); - } - break; - case 'Input': - context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); - break; - case 'MemoryOptimizedNumberTexture': - case 'NumberTexture': - case 'Array1D(2)': - case 'Array1D(3)': - case 'Array1D(4)': - case 'Array2D(2)': - case 'Array2D(3)': - case 'Array2D(4)': - case 'Array3D(2)': - case 'Array3D(3)': - case 'Array3D(4)': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture); - break; - default: - throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`); + astLiteral(ast, retArr) { + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + retArr.push(ast.value); + return retArr; } - }); - result.push('/** start of injected functions **/'); - result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.isArray)}`); - if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) { - result.push( - ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};` - ); - } - result.push('/** end of injected functions **/'); - result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`); - context.setIndent(4); - kernel.run.apply(kernel, args); - if (kernel.renderKernels) { - kernel.renderKernels(); - } else if (kernel.renderOutput) { - kernel.renderOutput(); - } - result.push(' /** start setup uploads for kernel values **/'); - kernel.kernelArguments.forEach(kernelArgument => { - result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n ')); - }); - result.push(' /** end setup uploads for kernel values **/'); - result.push(context.toString()); - if (kernel.renderOutput === kernel.renderTexture) { - context.reset(); - const results = kernel.renderKernels(); - const textureName = context.getContextVariableName(kernel.outputTexture); - result.push(` return { - result: { - texture: ${ textureName }, - type: '${ results.result.type }', - toArray: ${ getToArrayString(results.result, textureName) } - },`); - const { subKernels, subKernelOutputTextures } = kernel; - for (let i = 0; i < subKernels.length; i++) { - const texture = subKernelOutputTextures[i]; - const subKernel = subKernels[i]; - const subKernelResult = results[subKernel.property]; - const subKernelTextureName = context.getContextVariableName(texture); - result.push(` - ${subKernel.property}: { - texture: ${ subKernelTextureName }, - type: '${ subKernelResult.type }', - toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } - },`); + astBinaryExpression(ast, retArr) { + retArr.push('('); + this.astGeneric(ast.left, retArr); + retArr.push(ast.operator); + this.astGeneric(ast.right, retArr); + retArr.push(')'); + return retArr; } - result.push(` };`); - } - result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`); - result.push(postResult.join('\n')); - result.push(' };'); - if (kernel.graphical) { - result.push(getGetPixelsString(kernel)); - result.push(` innerKernel.getPixels = getPixels;`); - } - result.push(' return innerKernel;'); - - let constantsUpload = []; - kernelConstants.forEach((kernelConstant) => { - constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`); - }); - return `function kernel(settings) { - const { context, constants } = settings; - ${constantsUpload.join('')} - ${setupContextString ? setupContextString : ''} -${result.join('\n')} -}`; -} - -function getRenderString(targetName, kernel) { - const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`; - if (kernel.output[2]) { - return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`; - } - if (kernel.output[1]) { - return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`; - } - - return `renderOutput(${readBackValue}, ${kernel.output[0]})`; -} - -function getGetPixelsString(kernel) { - const getPixels = kernel.getPixels.toString(); - const useFunctionKeyword = !/^function/.test(getPixels); - return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, { - findDependency: (object, name) => { - if (object === 'utils') { - return `const ${name} = ${utils[name].toString()};`; - } - return null; - }, - thisLookup: (property) => { - if (property === 'context') { - return null; + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); } - if (kernel.hasOwnProperty(property)) { - return JSON.stringify(kernel[property]); + switch (idtNode.name) { + case 'Infinity': + retArr.push('Infinity'); + break; + default: + if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { + retArr.push('constants_' + idtNode.name); + } else { + retArr.push('user_' + idtNode.name); + } } - throw new Error(`unhandled thisLookup ${ property }`); + return retArr; } - }); -} - -function getToArrayString(kernelResult, textureName) { - const toArray = kernelResult.toArray.toString(); - const useFunctionKeyword = !/^function/.test(toArray); - const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, { - findDependency: (object, name) => { - if (object === 'utils') { - return `const ${name} = ${utils[name].toString()};`; - } else if (object === 'this') { - return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + astForStatement(forNode, retArr) { + if (forNode.type !== 'ForStatement') { + throw this.astErrorOutput('Invalid for statement', forNode); + } + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + if (forNode.init) { + this.pushState('in-for-loop-init'); + this.astGeneric(forNode.init, initArr); + for (let i = 0; i < initArr.length; i++) { + if (initArr[i].includes && initArr[i].includes(',')) { + isSafe = false; + } + } + this.popState('in-for-loop-init'); } else { - throw new Error('unhandled fromObject'); + isSafe = false; } - }, - thisLookup: (property) => { - if (property === 'texture') { - return textureName; + if (forNode.test) { + this.astGeneric(forNode.test, testArr); + } else { + isSafe = false; + } + if (forNode.update) { + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; + } + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); + } + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); } - if (kernelResult.hasOwnProperty(property)) { - return JSON.stringify(kernelResult[property]); + if (isSafe) { + retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); + retArr.push(bodyArr.join('')); + retArr.push('}\n'); + } else { + const iVariableName = this.getInternalVariableName('safeI'); + if (initArr.length > 0) { + retArr.push(initArr.join(''), ';\n'); + } + retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) { + retArr.push(`if (!${testArr.join('')}) break;\n`); + } + retArr.push(bodyArr.join('')); + retArr.push(`\n${updateArr.join('')};`); + retArr.push('}\n'); } - throw new Error(`unhandled thisLookup ${ property }`); + return retArr; } - }); - return `() => { - ${flattenedFunctions} - return toArray(); - }`; -} - -function findKernelValue(argument, kernelValues, values, context, uploadedValues) { - if (argument === null) return null; - switch (typeof argument) { - case 'boolean': - case 'number': - return null; - } - if ( - typeof HTMLImageElement !== 'undefined' && - argument instanceof HTMLImageElement - ) { - for (let i = 0; i < kernelValues.length; i++) { - const kernelValue = kernelValues[i]; - if (kernelValue.type !== 'HTMLImageArray') continue; - if (kernelValue.uploadValue !== argument) continue; - const variableIndex = values[i].indexOf(argument); - if (variableIndex === -1) continue; - const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`; - context.insertVariable(variableName, argument); - return variableName; + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput( + 'Invalid while statement', + whileNode + ); + } + retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); + retArr.push('if ('); + this.astGeneric(whileNode.test, retArr); + retArr.push(') {\n'); + this.astGeneric(whileNode.body, retArr); + retArr.push('} else {\n'); + retArr.push('break;\n'); + retArr.push('}\n'); + retArr.push('}\n'); + return retArr; } - return null; - } - - for (let i = 0; i < kernelValues.length; i++) { - const kernelValue = kernelValues[i]; - if (argument !== kernelValue.uploadValue) continue; - const variable = `uploadValue_${kernelValue.name}`; - context.insertVariable(variable, kernelValue); - return variable; - } - return null; -} - -module.exports = { - glKernelString -}; -},{"../../utils":111,"gl-wiretap":2}],12:[function(require,module,exports){ -const { Kernel } = require('../kernel'); -const { Texture } = require('../../texture'); -const { utils } = require('../../utils'); -const { GLTextureArray2Float } = require('./texture/array-2-float'); -const { GLTextureArray2Float2D } = require('./texture/array-2-float-2d'); -const { GLTextureArray2Float3D } = require('./texture/array-2-float-3d'); -const { GLTextureArray3Float } = require('./texture/array-3-float'); -const { GLTextureArray3Float2D } = require('./texture/array-3-float-2d'); -const { GLTextureArray3Float3D } = require('./texture/array-3-float-3d'); -const { GLTextureArray4Float } = require('./texture/array-4-float'); -const { GLTextureArray4Float2D } = require('./texture/array-4-float-2d'); -const { GLTextureArray4Float3D } = require('./texture/array-4-float-3d'); -const { GLTextureFloat } = require('./texture/float'); -const { GLTextureFloat2D } = require('./texture/float-2d'); -const { GLTextureFloat3D } = require('./texture/float-3d'); -const { GLTextureMemoryOptimized } = require('./texture/memory-optimized'); -const { GLTextureMemoryOptimized2D } = require('./texture/memory-optimized-2d'); -const { GLTextureMemoryOptimized3D } = require('./texture/memory-optimized-3d'); -const { GLTextureUnsigned } = require('./texture/unsigned'); -const { GLTextureUnsigned2D } = require('./texture/unsigned-2d'); -const { GLTextureUnsigned3D } = require('./texture/unsigned-3d'); -const { GLTextureGraphical } = require('./texture/graphical'); - -class GLKernel extends Kernel { - static get mode() { - return 'gpu'; - } - - static getIsFloatRead() { - const kernelString = `function kernelFunction() { - return 1; - }`; - const kernel = new this(kernelString, { - context: this.testContext, - canvas: this.testCanvas, - validate: false, - output: [1], - precision: 'single', - returnType: 'Number', - tactic: 'speed', - }); - kernel.build(); - kernel.run(); - const result = kernel.renderOutput(); - kernel.destroy(true); - return result[0] === 1; - } - - static getIsIntegerDivisionAccurate() { - function kernelFunction(v1, v2) { - return v1[this.thread.x] / v2[this.thread.x]; - } - const kernel = new this(kernelFunction.toString(), { - context: this.testContext, - canvas: this.testCanvas, - validate: false, - output: [2], - returnType: 'Number', - precision: 'unsigned', - tactic: 'speed', - }); - const args = [ - [6, 6030401], - [3, 3991] - ]; - kernel.build.apply(kernel, args); - kernel.run.apply(kernel, args); - const result = kernel.renderOutput(); - kernel.destroy(true); - return result[0] === 2 && result[1] === 1511; - } - - static get testCanvas() { - throw new Error(`"testCanvas" not defined on ${ this.name }`); - } - - static get testContext() { - throw new Error(`"testContext" not defined on ${ this.name }`); - } - - static get features() { - throw new Error(`"features" not defined on ${ this.name }`); - } - - static setupFeatureChecks() { - throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); - } - - setFixIntegerDivisionAccuracy(fix) { - this.fixIntegerDivisionAccuracy = fix; - return this; - } - - setPrecision(flag) { - this.precision = flag; - return this; - } - - setFloatTextures(flag) { - utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory'); - this.floatTextures = flag; - return this; - } - - static nativeFunctionArguments(source) { - const argumentTypes = []; - const argumentNames = []; - const states = []; - const isStartingVariableName = /^[a-zA-Z_]/; - const isVariableChar = /[a-zA-Z_0-9]/; - let i = 0; - let argumentName = null; - let argumentType = null; - while (i < source.length) { - const char = source[i]; - const nextChar = source[i + 1]; - const state = states.length > 0 ? states[states.length - 1] : null; - - if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') { - states.push('MULTI_LINE_COMMENT'); - i += 2; - continue; - } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') { - states.pop(); - i += 2; - continue; + astDoWhileStatement(doWhileNode, retArr) { + if (doWhileNode.type !== 'DoWhileStatement') { + throw this.astErrorOutput( + 'Invalid while statement', + doWhileNode + ); } - - else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') { - states.push('COMMENT'); - i += 2; - continue; - } else if (state === 'COMMENT' && char === '\n') { - states.pop(); - i++; - continue; + retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); + this.astGeneric(doWhileNode.body, retArr); + retArr.push('if (!'); + this.astGeneric(doWhileNode.test, retArr); + retArr.push(') {\n'); + retArr.push('break;\n'); + retArr.push('}\n'); + retArr.push('}\n'); + return retArr; + } + astAssignmentExpression(assNode, retArr) { + const declaration = this.getDeclaration(assNode.left); + if (declaration && !declaration.assignable) { + throw new this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode); } - - else if (state === null && char === '(') { - states.push('FUNCTION_ARGUMENTS'); - i++; - continue; - } else if (state === 'FUNCTION_ARGUMENTS') { - if (char === ')') { - states.pop(); - break; + this.astGeneric(assNode.left, retArr); + retArr.push(assNode.operator); + this.astGeneric(assNode.right, retArr); + return retArr; + } + astBlockStatement(bNode, retArr) { + if (this.isState('loop-body')) { + this.pushState('block-body'); + for (let i = 0; i < bNode.body.length; i++) { + this.astGeneric(bNode.body[i], retArr); } - if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'float'; - argumentName = ''; - i += 6; - continue; - } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'int'; - argumentName = ''; - i += 4; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec2'; - argumentName = ''; - i += 5; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec3'; - argumentName = ''; - i += 5; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec4'; - argumentName = ''; - i += 5; + this.popState('block-body'); + } else { + retArr.push('{\n'); + for (let i = 0; i < bNode.body.length; i++) { + this.astGeneric(bNode.body[i], retArr); + } + retArr.push('}\n'); + } + return retArr; + } + astVariableDeclaration(varDecNode, retArr) { + if (varDecNode.kind === 'var' && this.warnVarUsage) { + this.varWarn(); + } + retArr.push(`${varDecNode.kind} `); + const { declarations } = varDecNode; + for (let i = 0; i < declarations.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(declarations[i], retArr); + } + if (!this.isState('in-for-loop-init')) { + retArr.push(';'); + } + return retArr; + } + astIfStatement(ifNode, retArr) { + retArr.push('if ('); + this.astGeneric(ifNode.test, retArr); + retArr.push(')'); + if (ifNode.consequent.type === 'BlockStatement') { + this.astGeneric(ifNode.consequent, retArr); + } else { + retArr.push(' {\n'); + this.astGeneric(ifNode.consequent, retArr); + retArr.push('\n}\n'); + } + if (ifNode.alternate) { + retArr.push('else '); + if (ifNode.alternate.type === 'BlockStatement') { + this.astGeneric(ifNode.alternate, retArr); + } else { + retArr.push(' {\n'); + this.astGeneric(ifNode.alternate, retArr); + retArr.push('\n}\n'); + } + } + return retArr; + } + astSwitchStatement(ast, retArr) { + const { discriminant, cases } = ast; + retArr.push('switch ('); + this.astGeneric(discriminant, retArr); + retArr.push(') {\n'); + for (let i = 0; i < cases.length; i++) { + if (cases[i].test === null) { + retArr.push('default:\n'); + this.astGeneric(cases[i].consequent, retArr); + if (cases[i].consequent && cases[i].consequent.length > 0) { + retArr.push('break;\n'); + } continue; } + retArr.push('case '); + this.astGeneric(cases[i].test, retArr); + retArr.push(':\n'); + if (cases[i].consequent && cases[i].consequent.length > 0) { + this.astGeneric(cases[i].consequent, retArr); + retArr.push('break;\n'); + } } - - else if (state === 'DECLARE_VARIABLE') { - if (argumentName === '') { - if (char === ' ') { - i++; - continue; + retArr.push('\n}'); + } + astThisExpression(tNode, retArr) { + retArr.push('_this'); + return retArr; + } + astMemberExpression(mNode, retArr) { + const { + signature, + type, + property, + xProperty, + yProperty, + zProperty, + name, + origin + } = this.getMemberExpressionDetails(mNode); + switch (signature) { + case 'this.thread.value': + retArr.push(`_this.thread.${ name }`); + return retArr; + case 'this.output.value': + switch (name) { + case 'x': + retArr.push('outputX'); + break; + case 'y': + retArr.push('outputY'); + break; + case 'z': + retArr.push('outputZ'); + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); } - if (!isStartingVariableName.test(char)) { - throw new Error('variable name is not expected string'); + return retArr; + case 'value': + throw this.astErrorOutput('Unexpected expression', mNode); + case 'value[]': + case 'value[][]': + case 'value[][][]': + case 'value.value': + if (origin === 'Math') { + retArr.push(Math[name]); + return retArr; + } + switch (property) { + case 'r': + retArr.push(`user_${ name }[0]`); + return retArr; + case 'g': + retArr.push(`user_${ name }[1]`); + return retArr; + case 'b': + retArr.push(`user_${ name }[2]`); + return retArr; + case 'a': + retArr.push(`user_${ name }[3]`); + return retArr; } + break; + case 'this.constants.value': + case 'this.constants.value[]': + case 'this.constants.value[][]': + case 'this.constants.value[][][]': + break; + case 'fn()[]': + this.astGeneric(mNode.object, retArr); + retArr.push('['); + this.astGeneric(mNode.property, retArr); + retArr.push(']'); + return retArr; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + if (!mNode.computed) { + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + retArr.push(`${origin}_${name}`); + return retArr; } - argumentName += char; - if (!isVariableChar.test(nextChar)) { - states.pop(); - argumentNames.push(argumentName); - argumentTypes.push(typeMap[argumentType]); + } + const markupName = `${origin}_${name}`; + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + case 'HTMLImageArray': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'HTMLImage': + default: + let size; + let isInput; + if (origin === 'constants') { + const constant = this.constants[name]; + isInput = this.constantTypes[name] === 'Input'; + size = isInput ? constant.size : null; + } else { + isInput = this.isInput(name); + size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null; + } + retArr.push(`${ markupName }`); + if (zProperty && yProperty) { + if (isInput) { + retArr.push('[('); + this.astGeneric(zProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`); + this.astGeneric(yProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } else { + retArr.push('['); + this.astGeneric(zProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(yProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } + } else if (yProperty) { + if (isInput) { + retArr.push('[('); + this.astGeneric(yProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } else { + retArr.push('['); + this.astGeneric(yProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } + } else if (typeof xProperty !== 'undefined') { + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } + } + return retArr; + } + astCallExpression(ast, retArr) { + if (ast.type !== 'CallExpression') { + throw this.astErrorOutput('Unknown CallExpression', ast); + } + let functionName = this.astMemberExpressionUnroll(ast.callee); + if (this.calledFunctions.indexOf(functionName) < 0) { + this.calledFunctions.push(functionName); + } + const isMathFunction = this.isAstMathFunction(ast); + if (this.onFunctionCall) { + this.onFunctionCall(this.name, functionName, ast.arguments); + } + retArr.push(functionName); + retArr.push('('); + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + let argumentType = this.getType(argument); + if (!targetTypes[i]) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); } + if (i > 0) { + retArr.push(', '); + } + this.astGeneric(argument, retArr); } - - i++; + retArr.push(')'); + return retArr; } - if (states.length > 0) { - throw new Error('GLSL function was not parsable'); + astArrayExpression(arrNode, retArr) { + const arrLen = arrNode.elements.length; + retArr.push('new Float32Array(['); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + this.astGeneric(subNode, retArr); + } + retArr.push('])'); + return retArr; + } + astDebuggerStatement(arrNode, retArr) { + retArr.push('debugger;'); + return retArr; } - return { - argumentNames, - argumentTypes, - }; - } - - static nativeFunctionReturnType(source) { - return typeMap[source.match(/int|float|vec[2-4]/)[0]]; } - static combineKernels(combinedKernel, lastKernel) { - combinedKernel.apply(null, arguments); - const { - texSize, - context, - threadDim - } = lastKernel.texSize; - let result; - if (lastKernel.precision === 'single') { - const w = texSize[0]; - const h = Math.ceil(texSize[1] / 4); - result = new Float32Array(w * h * 4 * 4); - context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result); - } else { - const bytes = new Uint8Array(texSize[0] * texSize[1] * 4); - context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes); - result = new Float32Array(bytes.buffer); + function constantsToString(constants, types) { + const results = []; + for (const name in types) { + if (!types.hasOwnProperty(name)) continue; + const type = types[name]; + const constant = constants[name]; + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + results.push(`${name}:${constant}`); + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); + break; + } } - - result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]); - - if (lastKernel.output.length === 1) { - return result; - } else if (lastKernel.output.length === 2) { - return utils.splitArray(result, lastKernel.output[0]); - } else if (lastKernel.output.length === 3) { - const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); - return cube.map(function(x) { - return utils.splitArray(x, lastKernel.output[0]); + return `{ ${ results.join() } }`; + } + function cpuKernelString(cpuKernel, name) { + const header = []; + const thisProperties = []; + const beforeReturn = []; + const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString()); + header.push( + ' const { context, canvas, constants: incomingConstants } = settings;', + ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`, + ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`, + ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`, + ); + thisProperties.push( + ' constants: _constants,', + ' context,', + ' output,', + ' thread: {x: 0, y: 0, z: 0},', + ); + if (cpuKernel.graphical) { + header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`); + header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`); + const colorFn = utils$1.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), { + thisLookup: (propertyName) => { + switch (propertyName) { + case '_colorData': + return '_colorData'; + case '_imageData': + return '_imageData'; + case 'output': + return 'output'; + case 'thread': + return 'this.thread'; + } + return JSON.stringify(cpuKernel[propertyName]); + }, + findDependency: (object, name) => { + return null; + } + }); + const getPixelsFn = utils$1.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), { + thisLookup: (propertyName) => { + switch (propertyName) { + case '_colorData': + return '_colorData'; + case '_imageData': + return '_imageData'; + case 'output': + return 'output'; + case 'thread': + return 'this.thread'; + } + return JSON.stringify(cpuKernel[propertyName]); + }, + findDependency: () => { + return null; + } }); + thisProperties.push( + ' _imageData,', + ' _colorData,', + ` color: ${colorFn},`, + ); + beforeReturn.push( + ` kernel.getPixels = ${getPixelsFn};` + ); } + const constantTypes = []; + const constantKeys = Object.keys(cpuKernel.constantTypes); + for (let i = 0; i < constantKeys.length; i++) { + constantTypes.push(cpuKernel.constantTypes[constantKeys]); + } + if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) { + const flattenedImageTo3DArray = utils$1.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), { + doNotDefine: ['canvas'], + findDependency: (object, name) => { + if (object === 'this') { + return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString(); + } + return null; + }, + thisLookup: (propertyName) => { + switch (propertyName) { + case 'canvas': + return; + case 'context': + return 'context'; + } + } + }); + beforeReturn.push(flattenedImageTo3DArray); + thisProperties.push(` _mediaTo2DArray,`); + thisProperties.push(` _imageTo3DArray,`); + } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) { + const flattenedImageTo2DArray = utils$1.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), { + findDependency: (object, name) => { + return null; + }, + thisLookup: (propertyName) => { + switch (propertyName) { + case 'canvas': + return 'settings.canvas'; + case 'context': + return 'settings.context'; + } + throw new Error('unhandled thisLookup'); + } + }); + beforeReturn.push(flattenedImageTo2DArray); + thisProperties.push(` _mediaTo2DArray,`); + } + return `function(settings) { +${ header.join('\n') } + for (const p in _constantTypes) { + if (!_constantTypes.hasOwnProperty(p)) continue; + const type = _constantTypes[p]; + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + if (incomingConstants.hasOwnProperty(p)) { + console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); + } + continue; + } + if (!incomingConstants.hasOwnProperty(p)) { + throw new Error('constant ' + p + ' not found'); + } + _constants[p] = incomingConstants[p]; + } + const kernel = (function() { +${cpuKernel._kernelString} + }) + .apply({ ${thisProperties.join('\n')} }); + ${ beforeReturn.join('\n') } + return kernel; +}`; } - constructor(source, settings) { - super(source, settings); - this.transferValues = null; - this.formatValues = null; - this.TextureConstructor = null; - this.renderOutput = null; - this.renderRawOutput = null; - this.texSize = null; - this.translatedSource = null; - this.renderStrategy = null; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - } - - checkTextureSize() { - const { features } = this.constructor; - if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) { - throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`); + class CPUKernel extends Kernel { + static getFeatures() { + return this.features; } - } - - translateSource() { - throw new Error(`"translateSource" not defined on ${this.constructor.name}`); - } - - pickRenderStrategy(args) { - if (this.graphical) { - this.renderRawOutput = this.readPackedPixelsToUint8Array; - this.transferValues = (pixels) => pixels; - this.TextureConstructor = GLTextureGraphical; + static get features() { + return Object.freeze({ + kernelMap: true, + isIntegerDivisionAccurate: true + }); + } + static get isSupported() { + return true; + } + static isContextMatch(context) { + return false; + } + static get mode() { + return 'cpu'; + } + static nativeFunctionArguments() { return null; } - if (this.precision === 'unsigned') { - this.renderRawOutput = this.readPackedPixelsToUint8Array; - this.transferValues = this.readPackedPixelsToFloat32Array; - if (this.pipeline) { - this.renderOutput = this.renderTexture; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToTextures; + static nativeFunctionReturnType() { + return null; + } + static combineKernels(combinedKernel) { + return combinedKernel; + } + constructor(source, settings) { + super(source, settings); + this.mergeSettings(source.settings || settings); + this._imageData = null; + this._colorData = null; + this._kernelString = null; + this.thread = { + x: 0, + y: 0, + z: 0 + }; + this.translatedSources = null; + } + initCanvas() { + if (typeof document !== 'undefined') { + return document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + return new OffscreenCanvas(0, 0); + } + } + initContext() { + if (!this.canvas) return null; + return this.canvas.getContext('2d'); + } + initPlugins(settings) { + return []; + } + validateSettings(args) { + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureUnsigned3D; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - return null; - } - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return this.requestFallback(args); - } - } else { - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToArrays; - } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - this.renderOutput = this.renderValues; - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureUnsigned3D; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - this.formatValues = utils.erect3DPackedFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - this.formatValues = utils.erect2DPackedFloat; - return null; - } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - this.formatValues = utils.erectPackedFloat; - return null; - } - - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return this.requestFallback(args); + const argType = utils$1.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils$1.getDimensions(argType); + } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { + this.output = args[0].output; + } else { + throw new Error('Auto output not supported for input type: ' + argType); } } - } else if (this.precision === 'single') { - this.renderRawOutput = this.readFloatPixelsToFloat32Array; - this.transferValues = this.readFloatPixelsToFloat32Array; - if (this.pipeline) { - this.renderStrategy = renderStrategy.FloatTexture; - this.renderOutput = this.renderTexture; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToTextures; + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.optimizeFloatMemory) { - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - return null; - } - } else { - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureFloat3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - return null; - } - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - return null; - } + } + this.checkOutput(); + } + translateSource() { + this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = '; + if (this.subKernels) { + const followingReturnStatement = []; + for (let i = 0; i < this.subKernels.length; i++) { + const { + name + } = this.subKernels[i]; + followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`); } + this.followingReturnStatement = followingReturnStatement.join(''); } - this.renderOutput = this.renderValues; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToArrays; + const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); + this.translatedSources = functionBuilder.getPrototypes('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); } - if (this.optimizeFloatMemory) { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized3D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; - this.formatValues = utils.erectMemoryOptimized3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; - this.formatValues = utils.erectMemoryOptimized2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; - this.formatValues = utils.erectMemoryOptimizedFloat; - return null; - } + } + build() { + this.setupConstants(); + this.setupArguments(arguments); + this.validateSettings(arguments); + this.translateSource(); + if (this.graphical) { + const { + canvas, + output + } = this; + if (!canvas) { + throw new Error('no canvas available for using graphical output'); + } + const width = output[0]; + const height = output[1] || 1; + canvas.width = width; + canvas.height = height; + this._imageData = this.context.createImageData(width, height); + this._colorData = new Uint8ClampedArray(width * height * 4); + } + const kernelString = this.getKernelString(); + this.kernelString = kernelString; + if (this.debug) { + console.log('Function output:'); + console.log(kernelString); + } + try { + this.run = new Function([], kernelString).bind(this)(); + } catch (e) { + console.error('An error occurred compiling the javascript: ', e); + } + } + color(r, g, b, a) { + if (typeof a === 'undefined') { + a = 1; + } + r = Math.floor(r * 255); + g = Math.floor(g * 255); + b = Math.floor(b * 255); + a = Math.floor(a * 255); + const width = this.output[0]; + const height = this.output[1]; + const x = this.thread.x; + const y = height - this.thread.y - 1; + const index = x + y * width; + this._colorData[index * 4 + 0] = r; + this._colorData[index * 4 + 1] = g; + this._colorData[index * 4 + 2] = b; + this._colorData[index * 4 + 3] = a; + } + getKernelString() { + if (this._kernelString !== null) return this._kernelString; + let kernelThreadString = null; + let { + translatedSources + } = this; + if (translatedSources.length > 1) { + translatedSources = translatedSources.filter(fn => { + if (/^function/.test(fn)) return fn; + kernelThreadString = fn; + return false; + }); + } else { + kernelThreadString = translatedSources.shift(); + } + return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() }; + ${ this.injectedNative || '' } + const _this = this; + ${ this._processConstants() } + return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { + ${ this._processArguments() } + ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) } + ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' } + };`; + } + toString() { + return cpuKernelString(this); + } + _getLoopMaxString() { + return ( + this.loopMaxIterations ? + ` ${ parseInt(this.loopMaxIterations) };` : + ' 1000;' + ); + } + _processConstants() { + if (!this.constants) return ''; + const result = []; + for (let p in this.constants) { + const type = this.constantTypes[p]; + switch (type) { + case 'HTMLImage': + case 'HTMLVideo': + result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`); break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } + case 'HTMLImageArray': + result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`); break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } + case 'Input': + result.push(` const constants_${p} = this.constants.${p}.value;\n`); break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } + default: + result.push(` const constants_${p} = this.constants.${p};\n`); } - } else { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureFloat3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; - this.formatValues = utils.erect3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; - this.formatValues = utils.erect2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - this.renderStrategy = renderStrategy.FloatPixelToFloat; - this.formatValues = utils.erectFloat; - return null; - } + } + return result.join(''); + } + _processArguments() { + const result = []; + for (let i = 0; i < this.argumentTypes.length; i++) { + const variableName = `user_${this.argumentNames[i]}`; + switch (this.argumentTypes[i]) { + case 'HTMLImage': + case 'HTMLVideo': + result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`); break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } + case 'HTMLImageArray': + result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`); break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } + case 'Input': + result.push(` ${variableName} = ${variableName}.value;\n`); + break; + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'NumberTexture': + case 'MemoryOptimizedNumberTexture': + result.push(` + if (${variableName}.toArray) { + if (!_this.textureCache) { + _this.textureCache = []; + _this.arrayCache = []; + } + const textureIndex = _this.textureCache.indexOf(${variableName}); + if (textureIndex !== -1) { + ${variableName} = _this.arrayCache[textureIndex]; + } else { + _this.textureCache.push(${variableName}); + ${variableName} = ${variableName}.toArray(); + _this.arrayCache.push(${variableName}); + } + }`); break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } } } - } else { - throw new Error(`unhandled precision of "${this.precision}"`); + return result.join(''); + } + _mediaTo2DArray(media) { + const canvas = this.canvas; + const width = media.width > 0 ? media.width : media.videoWidth; + const height = media.height > 0 ? media.height : media.videoHeight; + if (canvas.width < width) { + canvas.width = width; + } + if (canvas.height < height) { + canvas.height = height; + } + const ctx = this.context; + ctx.drawImage(media, 0, 0, width, height); + const pixelsData = ctx.getImageData(0, 0, width, height).data; + const imageArray = new Array(height); + let index = 0; + for (let y = height - 1; y >= 0; y--) { + const row = imageArray[y] = new Array(width); + for (let x = 0; x < width; x++) { + const pixel = new Float32Array(4); + pixel[0] = pixelsData[index++] / 255; + pixel[1] = pixelsData[index++] / 255; + pixel[2] = pixelsData[index++] / 255; + pixel[3] = pixelsData[index++] / 255; + row[x] = pixel; + } + } + return imageArray; + } + getPixels(flip) { + const [width, height] = this.output; + return flip ? utils$1.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0); + } + _imageTo3DArray(images) { + const imagesArray = new Array(images.length); + for (let i = 0; i < images.length; i++) { + imagesArray[i] = this._mediaTo2DArray(images[i]); + } + return imagesArray; + } + _resultKernelBody(kernelString) { + switch (this.output.length) { + case 1: + return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); + case 2: + return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); + case 3: + return this._resultKernel3DLoop(kernelString) + this._kernelOutput(); + default: + throw new Error('unsupported size kernel'); + } + } + _graphicalKernelBody(kernelThreadString) { + switch (this.output.length) { + case 2: + return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput(); + default: + throw new Error('unsupported size kernel'); + } + } + _graphicalOutput() { + return ` + this._imageData.data.set(this._colorData); + this.context.putImageData(this._imageData, 0, 0); + return;` + } + _getKernelResultTypeConstructorString() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return 'Float32Array'; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return 'Array'; + default: + if (this.graphical) { + return 'Float32Array'; + } + throw new Error(`unhandled returnType ${ this.returnType }`); + } + } + _resultKernel1DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const result = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + this.thread.y = 0; + this.thread.z = 0; + ${ kernelString } + }`; + } + _resultKernel2DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const result = new Array(outputY); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + const resultX = result[y] = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + }`; + } + _graphicalKernel2DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + }`; + } + _resultKernel3DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const outputZ = _this.output[2]; + const result = new Array(outputZ); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let z = 0; z < outputZ; z++) { + this.thread.z = z; + const resultY = result[z] = new Array(outputY); + ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.y = y; + const resultX = resultY[y] = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + } + }`; + } + _kernelOutput() { + if (!this.subKernels) { + return '\n return result;'; + } + return `\n return { + result: result, + ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') } + };`; + } + _mapSubKernels(fn) { + return this.subKernels === null ? [''] : + this.subKernels.map(fn); + } + destroy(removeCanvasReference) { + if (removeCanvasReference) { + delete this.canvas; + } + } + static destroyContext(context) {} + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON(); + return json; + } + setOutput(output) { + super.setOutput(output); + const [width, height] = this.output; + if (this.graphical) { + this._imageData = this.context.createImageData(width, height); + this._colorData = new Uint8ClampedArray(width * height * 4); + } } - - throw new Error(`unhandled return type "${this.returnType}"`); - } - - getKernelString() { - throw new Error(`abstract method call`); } - getMainResultTexture() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Integer': - case 'Number': - return this.getMainResultNumberTexture(); - case 'Array(2)': - return this.getMainResultArray2Texture(); - case 'Array(3)': - return this.getMainResultArray3Texture(); - case 'Array(4)': - return this.getMainResultArray4Texture(); - default: - throw new Error(`unhandled returnType type ${ this.returnType }`); + class GLTextureFloat extends Texture { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Float32Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); + return result; + } + renderValues() { + return this.renderRawOutput(); + } + toArray() { + return utils$1.erectFloat(this.renderValues(), this.output[0]); } } - getMainResultKernelNumberTexture() { - throw new Error(`abstract method call`); - } - getMainResultSubKernelNumberTexture() { - throw new Error(`abstract method call`); - } - getMainResultKernelArray2Texture() { - throw new Error(`abstract method call`); - } - getMainResultSubKernelArray2Texture() { - throw new Error(`abstract method call`); - } - getMainResultKernelArray3Texture() { - throw new Error(`abstract method call`); - } - getMainResultSubKernelArray3Texture() { - throw new Error(`abstract method call`); - } - getMainResultKernelArray4Texture() { - throw new Error(`abstract method call`); - } - getMainResultSubKernelArray4Texture() { - throw new Error(`abstract method call`); - } - getMainResultGraphical() { - throw new Error(`abstract method call`); - } - getMainResultMemoryOptimizedFloats() { - throw new Error(`abstract method call`); - } - getMainResultPackedPixels() { - throw new Error(`abstract method call`); + class GLTextureArray2Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erectArray2(this.renderValues(), this.output[0], this.output[1]); + } } - getMainResultString() { - if (this.graphical) { - return this.getMainResultGraphical(); - } else if (this.precision === 'single') { - if (this.optimizeFloatMemory) { - return this.getMainResultMemoryOptimizedFloats(); - } - return this.getMainResultTexture(); - } else { - return this.getMainResultPackedPixels(); + class GLTextureArray2Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); } } - getMainResultNumberTexture() { - return utils.linesToString(this.getMainResultKernelNumberTexture()) + - utils.linesToString(this.getMainResultSubKernelNumberTexture()); + class GLTextureArray2Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - getMainResultArray2Texture() { - return utils.linesToString(this.getMainResultKernelArray2Texture()) + - utils.linesToString(this.getMainResultSubKernelArray2Texture()); + class GLTextureArray3Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erectArray3(this.renderValues(), this.output[0]); + } } - getMainResultArray3Texture() { - return utils.linesToString(this.getMainResultKernelArray3Texture()) + - utils.linesToString(this.getMainResultSubKernelArray3Texture()); + class GLTextureArray3Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); + } } - getMainResultArray4Texture() { - return utils.linesToString(this.getMainResultKernelArray4Texture()) + - utils.linesToString(this.getMainResultSubKernelArray4Texture()); + class GLTextureArray3Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - getFloatTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp float;\n'; - case 'performance': - return 'precision highp float;\n'; - case 'balanced': - default: - return 'precision mediump float;\n'; + class GLTextureArray4Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erectArray4(this.renderValues(), this.output[0]); } } - getIntTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp int;\n'; - case 'performance': - return 'precision highp int;\n'; - case 'balanced': - default: - return 'precision mediump int;\n'; + class GLTextureArray4Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); } } - getSampler2DTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2D;\n'; - case 'performance': - return 'precision highp sampler2D;\n'; - case 'balanced': - default: - return 'precision mediump sampler2D;\n'; + class GLTextureArray4Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); } } - getSampler2DArrayTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2DArray;\n'; - case 'performance': - return 'precision highp sampler2DArray;\n'; - case 'balanced': - default: - return 'precision mediump sampler2DArray;\n'; + class GLTextureFloat2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils$1.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); } } - renderTexture() { - return new this.TextureConstructor({ - texture: this.outputTexture, - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - readPackedPixelsToUint8Array() { - if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"'); - const { - texSize, - context: gl - } = this; - const result = new Uint8Array(texSize[0] * texSize[1] * 4); - gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result); - return result; + class GLTextureFloat3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils$1.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - readPackedPixelsToFloat32Array() { - return new Float32Array(this.readPackedPixelsToUint8Array().buffer); + class GLTextureMemoryOptimized extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); + } } - readFloatPixelsToFloat32Array() { - if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); - const { - texSize, - context: gl - } = this; - const w = texSize[0]; - const h = texSize[1]; - const result = new Float32Array(w * h * 4); - gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); - return result; + class GLTextureMemoryOptimized2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); + } } - readMemoryOptimizedFloatPixelsToFloat32Array() { - if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); - const { - texSize, - context: gl - } = this; - const w = texSize[0]; - const h = texSize[1]; - const result = new Float32Array(w * h * 4); - gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); - return result; + class GLTextureMemoryOptimized3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - getPixels(flip) { - const { - context: gl, - output - } = this; - const [width, height] = output; - const pixels = new Uint8Array(width * height * 4); - gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer); + class GLTextureUnsigned extends Texture { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Uint8Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result); + return result; + } + renderValues() { + return new Float32Array(this.renderRawOutput().buffer); + } + toArray() { + return utils$1.erectPackedFloat(this.renderValues(), this.output[0]); + } } - renderKernelsToArrays() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }).toArray(); + class GLTextureUnsigned2D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils$1.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); } - return result; } - renderKernelsToTextures() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); + class GLTextureUnsigned3D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils$1.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); } - return result; } - setOutput(output) { - super.setOutput(output); - if (this.program) { - this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - const { context: gl } = this; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - this.updateMaxTexSize(); - this.framebuffer.width = this.texSize[0]; - this.framebuffer.height = this.texSize[1]; - this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - this.canvas.width = this.maxTexSize[0]; - this.canvas.height = this.maxTexSize[1]; - this._setupOutputTexture(); - if (this.subKernels && this.subKernels.length > 0) { - this._setupSubOutputTextures(); - } + class GLTextureGraphical extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return this.renderValues(); } - return this; - } - renderValues() { - return this.formatValues( - this.transferValues(), - this.output[0], - this.output[1], - this.output[2] - ); } -} - -const renderStrategy = Object.freeze({ - PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), - PackedPixelToFloat: Symbol('PackedPixelToFloat'), - PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), - PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), - PackedTexture: Symbol('PackedTexture'), - FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), - FloatPixelToFloat: Symbol('FloatPixelToFloat'), - FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), - FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), - FloatPixelToArray2: Symbol('FloatPixelToArray2'), - FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), - FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), - FloatPixelToArray3: Symbol('FloatPixelToArray3'), - FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), - FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), - FloatPixelToArray4: Symbol('FloatPixelToArray4'), - FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), - FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), - FloatTexture: Symbol('FloatTexture'), - MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), -}); - -const typeMap = { - int: 'Integer', - float: 'Number', - vec2: 'Array(2)', - vec3: 'Array(3)', - vec4: 'Array(4)', -}; -module.exports = { - GLKernel, - renderStrategy -}; -},{"../../texture":110,"../../utils":111,"../kernel":34,"./texture/array-2-float":15,"./texture/array-2-float-2d":13,"./texture/array-2-float-3d":14,"./texture/array-3-float":18,"./texture/array-3-float-2d":16,"./texture/array-3-float-3d":17,"./texture/array-4-float":21,"./texture/array-4-float-2d":19,"./texture/array-4-float-3d":20,"./texture/float":24,"./texture/float-2d":22,"./texture/float-3d":23,"./texture/graphical":25,"./texture/memory-optimized":28,"./texture/memory-optimized-2d":26,"./texture/memory-optimized-3d":27,"./texture/unsigned":31,"./texture/unsigned-2d":29,"./texture/unsigned-3d":30}],13:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray2Float2D -}; -},{"../../../utils":111,"./float":24}],14:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray2Float3D -}; -},{"../../../utils":111,"./float":24}],15:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray2Float -}; -},{"../../../utils":111,"./float":24}],16:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray3Float2D -}; -},{"../../../utils":111,"./float":24}],17:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray3Float3D -}; -},{"../../../utils":111,"./float":24}],18:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erectArray3(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureArray3Float -}; -},{"../../../utils":111,"./float":24}],19:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray4Float2D -}; -},{"../../../utils":111,"./float":24}],20:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray4Float3D -}; -},{"../../../utils":111,"./float":24}],21:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erectArray4(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureArray4Float -}; -},{"../../../utils":111,"./float":24}],22:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureFloat2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - toArray() { - return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureFloat2D -}; -},{"../../../utils":111,"./float":24}],23:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureFloat3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - toArray() { - return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureFloat3D -}; -},{"../../../utils":111,"./float":24}],24:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureFloat extends Texture { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Float32Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); - return result; - } - renderValues() { - return this.renderRawOutput(); - } - toArray() { - return utils.erectFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureFloat -}; -},{"../../../texture":110,"../../../utils":111}],25:[function(require,module,exports){ -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureGraphical extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return this.renderValues(); - } -} - -module.exports = { - GLTextureGraphical -}; -},{"./unsigned":31}],26:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureMemoryOptimized2D -}; -},{"../../../utils":111,"./float":24}],27:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureMemoryOptimized3D -}; -},{"../../../utils":111,"./float":24}],28:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureMemoryOptimized -}; -},{"../../../utils":111,"./float":24}],29:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureUnsigned2D extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - toArray() { - return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureUnsigned2D -}; -},{"../../../utils":111,"./unsigned":31}],30:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureUnsigned3D extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - toArray() { - return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureUnsigned3D -}; -},{"../../../utils":111,"./unsigned":31}],31:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureUnsigned extends Texture { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Uint8Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result); - return result; - } - renderValues() { - return new Float32Array(this.renderRawOutput().buffer); - } - toArray() { - return utils.erectPackedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureUnsigned -}; -},{"../../../texture":110,"../../../utils":111}],32:[function(require,module,exports){ -const getContext = require('gl'); -const { WebGLKernel } = require('../web-gl/kernel'); -const { glKernelString } = require('../gl/kernel-string'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; -let features = null; - -class HeadlessGLKernel extends WebGLKernel { - static get isSupported() { - if (isSupported !== null) return isSupported; - this.setupFeatureChecks(); - isSupported = testContext !== null; - return isSupported; - } - - static setupFeatureChecks() { - testCanvas = null; - testExtensions = null; - if (typeof getContext !== 'function') return; - try { - testContext = getContext(2, 2, { - preserveDrawingBuffer: true - }); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - STACKGL_resize_drawingbuffer: testContext.getExtension('STACKGL_resize_drawingbuffer'), - STACKGL_destroy_context: testContext.getExtension('STACKGL_destroy_context'), - OES_texture_float: testContext.getExtension('OES_texture_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), - }; - features = this.getFeatures(); - } catch (e) { - console.warn(e); - } - } - - static isContextMatch(context) { - try { - return context.getParameter(context.RENDERER) === 'ANGLE'; - } catch (e) { - return false; - } - } - - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - static getIsTextureFloat() { - return Boolean(testExtensions.OES_texture_float); - } - - static getIsDrawBuffers() { - return Boolean(testExtensions.WEBGL_draw_buffers); - } - - static getChannelCount() { - return testExtensions.WEBGL_draw_buffers ? - testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : - 1; - } - - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); - } - - static get testCanvas() { - return testCanvas; - } - - static get testContext() { - return testContext; - } - - static get features() { - return features; - } - - initCanvas() { - return {}; - } - - initContext() { - const context = getContext(2, 2, { - preserveDrawingBuffer: true - }); - return context; - } - - initExtensions() { - this.extensions = { - STACKGL_resize_drawingbuffer: this.context.getExtension('STACKGL_resize_drawingbuffer'), - STACKGL_destroy_context: this.context.getExtension('STACKGL_destroy_context'), - OES_texture_float: this.context.getExtension('OES_texture_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), - }; - } - - build() { - super.build.apply(this, arguments); - if (!this.fallbackRequested) { - this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); - } - } - - destroyExtensions() { - this.extensions.STACKGL_resize_drawingbuffer = null; - this.extensions.STACKGL_destroy_context = null; - this.extensions.OES_texture_float = null; - this.extensions.OES_texture_float_linear = null; - this.extensions.OES_element_index_uint = null; - this.extensions.WEBGL_draw_buffers = null; - } - - static destroyContext(context) { - const extension = context.getExtension('STACKGL_destroy_context'); - if (extension && extension.destroy) { - extension.destroy(); - } - } - - toString() { - const setupContextString = `const gl = context || require('gl')(1, 1);\n`; - const destroyContextString = ` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n`; - return glKernelString(this.constructor, arguments, this, setupContextString, destroyContextString); - } - - setOutput(output) { - super.setOutput(output); - if (this.graphical && this.extensions.STACKGL_resize_drawingbuffer) { - this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); - } - } -} - -module.exports = { - HeadlessGLKernel -}; -},{"../gl/kernel-string":11,"../web-gl/kernel":67,"gl":1}],33:[function(require,module,exports){ -class KernelValue { - constructor(value, settings) { - const { - name, - kernel, - context, - checkContext, - onRequestContextHandle, - onUpdateValueMismatch, - origin, - strictIntegers, - type, - tactic, - } = settings; - if (!name) { - throw new Error('name not set'); - } - if (!type) { - throw new Error('type not set'); - } - if (!origin) { - throw new Error('origin not set'); - } - if (!tactic) { - throw new Error('tactic not set'); - } - if (origin !== 'user' && origin !== 'constants') { - throw new Error(`origin must be "user" or "constants" value is "${ origin }"`); - } - if (!onRequestContextHandle) { - throw new Error('onRequestContextHandle is not set'); - } - this.name = name; - this.origin = origin; - this.tactic = tactic; - this.id = `${this.origin}_${name}`; - this.varName = origin === 'constants' ? `constants.${name}` : name; - this.kernel = kernel; - this.strictIntegers = strictIntegers; - this.type = value.type || type; - this.size = value.size || null; - this.index = null; - this.context = context; - this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true; - this.contextHandle = null; - this.onRequestContextHandle = onRequestContextHandle; - this.onUpdateValueMismatch = onUpdateValueMismatch; - this.forceUploadEachRun = null; - } - - getSource() { - throw new Error(`"getSource" not defined on ${ this.constructor.name }`); - } - - updateValue(value) { - throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); - } -} - -module.exports = { - KernelValue -}; -},{}],34:[function(require,module,exports){ -const { utils } = require('../utils'); -const { Input } = require('../input'); - -class Kernel { - static get isSupported() { - throw new Error(`"isSupported" not implemented on ${ this.name }`); - } - - static isContextMatch(context) { - throw new Error(`"isContextMatch" not implemented on ${ this.name }`); - } - - static getFeatures() { - throw new Error(`"getFeatures" not implemented on ${ this.name }`); - } - - static destroyContext(context) { - throw new Error(`"destroyContext" called on ${ this.name }`); - } - - static nativeFunctionArguments() { - throw new Error(`"nativeFunctionArguments" called on ${ this.name }`); - } - - static nativeFunctionReturnType() { - throw new Error(`"nativeFunctionReturnType" called on ${ this.name }`); - } - - static combineKernels() { - throw new Error(`"combineKernels" called on ${ this.name }`); - } - - constructor(source, settings) { - if (typeof source !== 'object') { - if (typeof source !== 'string') { - throw new Error('source not a string'); - } - if (!utils.isFunctionString(source)) { - throw new Error('source not a function string'); - } + class GLKernel extends Kernel { + static get mode() { + return 'gpu'; } - this.useLegacyEncoder = false; - this.fallbackRequested = false; - this.onRequestFallback = null; - - this.argumentNames = typeof source === 'string' ? utils.getArgumentNamesFromString(source) : null; - this.argumentTypes = null; - this.argumentSizes = null; - this.argumentBitRatios = null; - this.kernelArguments = null; - this.kernelConstants = null; - this.forceUploadKernelConstants = null; - - - this.source = source; - - this.output = null; - - this.debug = false; - - this.graphical = false; - - this.loopMaxIterations = 0; - - this.constants = null; - this.constantTypes = null; - this.constantBitRatios = null; - this.dynamicArguments = false; - this.dynamicOutput = false; - - this.canvas = null; - - this.context = null; - - this.checkContext = null; - - this.gpu = null; - - this.functions = null; - - this.nativeFunctions = null; - - this.injectedNative = null; - - this.subKernels = null; - - this.validate = true; - - this.immutable = false; - - this.pipeline = false; - - this.precision = null; - - this.tactic = 'balanced'; - - this.plugins = null; - - this.returnType = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.optimizeFloatMemory = null; - this.strictIntegers = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - } - - mergeSettings(settings) { - for (let p in settings) { - if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue; - switch (p) { - case 'output': - if (!Array.isArray(settings.output)) { - this.setOutput(settings.output); - continue; + static getIsFloatRead() { + const kernelString = `function kernelFunction() { + return 1; + }`; + const kernel = new this(kernelString, { + context: this.testContext, + canvas: this.testCanvas, + validate: false, + output: [1], + precision: 'single', + returnType: 'Number', + tactic: 'speed', + }); + kernel.build(); + kernel.run(); + const result = kernel.renderOutput(); + kernel.destroy(true); + return result[0] === 1; + } + static getIsIntegerDivisionAccurate() { + function kernelFunction(v1, v2) { + return v1[this.thread.x] / v2[this.thread.x]; + } + const kernel = new this(kernelFunction.toString(), { + context: this.testContext, + canvas: this.testCanvas, + validate: false, + output: [2], + returnType: 'Number', + precision: 'unsigned', + tactic: 'speed', + }); + const args = [ + [6, 6030401], + [3, 3991] + ]; + kernel.build.apply(kernel, args); + kernel.run.apply(kernel, args); + const result = kernel.renderOutput(); + kernel.destroy(true); + return result[0] === 2 && result[1] === 1511; + } + static get testCanvas() { + throw new Error(`"testCanvas" not defined on ${ this.name }`); + } + static get testContext() { + throw new Error(`"testContext" not defined on ${ this.name }`); + } + static get features() { + throw new Error(`"features" not defined on ${ this.name }`); + } + static setupFeatureChecks() { + throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); + } + setFixIntegerDivisionAccuracy(fix) { + this.fixIntegerDivisionAccuracy = fix; + return this; + } + setPrecision(flag) { + this.precision = flag; + return this; + } + setFloatTextures(flag) { + utils$1.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory'); + this.floatTextures = flag; + return this; + } + static nativeFunctionArguments(source) { + const argumentTypes = []; + const argumentNames = []; + const states = []; + const isStartingVariableName = /^[a-zA-Z_]/; + const isVariableChar = /[a-zA-Z_0-9]/; + let i = 0; + let argumentName = null; + let argumentType = null; + while (i < source.length) { + const char = source[i]; + const nextChar = source[i + 1]; + const state = states.length > 0 ? states[states.length - 1] : null; + if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') { + states.push('MULTI_LINE_COMMENT'); + i += 2; + continue; + } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') { + states.pop(); + i += 2; + continue; + } + else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') { + states.push('COMMENT'); + i += 2; + continue; + } else if (state === 'COMMENT' && char === '\n') { + states.pop(); + i++; + continue; + } + else if (state === null && char === '(') { + states.push('FUNCTION_ARGUMENTS'); + i++; + continue; + } else if (state === 'FUNCTION_ARGUMENTS') { + if (char === ')') { + states.pop(); + break; } - break; - case 'functions': - if (typeof settings.functions[0] === 'function') { - this.functions = settings.functions.map(source => utils.functionToIFunction(source)); + if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'float'; + argumentName = ''; + i += 6; + continue; + } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'int'; + argumentName = ''; + i += 4; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec2'; + argumentName = ''; + i += 5; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec3'; + argumentName = ''; + i += 5; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec4'; + argumentName = ''; + i += 5; continue; } - break; - case 'graphical': - if (settings[p] && !settings.hasOwnProperty('precision')) { - this.precision = 'unsigned'; + } + else if (state === 'DECLARE_VARIABLE') { + if (argumentName === '') { + if (char === ' ') { + i++; + continue; + } + if (!isStartingVariableName.test(char)) { + throw new Error('variable name is not expected string'); + } } - this[p] = settings[p]; - continue; + argumentName += char; + if (!isVariableChar.test(nextChar)) { + states.pop(); + argumentNames.push(argumentName); + argumentTypes.push(typeMap$1[argumentType]); + } + } + i++; + } + if (states.length > 0) { + throw new Error('GLSL function was not parsable'); } - this[p] = settings[p]; + return { + argumentNames, + argumentTypes, + }; } - - if (!this.canvas) this.canvas = this.initCanvas(); - if (!this.context) this.context = this.initContext(); - if (!this.plugins) this.plugins = this.initPlugins(settings); - } - build() { - throw new Error(`"build" not defined on ${ this.constructor.name }`); - } - - run() { - throw new Error(`"run" not defined on ${ this.constructor.name }`) - } - - initCanvas() { - throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`); - } - - initContext() { - throw new Error(`"initContext" not defined on ${ this.constructor.name }`); - } - - initPlugins(settings) { - throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`); - } - - setupArguments(args) { - this.kernelArguments = []; - if (!this.argumentTypes) { - if (!this.argumentTypes) { - this.argumentTypes = []; - for (let i = 0; i < args.length; i++) { - const argType = utils.getVariableType(args[i], this.strictIntegers); - const type = argType === 'Integer' ? 'Number' : argType; - this.argumentTypes.push(type); - this.kernelArguments.push({ - type - }); - } + static nativeFunctionReturnType(source) { + return typeMap$1[source.match(/int|float|vec[2-4]/)[0]]; + } + static combineKernels(combinedKernel, lastKernel) { + combinedKernel.apply(null, arguments); + const { + texSize, + context, + threadDim + } = lastKernel.texSize; + let result; + if (lastKernel.precision === 'single') { + const w = texSize[0]; + const h = Math.ceil(texSize[1] / 4); + result = new Float32Array(w * h * 4 * 4); + context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result); + } else { + const bytes = new Uint8Array(texSize[0] * texSize[1] * 4); + context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes); + result = new Float32Array(bytes.buffer); } - } else { - for (let i = 0; i < this.argumentTypes.length; i++) { - this.kernelArguments.push({ - type: this.argumentTypes[i] + result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]); + if (lastKernel.output.length === 1) { + return result; + } else if (lastKernel.output.length === 2) { + return utils$1.splitArray(result, lastKernel.output[0]); + } else if (lastKernel.output.length === 3) { + const cube = utils$1.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); + return cube.map(function(x) { + return utils$1.splitArray(x, lastKernel.output[0]); }); } } - - this.argumentSizes = new Array(args.length); - this.argumentBitRatios = new Int32Array(args.length); - - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - this.argumentSizes[i] = arg.constructor === Input ? arg.size : null; - this.argumentBitRatios[i] = this.getBitRatio(arg); - } - - if (this.argumentNames.length !== args.length) { - throw new Error(`arguments are miss-aligned`); - } - } - - setupConstants() { - this.kernelConstants = []; - let needsConstantTypes = this.constantTypes === null; - if (needsConstantTypes) { - this.constantTypes = {}; - } - this.constantBitRatios = {}; - if (this.constants) { - for (let name in this.constants) { - if (needsConstantTypes) { - const type = utils.getVariableType(this.constants[name], this.strictIntegers); - this.constantTypes[name] = type; - this.kernelConstants.push({ - name, - type - }); + constructor(source, settings) { + super(source, settings); + this.transferValues = null; + this.formatValues = null; + this.TextureConstructor = null; + this.renderOutput = null; + this.renderRawOutput = null; + this.texSize = null; + this.translatedSource = null; + this.renderStrategy = null; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + } + checkTextureSize() { + const { features } = this.constructor; + if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) { + throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`); + } + } + translateSource() { + throw new Error(`"translateSource" not defined on ${this.constructor.name}`); + } + pickRenderStrategy(args) { + if (this.graphical) { + this.renderRawOutput = this.readPackedPixelsToUint8Array; + this.transferValues = (pixels) => pixels; + this.TextureConstructor = GLTextureGraphical; + return null; + } + if (this.precision === 'unsigned') { + this.renderRawOutput = this.readPackedPixelsToUint8Array; + this.transferValues = this.readPackedPixelsToFloat32Array; + if (this.pipeline) { + this.renderOutput = this.renderTexture; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToTextures; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureUnsigned3D; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + return null; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); + } } else { - this.kernelConstants.push({ - name, - type: this.constantTypes[name] - }); + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToArrays; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + this.renderOutput = this.renderValues; + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureUnsigned3D; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + this.formatValues = utils$1.erect3DPackedFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + this.formatValues = utils$1.erect2DPackedFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + this.formatValues = utils$1.erectPackedFloat; + return null; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); + } } - this.constantBitRatios[name] = this.getBitRatio(this.constants[name]); - } - } - } - - setOptimizeFloatMemory(flag) { - this.optimizeFloatMemory = flag; - return this; - } - - setOutput(output) { - if (output.hasOwnProperty('x')) { - if (output.hasOwnProperty('y')) { - if (output.hasOwnProperty('z')) { - this.output = [output.x, output.y, output.z]; + } else if (this.precision === 'single') { + this.renderRawOutput = this.readFloatPixelsToFloat32Array; + this.transferValues = this.readFloatPixelsToFloat32Array; + if (this.pipeline) { + this.renderStrategy = renderStrategy.FloatTexture; + this.renderOutput = this.renderTexture; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToTextures; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.optimizeFloatMemory) { + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + return null; + } + } else { + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureFloat3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + return null; + } + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + return null; + } + } + } + this.renderOutput = this.renderValues; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToArrays; + } + if (this.optimizeFloatMemory) { + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized3D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; + this.formatValues = utils$1.erectMemoryOptimized3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; + this.formatValues = utils$1.erectMemoryOptimized2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; + this.formatValues = utils$1.erectMemoryOptimizedFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils$1.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils$1.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils$1.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils$1.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils$1.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils$1.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils$1.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils$1.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils$1.erectArray4; + return null; + } + } } else { - this.output = [output.x, output.y]; + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureFloat3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; + this.formatValues = utils$1.erect3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; + this.formatValues = utils$1.erect2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + this.renderStrategy = renderStrategy.FloatPixelToFloat; + this.formatValues = utils$1.erectFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils$1.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils$1.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils$1.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils$1.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils$1.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils$1.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils$1.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils$1.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils$1.erectArray4; + return null; + } + } } } else { - this.output = [output.x]; + throw new Error(`unhandled precision of "${this.precision}"`); } - } else { - this.output = output; + throw new Error(`unhandled return type "${this.returnType}"`); } - return this; - } - - setDebug(flag) { - this.debug = flag; - return this; - } - - setGraphical(flag) { - this.graphical = flag; - this.precision = 'unsigned'; - return this; - } - - setLoopMaxIterations(max) { - this.loopMaxIterations = max; - return this; - } - - setConstants(constants) { - this.constants = constants; - return this; - } - - setConstantTypes(constantTypes) { - this.constantTypes = constantTypes; - return this; - } - - setFunctions(functions) { - if (typeof functions[0] === 'function') { - this.functions = functions.map(source => utils.functionToIFunction(source)); - } else { - this.functions = functions; + getKernelString() { + throw new Error(`abstract method call`); } - return this; - } - - setNativeFunctions(nativeFunctions) { - this.nativeFunctions = nativeFunctions; - return this; - } - - setInjectedNative(injectedNative) { - this.injectedNative = injectedNative; - return this; - } - - setPipeline(flag) { - this.pipeline = flag; - return this; - } - - setPrecision(flag) { - this.precision = flag; - return this; - } - - setOutputToTexture(flag) { - utils.warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); - this.pipeline = flag; - return this; - } - - setImmutable(flag) { - this.immutable = flag; - return this; - } - - setCanvas(canvas) { - this.canvas = canvas; - return this; - } - - setStrictIntegers(flag) { - this.strictIntegers = flag; - return this; - } - - setDynamicOutput(flag) { - this.dynamicOutput = flag; - return this; - } - - setHardcodeConstants(flag) { - utils.warnDeprecated('method', 'setHardcodeConstants'); - this.setDynamicOutput(flag); - this.setDynamicArguments(flag); - return this; - } - - setDynamicArguments(flag) { - this.dynamicArguments = flag; - return this; - } - - setUseLegacyEncoder(flag) { - this.useLegacyEncoder = flag; - return this; - } - - setWarnVarUsage(flag) { - this.warnVarUsage = flag; - return this; - } - - getCanvas() { - utils.warnDeprecated('method', 'getCanvas'); - return this.canvas; - } - - getWebGl() { - utils.warnDeprecated('method', 'getWebGl'); - return this.context; - } - - setContext(context) { - this.context = context; - return this; - } - - setArgumentTypes(argumentTypes) { - if (Array.isArray(argumentTypes)) { - this.argumentTypes = argumentTypes; - } else { - this.argumentTypes = []; - for (const p in argumentTypes) { - const argumentIndex = this.argumentNames.indexOf(p); - if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); - this.argumentTypes[argumentIndex] = argumentTypes[p]; + getMainResultTexture() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Integer': + case 'Number': + return this.getMainResultNumberTexture(); + case 'Array(2)': + return this.getMainResultArray2Texture(); + case 'Array(3)': + return this.getMainResultArray3Texture(); + case 'Array(4)': + return this.getMainResultArray4Texture(); + default: + throw new Error(`unhandled returnType type ${ this.returnType }`); } } - return this; - } - - setTactic(tactic) { - this.tactic = tactic; - return this; - } - - requestFallback(args) { - if (!this.onRequestFallback) { - throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); + getMainResultKernelNumberTexture() { + throw new Error(`abstract method call`); } - this.fallbackRequested = true; - return this.onRequestFallback(args); - } - - validateSettings() { - throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`); - } - - addSubKernel(subKernel) { - if (this.subKernels === null) { - this.subKernels = []; - } - if (!subKernel.source) throw new Error('subKernel missing "source" property'); - if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property'); - if (!subKernel.name) throw new Error('subKernel missing "name" property'); - this.subKernels.push(subKernel); - return this; - } - - destroy(removeCanvasReferences) { - throw new Error(`"destroy" called on ${ this.constructor.name }`); - } - - getBitRatio(value) { - if (this.precision === 'single') { - return 4; - } else if (Array.isArray(value[0])) { - return this.getBitRatio(value[0]); - } else if (value.constructor === Input) { - return this.getBitRatio(value.value); + getMainResultSubKernelNumberTexture() { + throw new Error(`abstract method call`); } - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - return 1; - case Uint16Array: - case Int16Array: - return 2; - case Float32Array: - case Int32Array: - default: - return 4; - } - } - - getPixels() { - throw new Error(`"getPixels" called on ${ this.constructor.name }`); - } - - checkOutput() { - if (!this.output || !utils.isArray(this.output)) throw new Error('kernel.output not an array'); - if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value'); - for (let i = 0; i < this.output.length; i++) { - if (isNaN(this.output[i]) || this.output[i] < 1) { - throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`); - } + getMainResultKernelArray2Texture() { + throw new Error(`abstract method call`); } - } - - toJSON() { - const settings = { - output: this.output, - threadDim: this.threadDim, - pipeline: this.pipeline, - argumentNames: this.argumentNames, - argumentsTypes: this.argumentTypes, - constants: this.constants, - pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null, - returnType: this.returnType, - }; - return { - settings - }; - } -} - -module.exports = { - Kernel -}; -},{"../input":107,"../utils":111}],35:[function(require,module,exports){ -const fragmentShader = `__HEADER__; -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -const int LOOP_MAX = __LOOP_MAX__; - -__PLUGINS__; -__CONSTANTS__; - -varying vec2 vTexCoord; - -vec4 round(vec4 x) { - return floor(x + 0.5); -} - -float round(float x) { - return floor(x + 0.5); -} - -const int BIT_COUNT = 32; -int modi(int x, int y) { - return x - y * (x / y); -} - -int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; + getMainResultSubKernelArray2Texture() { + throw new Error(`abstract method call`); } - } - return result; -} -int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; + getMainResultKernelArray3Texture() { + throw new Error(`abstract method call`); } - } - return result; -} -int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; + getMainResultSubKernelArray3Texture() { + throw new Error(`abstract method call`); } - } - return result; -} -int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; -} -int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; + getMainResultKernelArray4Texture() { + throw new Error(`abstract method call`); } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); -} - -int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; + getMainResultSubKernelArray4Texture() { + throw new Error(`abstract method call`); } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; + getMainResultGraphical() { + throw new Error(`abstract method call`); } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); -} - -int integerMod(int x, int y) { - return x - (y * int(x / y)); -} - -__DIVIDE_WITH_INTEGER_CHECK__; - -// Here be dragons! -// DO NOT OPTIMIZE THIS CODE -// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE -// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME -const vec2 MAGIC_VEC = vec2(1.0, -256.0); -const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); -const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 -float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; -} - -float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; - if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; - return 0.0; -} - -float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - if (channel == 0) return texel.r * 255.0; - if (channel == 1) return texel.g * 255.0; - if (channel == 2) return texel.b * 255.0; - if (channel == 3) return texel.a * 255.0; - return 0.0; -} - -vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; -} - -// https://github.com/gpujs/gpu.js/wiki/Encoder-details -vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; -} -// Dragons end here - -int index; -ivec3 threadId; - -ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); -} - -float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return decode32(texel); -} - -float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); -} - -float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); -} - -float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return texel.r; - if (channel == 1) return texel.g; - if (channel == 2) return texel.b; - if (channel == 3) return texel.a; - return 0.0; -} - -vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture2D(tex, st / vec2(texSize)); -} - -float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; -} - -vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); -} - -vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); -} - -vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); -} - -vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); + getMainResultMemoryOptimizedFloats() { + throw new Error(`abstract method call`); } - } -} - -vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); -} - -vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); -} - -vec4 actualColor; -void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); -} - -void color(float r, float g, float b) { - color(r,g,b,1.0); -} - -void color(sampler2D image) { - actualColor = texture2D(image, vTexCoord); -} - -__INJECTED_NATIVE__; -__MAIN_CONSTANTS__; -__MAIN_ARGUMENTS__; -__KERNEL__; - -void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; -}`; - -module.exports = { - fragmentShader -}; -},{}],36:[function(require,module,exports){ -const { utils } = require('../../utils'); -const { FunctionNode } = require('../function-node'); -const jsMathPrefix = 'Math.'; -const localPrefix = 'this.'; - -class WebGLFunctionNode extends FunctionNode { - constructor(source, settings) { - super(source, settings); - if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { - this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; + getMainResultPackedPixels() { + throw new Error(`abstract method call`); } - } - - astFunction(ast, retArr) { - if (this.isRootKernel) { - retArr.push('void'); - } else { - let lastReturn = null; - if (!this.returnType) { - const lastReturn = this.findLastReturn(); - if (lastReturn) { - this.returnType = this.getType(ast.body); - if (this.returnType === 'LiteralInteger') { - this.returnType = 'Number'; - } + getMainResultString() { + if (this.graphical) { + return this.getMainResultGraphical(); + } else if (this.precision === 'single') { + if (this.optimizeFloatMemory) { + return this.getMainResultMemoryOptimizedFloats(); } - } - - const { returnType } = this; - if (!returnType) { - retArr.push('void'); + return this.getMainResultTexture(); } else { - const type = typeMap[returnType]; - if (!type) { - throw new Error(`unknown type ${returnType}`); - } - retArr.push(type); + return this.getMainResultPackedPixels(); } } - retArr.push(' '); - retArr.push(this.name); - retArr.push('('); - - if (!this.isRootKernel) { - for (let i = 0; i < this.argumentNames.length; ++i) { - const argumentName = this.argumentNames[i]; - - if (i > 0) { - retArr.push(', '); - } - let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; - if (!argumentType) { - throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast); - } - if (argumentType === 'LiteralInteger') { - this.argumentTypes[i] = argumentType = 'Number'; - } - const type = typeMap[argumentType]; - if (!type) { - throw this.astErrorOutput('Unexpected expression', ast); - } - - if (type === 'sampler2D' || type === 'sampler2DArray') { - retArr.push(`${type} user_${argumentName},ivec2 user_${argumentName}Size,ivec3 user_${argumentName}Dim`); - } else { - retArr.push(`${type} user_${argumentName}`); - } + getMainResultNumberTexture() { + return utils$1.linesToString(this.getMainResultKernelNumberTexture()) + + utils$1.linesToString(this.getMainResultSubKernelNumberTexture()); + } + getMainResultArray2Texture() { + return utils$1.linesToString(this.getMainResultKernelArray2Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray2Texture()); + } + getMainResultArray3Texture() { + return utils$1.linesToString(this.getMainResultKernelArray3Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray3Texture()); + } + getMainResultArray4Texture() { + return utils$1.linesToString(this.getMainResultKernelArray4Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray4Texture()); + } + getFloatTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp float;\n'; + case 'performance': + return 'precision highp float;\n'; + case 'balanced': + default: + return 'precision mediump float;\n'; } } - - retArr.push(') {\n'); - - for (let i = 0; i < ast.body.body.length; ++i) { - this.astGeneric(ast.body.body[i], retArr); - retArr.push('\n'); + getIntTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp int;\n'; + case 'performance': + return 'precision highp int;\n'; + case 'balanced': + default: + return 'precision mediump int;\n'; + } } - - retArr.push('}\n'); - return retArr; - } - - astReturnStatement(ast, retArr) { - if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast); - this.pushState('skip-literal-correction'); - const type = this.getType(ast.argument); - this.popState('skip-literal-correction'); - - const result = []; - - if (!this.returnType) { - if (type === 'LiteralInteger' || type === 'Integer') { - this.returnType = 'Number'; - } else { - this.returnType = type; + getSampler2DTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2D;\n'; + case 'performance': + return 'precision highp sampler2D;\n'; + case 'balanced': + default: + return 'precision mediump sampler2D;\n'; } } - - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Float': - switch (type) { - case 'Integer': - result.push('float('); - this.astGeneric(ast.argument, result); - result.push(')'); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.argument, result); - - if (this.getType(ast) === 'Integer') { - result.unshift('float('); - result.push(')'); - } - break; - default: - this.astGeneric(ast.argument, result); - } - break; - case 'Integer': - switch (type) { - case 'Float': - case 'Number': - this.castValueToInteger(ast.argument, result); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.argument, result); - break; - default: - this.astGeneric(ast.argument, result); - } - break; - case 'Array(4)': - case 'Array(3)': - case 'Array(2)': - case 'Input': - this.astGeneric(ast.argument, result); - break; - default: - throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + getSampler2DArrayTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2DArray;\n'; + case 'performance': + return 'precision highp sampler2DArray;\n'; + case 'balanced': + default: + return 'precision mediump sampler2DArray;\n'; + } } - - if (this.isRootKernel) { - retArr.push(`kernelResult = ${ result.join('') };`); - retArr.push('return;'); - } else if (this.isSubKernel) { - retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`); - retArr.push(`return subKernelResult_${ this.name };`); - } else { - retArr.push(`return ${ result.join('') };`); + renderTexture() { + return new this.TextureConstructor({ + texture: this.outputTexture, + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); } - return retArr; - } - - astLiteral(ast, retArr) { - if (isNaN(ast.value)) { - throw this.astErrorOutput( - 'Non-numeric literal not supported : ' + ast.value, - ast - ); + readPackedPixelsToUint8Array() { + if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"'); + const { + texSize, + context: gl + } = this; + const result = new Uint8Array(texSize[0] * texSize[1] * 4); + gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result); + return result; } - - const key = `${ast.start},${ast.end}`; - if (Number.isInteger(ast.value)) { - if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) { - this.literalTypes[key] = 'Integer'; - retArr.push(`${ast.value}`); - } else if (this.isState('casting-to-float') || this.isState('building-float')) { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}.0`); - } else { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}.0`); + readPackedPixelsToFloat32Array() { + return new Float32Array(this.readPackedPixelsToUint8Array().buffer); + } + readFloatPixelsToFloat32Array() { + if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); + const { + texSize, + context: gl + } = this; + const w = texSize[0]; + const h = texSize[1]; + const result = new Float32Array(w * h * 4); + gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); + return result; + } + readMemoryOptimizedFloatPixelsToFloat32Array() { + if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); + const { + texSize, + context: gl + } = this; + const w = texSize[0]; + const h = texSize[1]; + const result = new Float32Array(w * h * 4); + gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); + return result; + } + getPixels(flip) { + const { + context: gl, + output + } = this; + const [width, height] = output; + const pixels = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + return new Uint8ClampedArray((flip ? pixels : utils$1.flipPixels(pixels, width, height)).buffer); + } + renderKernelsToArrays() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }).toArray(); } - } else if (this.isState('casting-to-integer') || this.isState('building-integer')) { - this.literalTypes[key] = 'Integer'; - retArr.push(Math.round(ast.value)); - } else { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}`); + return result; + } + renderKernelsToTextures() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + return result; + } + setOutput(output) { + super.setOutput(output); + if (this.program) { + this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + const { context: gl } = this; + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.updateMaxTexSize(); + this.framebuffer.width = this.texSize[0]; + this.framebuffer.height = this.texSize[1]; + this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + this.canvas.width = this.maxTexSize[0]; + this.canvas.height = this.maxTexSize[1]; + this._setupOutputTexture(); + if (this.subKernels && this.subKernels.length > 0) { + this._setupSubOutputTextures(); + } + } + return this; + } + renderValues() { + return this.formatValues( + this.transferValues(), + this.output[0], + this.output[1], + this.output[2] + ); } - return retArr; } + const renderStrategy = Object.freeze({ + PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), + PackedPixelToFloat: Symbol('PackedPixelToFloat'), + PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), + PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), + PackedTexture: Symbol('PackedTexture'), + FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), + FloatPixelToFloat: Symbol('FloatPixelToFloat'), + FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), + FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), + FloatPixelToArray2: Symbol('FloatPixelToArray2'), + FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), + FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), + FloatPixelToArray3: Symbol('FloatPixelToArray3'), + FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), + FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), + FloatPixelToArray4: Symbol('FloatPixelToArray4'), + FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), + FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), + FloatTexture: Symbol('FloatTexture'), + MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), + }); + const typeMap$1 = { + int: 'Integer', + float: 'Number', + vec2: 'Array(2)', + vec3: 'Array(3)', + vec4: 'Array(4)', + }; - astBinaryExpression(ast, retArr) { - if (this.checkAndUpconvertOperator(ast, retArr)) { - return retArr; + class WebGLFunctionNode extends FunctionNode { + constructor(source, settings) { + super(source, settings); + if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { + this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; + } } - - if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { - retArr.push('div_with_int_check('); - this.pushState('building-float'); - switch (this.getType(ast.left)) { - case 'Integer': - this.castValueToFloat(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.left, retArr); - break; - default: - this.astGeneric(ast.left, retArr); + astFunction(ast, retArr) { + if (this.isRootKernel) { + retArr.push('void'); + } else { + if (!this.returnType) { + const lastReturn = this.findLastReturn(); + if (lastReturn) { + this.returnType = this.getType(ast.body); + if (this.returnType === 'LiteralInteger') { + this.returnType = 'Number'; + } + } + } + const { returnType } = this; + if (!returnType) { + retArr.push('void'); + } else { + const type = typeMap$2[returnType]; + if (!type) { + throw new Error(`unknown type ${returnType}`); + } + retArr.push(type); + } } - retArr.push(', '); - switch (this.getType(ast.right)) { - case 'Integer': - this.castValueToFloat(ast.right, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.right, retArr); - break; - default: - this.astGeneric(ast.right, retArr); + retArr.push(' '); + retArr.push(this.name); + retArr.push('('); + if (!this.isRootKernel) { + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + if (i > 0) { + retArr.push(', '); + } + let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; + if (!argumentType) { + throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast); + } + if (argumentType === 'LiteralInteger') { + this.argumentTypes[i] = argumentType = 'Number'; + } + const type = typeMap$2[argumentType]; + if (!type) { + throw this.astErrorOutput('Unexpected expression', ast); + } + retArr.push(type); + retArr.push(' '); + retArr.push('user_'); + retArr.push(argumentName); + } } - this.popState('building-float'); - retArr.push(')'); + retArr.push(') {\n'); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); + } + retArr.push('}\n'); return retArr; } - - retArr.push('('); - const leftType = this.getType(ast.left) || 'Number'; - const rightType = this.getType(ast.right) || 'Number'; - if (!leftType || !rightType) { - throw this.astErrorOutput(`Unhandled binary expression`, ast); - } - const key = leftType + ' & ' + rightType; - switch (key) { - case 'Integer & Integer': - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-integer'); - break; - case 'Number & Float': - case 'Float & Number': - case 'Float & Float': - case 'Number & Number': + astReturnStatement(ast, retArr) { + if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast); + this.pushState('skip-literal-correction'); + const type = this.getType(ast.argument); + this.popState('skip-literal-correction'); + const result = []; + if (!this.returnType) { + if (type === 'LiteralInteger' || type === 'Integer') { + this.returnType = 'Number'; + } else { + this.returnType = type; + } + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Float': + switch (type) { + case 'Integer': + result.push('float('); + this.astGeneric(ast.argument, result); + result.push(')'); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.argument, result); + if (this.getType(ast) === 'Integer') { + result.unshift('float('); + result.push(')'); + } + break; + default: + this.astGeneric(ast.argument, result); + } + break; + case 'Integer': + switch (type) { + case 'Float': + case 'Number': + this.castValueToInteger(ast.argument, result); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, result); + break; + default: + this.astGeneric(ast.argument, result); + } + break; + case 'Array(4)': + case 'Array(3)': + case 'Array(2)': + case 'Input': + this.astGeneric(ast.argument, result); + break; + default: + throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + } + if (this.isRootKernel) { + retArr.push(`kernelResult = ${ result.join('') };`); + retArr.push('return;'); + } else if (this.isSubKernel) { + retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`); + retArr.push(`return subKernelResult_${ this.name };`); + } else { + retArr.push(`return ${ result.join('') };`); + } + return retArr; + } + astLiteral(ast, retArr) { + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + const key = `${ast.start},${ast.end}`; + if (Number.isInteger(ast.value)) { + if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) { + this.literalTypes[key] = 'Integer'; + retArr.push(`${ast.value}`); + } else if (this.isState('casting-to-float') || this.isState('building-float')) { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}.0`); + } else { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}.0`); + } + } else if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.literalTypes[key] = 'Integer'; + retArr.push(Math.round(ast.value)); + } else { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}`); + } + return retArr; + } + astBinaryExpression(ast, retArr) { + if (this.checkAndUpconvertOperator(ast, retArr)) { + return retArr; + } + if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { + retArr.push('div_with_int_check('); this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); + switch (this.getType(ast.left)) { + case 'Integer': + this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(', '); + switch (this.getType(ast.right)) { + case 'Integer': + this.castValueToFloat(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } this.popState('building-float'); - break; - case 'LiteralInteger & LiteralInteger': - if (this.isState('casting-to-integer') || this.isState('building-integer')) { + retArr.push(')'); + return retArr; + } + retArr.push('('); + const leftType = this.getType(ast.left) || 'Number'; + const rightType = this.getType(ast.right) || 'Number'; + if (!leftType || !rightType) { + throw this.astErrorOutput(`Unhandled binary expression`, ast); + } + const key = leftType + ' & ' + rightType; + switch (key) { + case 'Integer & Integer': this.pushState('building-integer'); this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); this.astGeneric(ast.right, retArr); this.popState('building-integer'); - } else { + break; + case 'Number & Float': + case 'Float & Number': + case 'Float & Float': + case 'Number & Number': this.pushState('building-float'); - this.castLiteralToFloat(ast.left, retArr); + this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); + this.astGeneric(ast.right, retArr); this.popState('building-float'); - } - break; - - case 'Integer & Float': - case 'Integer & Number': - if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') { - if (!Number.isInteger(ast.right.value)) { - this.pushState('building-float'); - this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger & LiteralInteger': + if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); this.astGeneric(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); this.popState('building-float'); - break; } - } - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.pushState('casting-to-integer'); - if (ast.right.type === 'Literal') { - const literalResult = []; - this.astGeneric(ast.right, literalResult); - const literalType = this.getType(ast.right); - if (literalType === 'Integer') { - retArr.push(literalResult.join('')); + break; + case 'Integer & Float': + case 'Integer & Number': + if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') { + if (!Number.isInteger(ast.right.value)) { + this.pushState('building-float'); + this.castValueToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-float'); + break; + } + } + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState('casting-to-integer'); + if (ast.right.type === 'Literal') { + const literalResult = []; + this.astGeneric(ast.right, literalResult); + const literalType = this.getType(ast.right); + if (literalType === 'Integer') { + retArr.push(literalResult.join('')); + } else { + throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + } } else { - throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + retArr.push('int('); + this.astGeneric(ast.right, retArr); + retArr.push(')'); } - } else { - retArr.push('int('); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - } - this.popState('casting-to-integer'); - this.popState('building-integer'); - break; - case 'Integer & LiteralInteger': - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToInteger(ast.right, retArr); - this.popState('building-integer'); - break; - - case 'Number & Integer': - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToFloat(ast.right, retArr); - this.popState('building-float'); - break; - case 'Float & LiteralInteger': - case 'Number & LiteralInteger': - if (this.isState('in-for-loop-test')) { + this.popState('casting-to-integer'); + this.popState('building-integer'); + break; + case 'Integer & LiteralInteger': this.pushState('building-integer'); - retArr.push('int('); this.astGeneric(ast.left, retArr); - retArr.push(')'); retArr.push(operatorMap[ast.operator] || ast.operator); this.castLiteralToInteger(ast.right, retArr); this.popState('building-integer'); - } else { + break; + case 'Number & Integer': this.pushState('building-float'); this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); + this.castValueToFloat(ast.right, retArr); this.popState('building-float'); - } - break; - case 'LiteralInteger & Float': - case 'LiteralInteger & Number': - if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) { + break; + case 'Float & LiteralInteger': + case 'Number & LiteralInteger': + if (this.isState('in-for-loop-test')) { + this.pushState('building-integer'); + retArr.push('int('); + this.astGeneric(ast.left, retArr); + retArr.push(')'); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Float': + case 'LiteralInteger & Number': + if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) { + this.pushState('building-integer'); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToInteger(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState('casting-to-float'); + this.astGeneric(ast.right, retArr); + this.popState('casting-to-float'); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Integer': this.pushState('building-integer'); this.castLiteralToInteger(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToInteger(ast.right, retArr); + this.astGeneric(ast.right, retArr); this.popState('building-integer'); - } else { - this.pushState('building-float'); + break; + case 'Boolean & Boolean': + this.pushState('building-boolean'); this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.pushState('casting-to-float'); this.astGeneric(ast.right, retArr); - this.popState('casting-to-float'); + this.popState('building-boolean'); + break; + case 'Float & Integer': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); this.popState('building-float'); - } - break; - case 'LiteralInteger & Integer': - this.pushState('building-integer'); - this.castLiteralToInteger(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-integer'); - break; - - case 'Boolean & Boolean': - this.pushState('building-boolean'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-boolean'); - break; - - case 'Float & Integer': - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToFloat(ast.right, retArr); - this.popState('building-float'); - break; - - default: - throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); + break; + default: + throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); + } + retArr.push(')'); + return retArr; } - retArr.push(')'); - - return retArr; - } - - checkAndUpconvertOperator(ast, retArr) { - const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); - if (bitwiseResult) { - return bitwiseResult; - } - const upconvertableOperators = { - '%': 'mod', - '**': 'pow', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - switch (this.getType(ast.left)) { - case 'Integer': - this.castValueToFloat(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.left, retArr); - break; - default: - this.astGeneric(ast.left, retArr); - } - retArr.push(','); - switch (this.getType(ast.right)) { - case 'Integer': - this.castValueToFloat(ast.right, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.right, retArr); - break; - default: - this.astGeneric(ast.right, retArr); + checkAndUpconvertOperator(ast, retArr) { + const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); + if (bitwiseResult) { + return bitwiseResult; + } + const upconvertableOperators = { + '%': 'mod', + '**': 'pow', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + switch (this.getType(ast.left)) { + case 'Integer': + this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(','); + switch (this.getType(ast.right)) { + case 'Integer': + this.castValueToFloat(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } + retArr.push(')'); + return retArr; } - retArr.push(')'); - return retArr; - } - - checkAndUpconvertBitwiseOperators(ast, retArr) { - const upconvertableOperators = { - '&': 'bitwiseAnd', - '|': 'bitwiseOr', - '^': 'bitwiseXOR', - '<<': 'bitwiseZeroFillLeftShift', - '>>': 'bitwiseSignedRightShift', - '>>>': 'bitwiseZeroFillRightShift', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - const leftType = this.getType(ast.left); - switch (leftType) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.left, retArr); - break; - default: - this.astGeneric(ast.left, retArr); - } - retArr.push(','); - const rightType = this.getType(ast.right); - switch (rightType) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.right, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.right, retArr); - break; - default: - this.astGeneric(ast.right, retArr); + checkAndUpconvertBitwiseOperators(ast, retArr) { + const upconvertableOperators = { + '&': 'bitwiseAnd', + '|': 'bitwiseOr', + '^': 'bitwiseXOR', + '<<': 'bitwiseZeroFillLeftShift', + '>>': 'bitwiseSignedRightShift', + '>>>': 'bitwiseZeroFillRightShift', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + const leftType = this.getType(ast.left); + switch (leftType) { + case 'Number': + case 'Float': + this.castValueToInteger(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(','); + const rightType = this.getType(ast.right); + switch (rightType) { + case 'Number': + case 'Float': + this.castValueToInteger(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } + retArr.push(')'); + return retArr; } - retArr.push(')'); - return retArr; - } - - checkAndUpconvertBitwiseUnary(ast, retArr) { - const upconvertableOperators = { - '~': 'bitwiseNot', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - switch (this.getType(ast.argument)) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.argument, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.argument, retArr); - break; - default: - this.astGeneric(ast.argument, retArr); + checkAndUpconvertBitwiseUnary(ast, retArr) { + const upconvertableOperators = { + '~': 'bitwiseNot', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + switch (this.getType(ast.argument)) { + case 'Number': + case 'Float': + this.castValueToInteger(ast.argument, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, retArr); + break; + default: + this.astGeneric(ast.argument, retArr); + } + retArr.push(')'); + return retArr; } - retArr.push(')'); - return retArr; - } - - castLiteralToInteger(ast, retArr) { - this.pushState('casting-to-integer'); - this.astGeneric(ast, retArr); - this.popState('casting-to-integer'); - return retArr; - } - - castLiteralToFloat(ast, retArr) { - this.pushState('casting-to-float'); - this.astGeneric(ast, retArr); - this.popState('casting-to-float'); - return retArr; - } - - castValueToInteger(ast, retArr) { - this.pushState('casting-to-integer'); - retArr.push('int('); - this.astGeneric(ast, retArr); - retArr.push(')'); - this.popState('casting-to-integer'); - return retArr; - } - - castValueToFloat(ast, retArr) { - this.pushState('casting-to-float'); - retArr.push('float('); - this.astGeneric(ast, retArr); - retArr.push(')'); - this.popState('casting-to-float'); - return retArr; - } - - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); + castLiteralToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + this.astGeneric(ast, retArr); + this.popState('casting-to-integer'); + return retArr; } - - const type = this.getType(idtNode); - - if (idtNode.name === 'Infinity') { - retArr.push('3.402823466e+38'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); + castLiteralToFloat(ast, retArr) { + this.pushState('casting-to-float'); + this.astGeneric(ast, retArr); + this.popState('casting-to-float'); + return retArr; + } + castValueToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + retArr.push('int('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-integer'); + return retArr; + } + castValueToFloat(ast, retArr) { + this.pushState('casting-to-float'); + retArr.push('float('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-float'); + return retArr; + } + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); + } + const type = this.getType(idtNode); + if (idtNode.name === 'Infinity') { + retArr.push('3.402823466e+38'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); + } else { + retArr.push(`user_${idtNode.name}`); + } } else { retArr.push(`user_${idtNode.name}`); } - } else { - retArr.push(`user_${idtNode.name}`); + return retArr; } - - return retArr; - } - - astForStatement(forNode, retArr) { - if (forNode.type !== 'ForStatement') { - throw this.astErrorOutput('Invalid for statement', forNode); - } - - const initArr = []; - const testArr = []; - const updateArr = []; - const bodyArr = []; - let isSafe = null; - - if (forNode.init) { - this.pushState('in-for-loop-init'); - this.astGeneric(forNode.init, initArr); - const { declarations } = forNode.init; - for (let i = 0; i < declarations.length; i++) { - if (declarations[i].init && declarations[i].init.type !== 'Literal') { - isSafe = false; + astForStatement(forNode, retArr) { + if (forNode.type !== 'ForStatement') { + throw this.astErrorOutput('Invalid for statement', forNode); + } + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + if (forNode.init) { + this.pushState('in-for-loop-init'); + this.astGeneric(forNode.init, initArr); + const { declarations } = forNode.init; + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init && declarations[i].init.type !== 'Literal') { + isSafe = false; + } + } + if (isSafe) { + for (let i = 0; i < initArr.length; i++) { + if (initArr[i].includes && initArr[i].includes(',')) { + isSafe = false; + } + } } + this.popState('in-for-loop-init'); + } else { + isSafe = false; + } + if (forNode.test) { + this.pushState('in-for-loop-test'); + this.astGeneric(forNode.test, testArr); + this.popState('in-for-loop-test'); + } else { + isSafe = false; + } + if (forNode.update) { + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; + } + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); + } + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); } if (isSafe) { - for (let i = 0; i < initArr.length; i++) { - if (initArr[i].includes && initArr[i].includes(',')) { - isSafe = false; - } + retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); + retArr.push(bodyArr.join('')); + retArr.push('}\n'); + } else { + const iVariableName = this.getInternalVariableName('safeI'); + if (initArr.length > 0) { + retArr.push(initArr.join(''), ';\n'); + } + retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) { + retArr.push(`if (!${testArr.join('')}) break;\n`); } + retArr.push(bodyArr.join('')); + retArr.push(`\n${updateArr.join('')};`); + retArr.push('}\n'); } - this.popState('in-for-loop-init'); - } else { - isSafe = false; - } - - if (forNode.test) { - this.pushState('in-for-loop-test'); - this.astGeneric(forNode.test, testArr); - this.popState('in-for-loop-test'); - } else { - isSafe = false; - } - - if (forNode.update) { - this.astGeneric(forNode.update, updateArr); - } else { - isSafe = false; - } - - if (forNode.body) { - this.pushState('loop-body'); - this.astGeneric(forNode.body, bodyArr); - this.popState('loop-body'); - } - - if (isSafe === null) { - isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); + return retArr; } - - if (isSafe) { - retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); - retArr.push(bodyArr.join('')); - retArr.push('}\n'); - } else { - const iVariableName = this.getInternalVariableName('safeI'); - if (initArr.length > 0) { - retArr.push(initArr.join(''), ';\n'); + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput('Invalid while statement', whileNode); } + const iVariableName = this.getInternalVariableName('safeI'); retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) { - retArr.push(`if (!${testArr.join('')}) break;\n`); - } - retArr.push(bodyArr.join('')); - retArr.push(`\n${updateArr.join('')};`); + retArr.push('if (!'); + this.astGeneric(whileNode.test, retArr); + retArr.push(') break;\n'); + this.astGeneric(whileNode.body, retArr); retArr.push('}\n'); + return retArr; } - return retArr; - } - - astWhileStatement(whileNode, retArr) { - if (whileNode.type !== 'WhileStatement') { - throw this.astErrorOutput('Invalid while statement', whileNode); - } - - const iVariableName = this.getInternalVariableName('safeI'); - retArr.push(`for (int ${iVariableName}=0;${iVariableName} i + 1) { - movingDefaultToEnd = true; - this.astGeneric(cases[i].consequent, defaultResult); - continue; + if (ifNode.alternate) { + retArr.push('else '); + if (ifNode.alternate.type === 'BlockStatement') { + this.astGeneric(ifNode.alternate, retArr); } else { - retArr.push(' else {\n'); + retArr.push(' {\n'); + this.astGeneric(ifNode.alternate, retArr); + retArr.push('\n}\n'); } - } else { - if (i === 0 || !pastFirstIf) { - pastFirstIf = true; - retArr.push(`if (${varName} == `); + } + return retArr; + } + astSwitchStatement(ast, retArr) { + if (ast.type !== 'SwitchStatement') { + throw this.astErrorOutput('Invalid switch statement', ast); + } + const { discriminant, cases } = ast; + const type = this.getType(discriminant); + const varName = `switchDiscriminant${ast.start}_${ast.end}`; + switch (type) { + case 'Float': + case 'Number': + retArr.push(`float ${varName} = `); + this.astGeneric(discriminant, retArr); + retArr.push(';\n'); + break; + case 'Integer': + retArr.push(`int ${varName} = `); + this.astGeneric(discriminant, retArr); + retArr.push(';\n'); + break; + } + if (cases.length === 1 && !cases[0].test) { + this.astGeneric(cases[0].consequent, retArr); + return retArr; + } + let fallingThrough = false; + let defaultResult = []; + let movingDefaultToEnd = false; + let pastFirstIf = false; + for (let i = 0; i < cases.length; i++) { + if (!cases[i].test) { + if (cases.length > i + 1) { + movingDefaultToEnd = true; + this.astGeneric(cases[i].consequent, defaultResult); + continue; + } else { + retArr.push(' else {\n'); + } } else { - if (fallingThrough) { - retArr.push(`${varName} == `); - fallingThrough = false; + if (i === 0 || !pastFirstIf) { + pastFirstIf = true; + retArr.push(`if (${varName} == `); } else { - retArr.push(` else if (${varName} == `); + if (fallingThrough) { + retArr.push(`${varName} == `); + fallingThrough = false; + } else { + retArr.push(` else if (${varName} == `); + } } - } - if (type === 'Integer') { - const testType = this.getType(cases[i].test); - switch (testType) { - case 'Number': - case 'Float': - this.castValueToInteger(cases[i].test, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(cases[i].test, retArr); - break; + if (type === 'Integer') { + const testType = this.getType(cases[i].test); + switch (testType) { + case 'Number': + case 'Float': + this.castValueToInteger(cases[i].test, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(cases[i].test, retArr); + break; + } + } else if (type === 'Float') { + const testType = this.getType(cases[i].test); + switch (testType) { + case 'LiteralInteger': + this.castLiteralToFloat(cases[i].test, retArr); + break; + case 'Integer': + this.castValueToFloat(cases[i].test, retArr); + break; + } + } else { + throw new Error('unhanlded'); } - } else if (type === 'Float') { - const testType = this.getType(cases[i].test); - switch (testType) { - case 'LiteralInteger': - this.castLiteralToFloat(cases[i].test, retArr); - break; - case 'Integer': - this.castValueToFloat(cases[i].test, retArr); - break; + if (!cases[i].consequent || cases[i].consequent.length === 0) { + fallingThrough = true; + retArr.push(' || '); + continue; } - } else { - throw new Error('unhanlded'); - } - if (!cases[i].consequent || cases[i].consequent.length === 0) { - fallingThrough = true; - retArr.push(' || '); - continue; + retArr.push(`) {\n`); } - retArr.push(`) {\n`); + this.astGeneric(cases[i].consequent, retArr); + retArr.push('\n}'); } - this.astGeneric(cases[i].consequent, retArr); - retArr.push('\n}'); + if (movingDefaultToEnd) { + retArr.push(' else {'); + retArr.push(defaultResult.join('')); + retArr.push('}'); + } + return retArr; } - if (movingDefaultToEnd) { - retArr.push(' else {'); - retArr.push(defaultResult.join('')); - retArr.push('}'); + astThisExpression(tNode, retArr) { + retArr.push('this'); + return retArr; } - return retArr; - } - - astThisExpression(tNode, retArr) { - retArr.push('this'); - return retArr; - } - - astMemberExpression(mNode, retArr) { - const { - property, - name, - signature, - origin, - type, - xProperty, - yProperty, - zProperty - } = this.getMemberExpressionDetails(mNode); - switch (signature) { - case 'value.thread.value': - case 'this.thread.value': - if (name !== 'x' && name !== 'y' && name !== 'z') { - throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode); - } - retArr.push(`threadId.${name}`); - return retArr; - case 'this.output.value': - if (this.dynamicOutput) { - switch (name) { - case 'x': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.x)'); - } else { - retArr.push('uOutputDim.x'); - } - break; - case 'y': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.y)'); - } else { - retArr.push('uOutputDim.y'); - } - break; - case 'z': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.z)'); - } else { - retArr.push('uOutputDim.z'); - } - break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); + astMemberExpression(mNode, retArr) { + const { + property, + name, + signature, + origin, + type, + xProperty, + yProperty, + zProperty + } = this.getMemberExpressionDetails(mNode); + switch (signature) { + case 'value.thread.value': + case 'this.thread.value': + if (name !== 'x' && name !== 'y' && name !== 'z') { + throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode); } - } else { - switch (name) { - case 'x': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[0]); - } else { - retArr.push(this.output[0], '.0'); - } - break; - case 'y': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[1]); - } else { - retArr.push(this.output[1], '.0'); - } - break; - case 'z': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[2]); - } else { - retArr.push(this.output[2], '.0'); - } - break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); + retArr.push(`threadId.${name}`); + return retArr; + case 'this.output.value': + if (this.dynamicOutput) { + switch (name) { + case 'x': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.x)'); + } else { + retArr.push('uOutputDim.x'); + } + break; + case 'y': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.y)'); + } else { + retArr.push('uOutputDim.y'); + } + break; + case 'z': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.z)'); + } else { + retArr.push('uOutputDim.z'); + } + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + } else { + switch (name) { + case 'x': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[0]); + } else { + retArr.push(this.output[0], '.0'); + } + break; + case 'y': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[1]); + } else { + retArr.push(this.output[1], '.0'); + } + break; + case 'z': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[2]); + } else { + retArr.push(this.output[2], '.0'); + } + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } } - } - return retArr; - case 'value': - throw this.astErrorOutput('Unexpected expression', mNode); - case 'value[]': - case 'value[][]': - case 'value[][][]': - case 'value[][][][]': - case 'value.value': - if (origin === 'Math') { - retArr.push(Math[name]); return retArr; - } - switch (property) { - case 'r': - retArr.push(`user_${ name }.r`); - return retArr; - case 'g': - retArr.push(`user_${ name }.g`); - return retArr; - case 'b': - retArr.push(`user_${ name }.b`); - return retArr; - case 'a': - retArr.push(`user_${ name }.a`); + case 'value': + throw this.astErrorOutput('Unexpected expression', mNode); + case 'value[]': + case 'value[][]': + case 'value[][][]': + case 'value[][][][]': + case 'value.value': + if (origin === 'Math') { + retArr.push(Math[name]); return retArr; - } - break; - case 'this.constants.value': - if (typeof xProperty === 'undefined') { - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - retArr.push(`constants_${ name }`); + } + switch (property) { + case 'r': + retArr.push(`user_${ name }.r`); + return retArr; + case 'g': + retArr.push(`user_${ name }.g`); + return retArr; + case 'b': + retArr.push(`user_${ name }.b`); + return retArr; + case 'a': + retArr.push(`user_${ name }.a`); return retArr; } - } - case 'this.constants.value[]': - case 'this.constants.value[][]': - case 'this.constants.value[][][]': - case 'this.constants.value[][][][]': break; - case 'fn()[]': - this.astCallExpression(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(property)); - retArr.push(']'); - return retArr; - case '[][]': - this.astArrayExpression(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(property)); - retArr.push(']'); - return retArr; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - - if (mNode.computed === false) { - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - retArr.push(`${origin}_${name}`); - return retArr; - } - } - - const markupName = `${origin}_${name}`; - - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - this.astGeneric(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(xProperty)); - retArr.push(']'); - break; - case 'HTMLImageArray': - retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(1)': - retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(2)': - case 'Array2D(2)': - case 'Array3D(2)': - retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(2)': - retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(3)': - case 'Array2D(3)': - case 'Array3D(3)': - retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(3)': - retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(4)': - case 'Array2D(4)': - case 'Array3D(4)': - retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(4)': - case 'HTMLImage': - case 'HTMLVideo': - retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'NumberTexture': - case 'Array': - case 'Array2D': - case 'Array3D': - case 'Array4D': - case 'Input': - case 'Number': - case 'Float': - case 'Integer': - if (this.precision === 'single') { - retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - } else { - const bitRatio = (origin === 'user' ? - this.lookupFunctionArgumentBitRatio(this.name, name) : - this.constantBitRatios[name] - ); - switch (bitRatio) { - case 1: - retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - case 2: - retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - case 4: - case 0: - retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - default: - throw new Error(`unhandled bit ratio of ${bitRatio}`); + case 'this.constants.value': + if (typeof xProperty === 'undefined') { + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + retArr.push(`constants_${ name }`); + return retArr; + } } - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - } - break; - case 'MemoryOptimizedNumberTexture': - retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - default: - throw new Error(`unhandled member expression "${ type }"`); - } - return retArr; - } - - astCallExpression(ast, retArr) { - if (!ast.callee) { - throw this.astErrorOutput('Unknown CallExpression', ast); - } - - let functionName = null; - const isMathFunction = this.isAstMathFunction(ast); - - if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) { - functionName = ast.callee.property.name; - } - else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) { - functionName = ast.callee.expressions[1].property.name; - } else { - functionName = ast.callee.name; - } - - if (!functionName) { - throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); - } - - if (functionName === 'atan2') { - functionName = 'atan'; - } - - if (this.calledFunctions.indexOf(functionName) < 0) { - this.calledFunctions.push(functionName); - } - - if (functionName === 'random' && this.plugins && this.plugins.length > 0) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) { - retArr.push(plugin.functionReplace); - return retArr; - } - } - } - - if (this.onFunctionCall) { - this.onFunctionCall(this.name, functionName, ast.arguments); - } - - retArr.push(functionName); - - retArr.push('('); - - if (isMathFunction) { - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - const argumentType = this.getType(argument); - if (i > 0) { - retArr.push(', '); - } - - switch (argumentType) { - case 'Integer': - this.castValueToFloat(argument, retArr); + case 'this.constants.value[]': + case 'this.constants.value[][]': + case 'this.constants.value[][][]': + case 'this.constants.value[][][][]': break; + case 'fn()[]': + this.astCallExpression(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push(']'); + return retArr; + case '[][]': + this.astArrayExpression(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push(']'); + return retArr; default: - this.astGeneric(argument, retArr); - break; - } + throw this.astErrorOutput('Unexpected expression', mNode); } - } else { - const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - let targetType = targetTypes[i]; - if (i > 0) { - retArr.push(', '); - } - const argumentType = this.getType(argument); - if (!targetType) { - this.triggerImplyArgumentType(functionName, i, argumentType, this); - targetType = argumentType; - } - switch (argumentType) { + if (mNode.computed === false) { + switch (type) { case 'Number': - case 'Float': - if (targetType === 'Integer') { - retArr.push('int('); - this.astGeneric(argument, retArr); - retArr.push(')'); - continue; - } else if (targetType === 'Number' || targetType === 'Float') { - this.astGeneric(argument, retArr); - continue; - } else if (targetType === 'LiteralInteger') { - this.castLiteralToFloat(argument, retArr); - continue; - } - break; case 'Integer': - if (targetType === 'Number' || targetType === 'Float') { - retArr.push('float('); - this.astGeneric(argument, retArr); - retArr.push(')'); - continue; - } else if (targetType === 'Integer') { - this.astGeneric(argument, retArr); - continue; - } - break; - case 'LiteralInteger': - if (targetType === 'Integer') { - this.castLiteralToInteger(argument, retArr); - continue; - } else if (targetType === 'Number' || targetType === 'Float') { - this.castLiteralToFloat(argument, retArr); - continue; - } else if (targetType === 'LiteralInteger') { - this.astGeneric(argument, retArr); - continue; - } - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - if (targetType === argumentType) { - if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name}`); - continue; - } - break; - case 'HTMLImage': - case 'HTMLImageArray': - case 'HTMLVideo': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'Array': - case 'Input': - if (targetType === argumentType) { - if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); - continue; - } - break; + case 'Float': + case 'Boolean': + retArr.push(`${origin}_${name}`); + return retArr; } - throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); - } - } - retArr.push(')'); - - return retArr; - } - - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('vec' + arrLen + '('); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - const subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr) - } - retArr.push(')'); - - return retArr; - } - - memberExpressionXYZ(x, y, z, retArr) { - if (z) { - retArr.push(this.memberExpressionPropertyMarkup(z), ', '); - } else { - retArr.push('0, '); - } - if (y) { - retArr.push(this.memberExpressionPropertyMarkup(y), ', '); - } else { - retArr.push('0, '); - } - retArr.push(this.memberExpressionPropertyMarkup(x)); - return retArr; - } - - memberExpressionPropertyMarkup(property) { - if (!property) { - throw new Error('Property not set'); - } - const type = this.getType(property); - const result = []; - switch (type) { - case 'Number': - case 'Float': - this.castValueToInteger(property, result); - break; - case 'LiteralInteger': - this.castLiteralToInteger(property, result); - break; - default: - this.astGeneric(property, result); - } - return result.join(''); - } -} - -const typeMap = { - 'Array': 'sampler2D', - 'Array(2)': 'vec2', - 'Array(3)': 'vec3', - 'Array(4)': 'vec4', - 'Array2D': 'sampler2D', - 'Array3D': 'sampler2D', - 'Boolean': 'bool', - 'Float': 'float', - 'Input': 'sampler2D', - 'Integer': 'int', - 'Number': 'float', - 'LiteralInteger': 'float', - 'NumberTexture': 'sampler2D', - 'MemoryOptimizedNumberTexture': 'sampler2D', - 'ArrayTexture(1)': 'sampler2D', - 'ArrayTexture(2)': 'sampler2D', - 'ArrayTexture(3)': 'sampler2D', - 'ArrayTexture(4)': 'sampler2D', - 'HTMLVideo': 'sampler2D', - 'HTMLImage': 'sampler2D', - 'HTMLImageArray': 'sampler2DArray', -}; - -const operatorMap = { - '===': '==', - '!==': '!=' -}; - -module.exports = { - WebGLFunctionNode -}; -},{"../../utils":111,"../function-node":9}],37:[function(require,module,exports){ -const { WebGLKernelValueBoolean } = require('./kernel-value/boolean'); -const { WebGLKernelValueFloat } = require('./kernel-value/float'); -const { WebGLKernelValueInteger } = require('./kernel-value/integer'); - -const { WebGLKernelValueHTMLImage } = require('./kernel-value/html-image'); -const { WebGLKernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image'); - -const { WebGLKernelValueHTMLVideo } = require('./kernel-value/html-video'); -const { WebGLKernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video'); - -const { WebGLKernelValueSingleInput } = require('./kernel-value/single-input'); -const { WebGLKernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input'); - -const { WebGLKernelValueUnsignedInput } = require('./kernel-value/unsigned-input'); -const { WebGLKernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input'); - -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture'); -const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture'); - -const { WebGLKernelValueNumberTexture } = require('./kernel-value/number-texture'); -const { WebGLKernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture'); - -const { WebGLKernelValueSingleArray } = require('./kernel-value/single-array'); -const { WebGLKernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array'); - -const { WebGLKernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i'); -const { WebGLKernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i'); - -const { WebGLKernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i'); -const { WebGLKernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i'); - -const { WebGLKernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i'); -const { WebGLKernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i'); - -const { WebGLKernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGLKernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGLKernelValueSingleArray4 } = require('./kernel-value/single-array4'); - -const { WebGLKernelValueUnsignedArray } = require('./kernel-value/unsigned-array'); -const { WebGLKernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array'); - -const kernelValueMaps = { - unsigned: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGLKernelValueDynamicUnsignedInput, - 'NumberTexture': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGLKernelValueUnsignedInput, - 'NumberTexture': WebGLKernelValueNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI, - 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI, - 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI, - 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI, - 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI, - 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI, - 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI, - 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI, - 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI, - 'Input': WebGLKernelValueDynamicSingleInput, - 'NumberTexture': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - 'Array1D(2)': WebGLKernelValueSingleArray1DI, - 'Array1D(3)': WebGLKernelValueSingleArray1DI, - 'Array1D(4)': WebGLKernelValueSingleArray1DI, - 'Array2D(2)': WebGLKernelValueSingleArray2DI, - 'Array2D(3)': WebGLKernelValueSingleArray2DI, - 'Array2D(4)': WebGLKernelValueSingleArray2DI, - 'Array3D(2)': WebGLKernelValueSingleArray3DI, - 'Array3D(3)': WebGLKernelValueSingleArray3DI, - 'Array3D(4)': WebGLKernelValueSingleArray3DI, - 'Input': WebGLKernelValueSingleInput, - 'NumberTexture': WebGLKernelValueNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, -}; - -function lookupKernelValueType(type, dynamic, precision, value) { - if (!type) { - throw new Error('type missing'); - } - if (!dynamic) { - throw new Error('dynamic missing'); - } - if (!precision) { - throw new Error('precision missing'); - } - if (value.type) { - type = value.type; - } - const types = kernelValueMaps[precision][dynamic]; - if (types[type] === false) { - return null; - } else if (types[type] === undefined) { - throw new Error(`Could not find a KernelValue for ${ type }`); - } - return types[type]; -} - -module.exports = { - lookupKernelValueType, - kernelValueMaps, -}; -},{"./kernel-value/boolean":38,"./kernel-value/dynamic-html-image":39,"./kernel-value/dynamic-html-video":40,"./kernel-value/dynamic-memory-optimized-number-texture":41,"./kernel-value/dynamic-number-texture":42,"./kernel-value/dynamic-single-array":43,"./kernel-value/dynamic-single-array1d-i":44,"./kernel-value/dynamic-single-array2d-i":45,"./kernel-value/dynamic-single-array3d-i":46,"./kernel-value/dynamic-single-input":47,"./kernel-value/dynamic-unsigned-array":48,"./kernel-value/dynamic-unsigned-input":49,"./kernel-value/float":50,"./kernel-value/html-image":51,"./kernel-value/html-video":52,"./kernel-value/integer":54,"./kernel-value/memory-optimized-number-texture":55,"./kernel-value/number-texture":56,"./kernel-value/single-array":57,"./kernel-value/single-array1d-i":58,"./kernel-value/single-array2":59,"./kernel-value/single-array2d-i":60,"./kernel-value/single-array3":61,"./kernel-value/single-array3d-i":62,"./kernel-value/single-array4":63,"./kernel-value/single-input":64,"./kernel-value/unsigned-array":65,"./kernel-value/unsigned-input":66}],38:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueBoolean extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const bool ${this.id} = ${value};\n`; - } - return `uniform bool ${this.id};\n`; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueBoolean -}; -},{"../../../utils":111,"./index":53}],39:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.textureSize = [width, height]; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicHTMLImage -}; -},{"../../../utils":111,"./html-image":51}],40:[function(require,module,exports){ -const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} - -module.exports = { - WebGLKernelValueDynamicHTMLVideo -}; -},{"./dynamic-html-image":39}],41:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./memory-optimized-number-texture'); - -class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(inputTexture) { - this.checkSize(inputTexture.size[0], inputTexture.size[1]); - this.dimensions = inputTexture.dimensions; - this.textureSize = inputTexture.size; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(inputTexture); - } -} - -module.exports = { - WebGLKernelValueDynamicMemoryOptimizedNumberTexture -}; -},{"../../../utils":111,"./memory-optimized-number-texture":55}],42:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueNumberTexture } = require('./number-texture'); - -class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = value.dimensions; - this.checkSize(value.size[0], value.size[1]); - this.textureSize = value.size; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicNumberTexture -}; -},{"../../../utils":111,"./number-texture":56}],43:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray } = require('./single-array'); - -class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray -}; -},{"../../../utils":111,"./single-array":57}],44:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray1DI } = require('./single-array1d-i'); - -class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray1DI -}; -},{"../../../utils":111,"./single-array1d-i":58}],45:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray2DI } = require('./single-array2d-i'); - -class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray2DI -}; -},{"../../../utils":111,"./single-array2d-i":60}],46:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray3DI } = require('./single-array3d-i'); - -class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray3DI -}; -},{"../../../utils":111,"./single-array3d-i":62}],47:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleInput } = require('./single-input'); - -class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleInput -}; -},{"../../../utils":111,"./single-input":64}],48:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedArray } = require('./unsigned-array'); - -class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - const Type = this.getTransferArrayType(value); - this.preUploadValue = new Type(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicUnsignedArray -}; -},{"../../../utils":111,"./unsigned-array":65}],49:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedInput } = require('./unsigned-input'); - -class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - const Type = this.getTransferArrayType(value.value); - this.preUploadValue = new Type(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicUnsignedInput -}; -},{"../../../utils":111,"./unsigned-input":66}],50:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueFloat extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - getSource(value) { - if (this.origin === 'constants') { - if (Number.isInteger(value)) { - return `const float ${this.id} = ${value}.0;\n`; } - return `const float ${this.id} = ${value};\n`; - } - return `uniform float ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1f(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueFloat -}; -},{"../../../utils":111,"./index":53}],51:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueHTMLImage extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.requestTexture(); - this.textureSize = [width, height]; - this.uploadValue = value; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputImage) { - if (inputImage.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueHTMLImage -}; -},{"../../../utils":111,"./index":53}],52:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} - -module.exports = { - WebGLKernelValueHTMLVideo -}; -},{"../../../utils":111,"./html-image":51}],53:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Input } = require('../../../input'); -const { KernelValue } = require('../../kernel-value'); - -class WebGLKernelValue extends KernelValue { - constructor(value, settings) { - super(value, settings); - this.dimensionsId = null; - this.sizeId = null; - this.initialValueConstructor = value.constructor; - this.onRequestTexture = settings.onRequestTexture; - this.onRequestIndex = settings.onRequestIndex; - this.uploadValue = null; - this.textureSize = null; - this.bitRatio = null; - } - - checkSize(width, height) { - if (!this.kernel.validate) return; - const { maxTextureSize } = this.kernel.constructor.features; - if (width > maxTextureSize || height > maxTextureSize) { - if (width > height) { - throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); - } else { - throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); - } - } - } - - requestTexture() { - this.texture = this.onRequestTexture(); - this.setupTexture(); - } - - setupTexture() { - this.contextHandle = this.onRequestContextHandle(); - this.index = this.onRequestIndex(); - this.dimensionsId = this.id + 'Dim'; - this.sizeId = this.id + 'Size'; - } - - getTransferArrayType(value) { - if (Array.isArray(value[0])) { - return this.getTransferArrayType(value[0]); - } - switch (value.constructor) { - case Array: - case Int32Array: - case Int16Array: - case Int8Array: - return Float32Array; - case Uint8ClampedArray: - case Uint8Array: - case Uint16Array: - case Uint32Array: - case Float32Array: - case Float64Array: - return value.constructor; - } - console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros'); - return value.constructor; - } - formatArrayTransfer(value, length, Type) { - if (utils.isArray(value[0]) || this.optimizeFloatMemory) { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } else { - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - case Uint16Array: - case Int16Array: - case Float32Array: - case Int32Array: { - const valuesFlat = new(Type || value.constructor)(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - default: { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - } - } - } - - getBitRatio(value) { - if (Array.isArray(value[0])) { - return this.getBitRatio(value[0]); - } else if (value.constructor === Input) { - return this.getBitRatio(value.value); - } - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - return 1; - case Uint16Array: - case Int16Array: - return 2; - case Float32Array: - case Int32Array: - default: - return 4; - } - } - - getStringValueHandler() { - throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); - } - - getVariablePrecisionString() { - switch (this.tactic) { - case 'speed': - return 'lowp'; - case 'performance': - return 'highp'; - case 'balanced': - default: - return 'mediump'; - } - } -} - -module.exports = { - WebGLKernelValue -}; -},{"../../../input":107,"../../../utils":111,"../../kernel-value":33}],54:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueInteger extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - getSource(value) { - if (this.origin === 'constants') { - return `const int ${this.id} = ${ parseInt(value) };\n`; - } - return `uniform int ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueInteger -}; -},{"../../../utils":111,"./index":53}],55:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - this.dimensions = value.dimensions; - this.textureSize = value.size; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputTexture) { - if (inputTexture.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type }) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueMemoryOptimizedNumberTexture -}; -},{"../../../utils":111,"./index":53}],56:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - const { size: textureSize, dimensions } = value; - this.bitRatio = this.getBitRatio(value); - this.dimensions = dimensions; - this.textureSize = textureSize; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputTexture) { - if (inputTexture.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type}) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueNumberTexture -}; -},{"../../../utils":111,"./index":53}],57:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray -}; -},{"../../../utils":111,"./index":53}],58:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], 1, 1]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten2dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray1DI -}; -},{"../../../utils":111,"./index":53}],59:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`; - } - return `uniform vec2 ${this.id};\n`; - } - - getStringValueHandler() { - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform2fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray2 -}; -},{"../../../utils":111,"./index":53}],60:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten3dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray2DI -}; -},{"../../../utils":111,"./index":53}],61:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`; - } - return `uniform vec3 ${this.id};\n`; - } - - getStringValueHandler() { - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform3fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray3 -}; -},{"../../../utils":111,"./index":53}],62:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten4dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray3DI -}; -},{"../../../utils":111,"./index":53}],63:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray4 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`; - } - return `uniform vec4 ${this.id};\n`; - } - - getStringValueHandler() { - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform4fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray4 -}; -},{"../../../utils":111,"./index":53}],64:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}.value, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(input) { - if (input.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleInput -}; -},{"../../../utils":111,"./index":53}],65:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = this.getBitRatio(value); - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - this.TranserArrayType = this.getTransferArrayType(value); - this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - } - - getStringValueHandler() { - return utils.linesToString([ - `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, - `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, - `flattenTo(${this.varName}, preUploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.preUploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueUnsignedArray -}; -},{"../../../utils":111,"./index":53}],66:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = this.getBitRatio(value); - const [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - this.TranserArrayType = this.getTransferArrayType(value.value); - this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - } - - getStringValueHandler() { - return utils.linesToString([ - `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, - `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, - `flattenTo(${this.varName}.value, preUploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(input) { - if (input.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.preUploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueUnsignedInput -}; -},{"../../../utils":111,"./index":53}],67:[function(require,module,exports){ -const { GLKernel } = require('../gl/kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { WebGLFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const triangleNoise = require('../../plugins/triangle-noise'); -const { fragmentShader } = require('./fragment-shader'); -const { vertexShader } = require('./vertex-shader'); -const { glKernelString } = require('../gl/kernel-string'); -const { lookupKernelValueType } = require('./kernel-value-maps'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; -let features = null; - -const plugins = [triangleNoise]; -const canvases = []; -const maxTexSizes = {}; - - -class WebGLKernel extends GLKernel { - static get isSupported() { - if (isSupported !== null) { - return isSupported; - } - this.setupFeatureChecks(); - isSupported = this.isContextMatch(testContext); - return isSupported; - } - - static setupFeatureChecks() { - if (typeof document !== 'undefined') { - testCanvas = document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - testCanvas = new OffscreenCanvas(0, 0); - } - if (!testCanvas) return; - testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - OES_texture_float: testContext.getExtension('OES_texture_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), - }; - features = this.getFeatures(); - } - - static isContextMatch(context) { - if (typeof WebGLRenderingContext !== 'undefined') { - return context instanceof WebGLRenderingContext; - } - return false; - } - - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - static getIsTextureFloat() { - return Boolean(testExtensions.OES_texture_float); - } - - static getIsDrawBuffers() { - return Boolean(testExtensions.WEBGL_draw_buffers); - } - - static getChannelCount() { - return testExtensions.WEBGL_draw_buffers ? - testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : - 1; - } - - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); - } - - static lookupKernelValueType(type, dynamic, precision, value) { - return lookupKernelValueType(type, dynamic, precision, value); - } - - static get testCanvas() { - return testCanvas; - } - - static get testContext() { - return testContext; - } - - static get features() { - return features; - } - - static get fragmentShader() { - return fragmentShader; - } - - static get vertexShader() { - return vertexShader; - } - - constructor(source, settings) { - super(source, settings); - this.program = null; - this.pipeline = settings.pipeline; - this.endianness = utils.systemEndianness(); - this.extensions = {}; - this.subKernelOutputTextures = null; - this.kernelArguments = null; - this.argumentTextureCount = 0; - this.constantTextureCount = 0; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - this.fragShader = null; - this.vertShader = null; - this.drawBuffersMap = null; - this.outputTexture = null; - - this.maxTexSize = null; - this.switchingKernels = false; - this.onRequestSwitchKernel = null; - - this.mergeSettings(source.settings || settings); - - this.threadDim = null; - this.framebuffer = null; - this.buffer = null; - this.textureCache = {}; - this.programUniformLocationCache = {}; - this.uniform1fCache = {}; - this.uniform1iCache = {}; - this.uniform2fCache = {}; - this.uniform2fvCache = {}; - this.uniform2ivCache = {}; - this.uniform3fvCache = {}; - this.uniform3ivCache = {}; - this.uniform4fvCache = {}; - this.uniform4ivCache = {}; - } - - initCanvas() { - if (typeof document !== 'undefined') { - const canvas = document.createElement('canvas'); - canvas.width = 2; - canvas.height = 2; - return canvas; - } else if (typeof OffscreenCanvas !== 'undefined') { - return new OffscreenCanvas(0, 0); - } - } - - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings); - } - - initPlugins(settings) { - const pluginsToUse = []; - const { source } = this; - if (typeof source === 'string') { - for (let i = 0; i < plugins.length; i++) { - const plugin = plugins[i]; - if (source.match(plugin.functionMatch)) { - pluginsToUse.push(plugin); - } - } - } else if (typeof source === 'object') { - if (settings.pluginNames) { - for (let i = 0; i < plugins.length; i++) { - const plugin = plugins[i]; - const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name); - if (usePlugin) { - pluginsToUse.push(plugin); - } - } - } - } - return pluginsToUse; - } - - initExtensions() { - this.extensions = { - OES_texture_float: this.context.getExtension('OES_texture_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), - WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'), - }; - } - - validateSettings(args) { - if (!this.validate) { - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - return; - } - - const { features } = this.constructor; - - if (this.optimizeFloatMemory === true && !features.isTextureFloat) { - throw new Error('Float textures are not supported'); - } else if (this.precision === 'single' && !features.isFloatRead) { - throw new Error('Single precision not supported'); - } else if (!this.graphical && this.precision === null && features.isTextureFloat) { - this.precision = features.isFloatRead ? 'single' : 'unsigned'; - } - - if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) { - throw new Error('could not instantiate draw buffers extension'); - } - - if (this.fixIntegerDivisionAccuracy === null) { - this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; - } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { - this.fixIntegerDivisionAccuracy = false; - } - - this.checkOutput(); - - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); - } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { - this.output = args[0].output; - } else { - throw new Error('Auto output not supported for input type: ' + argType); - } - } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); - } - - if (this.precision === 'precision') { - this.precision = 'unsigned'; - console.warn('Cannot use graphical mode and single precision at the same time'); - } - - this.texSize = utils.clone(this.output); - return; - } else if (this.precision === null && features.isTextureFloat) { - this.precision = 'single'; - } - - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - - this.checkTextureSize(); - } - - updateMaxTexSize() { - const { texSize, canvas } = this; - if (this.maxTexSize === null) { - let canvasIndex = canvases.indexOf(canvas); - if (canvasIndex === -1) { - canvasIndex = canvases.length; - canvases.push(canvas); - maxTexSizes[canvasIndex] = [texSize[0], texSize[1]]; - } - this.maxTexSize = maxTexSizes[canvasIndex]; - } - if (this.maxTexSize[0] < texSize[0]) { - this.maxTexSize[0] = texSize[0]; - } - if (this.maxTexSize[1] < texSize[1]) { - this.maxTexSize[1] = texSize[1]; - } - } - - _oldtranslateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - - const translatedSource = functionBuilder.getPrototypeString('kernel'); - - if (!this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - - let requiredChannels = 0; - const returnTypes = functionBuilder.getReturnTypes(); - for (let i = 0; i < returnTypes.length; i++) { - switch (returnTypes[i]) { - case 'Float': - case 'Number': - case 'Integer': - requiredChannels++; - break; - case 'Array(2)': - requiredChannels += 2; - break; - case 'Array(3)': - requiredChannels += 3; - break; - case 'Array(4)': - requiredChannels += 4; - break; - } - } - - if (features && requiredChannels > features.channelCount) { - throw new Error('Too many channels!'); - } - - return this.translatedSource = translatedSource; - } - - setupArguments(args) { - this.kernelArguments = []; - this.argumentTextureCount = 0; - const needsArgumentTypes = this.argumentTypes === null; - if (needsArgumentTypes) { - this.argumentTypes = []; - } - this.argumentSizes = []; - this.argumentBitRatios = []; - - if (args.length < this.argumentNames.length) { - throw new Error('not enough arguments for kernel'); - } else if (args.length > this.argumentNames.length) { - throw new Error('too many arguments for kernel'); - } - - const { context: gl } = this; - let textureIndexes = 0; - for (let index = 0; index < args.length; index++) { - const value = args[index]; - const name = this.argumentNames[index]; - let type; - if (needsArgumentTypes) { - type = utils.getVariableType(value, this.strictIntegers); - this.argumentTypes.push(type); - } else { - type = this.argumentTypes[index]; - } - const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]); - if (KernelValue === null) { - return this.requestFallback(args); - } - const kernelArgument = new KernelValue(value, { - name, - type, - tactic: this.tactic, - origin: 'user', - context: gl, - checkContext: this.checkContext, - kernel: this, - strictIntegers: this.strictIntegers, - onRequestTexture: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onUpdateValueMismatch: () => { - this.switchingKernels = true; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; - } - }); - this.kernelArguments.push(kernelArgument); - this.argumentSizes.push(kernelArgument.textureSize); - this.argumentBitRatios[index] = kernelArgument.bitRatio; - } - } - - setupConstants(args) { - const { context: gl } = this; - this.kernelConstants = []; - this.forceUploadKernelConstants = []; - let needsConstantTypes = this.constantTypes === null; - if (needsConstantTypes) { - this.constantTypes = {}; - } - this.constantBitRatios = {}; - let textureIndexes = 0; - for (const name in this.constants) { - const value = this.constants[name]; - let type; - if (needsConstantTypes) { - type = utils.getVariableType(value, this.strictIntegers); - this.constantTypes[name] = type; - } else { - type = this.constantTypes[name]; - } - const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value); - if (KernelValue === null) { - return this.requestFallback(args); - } - const kernelValue = new KernelValue(value, { - name, - type, - tactic: this.tactic, - origin: 'constants', - context: this.context, - checkContext: this.checkContext, - kernel: this, - strictIntegers: this.strictIntegers, - onRequestTexture: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount++; - } - }); - this.constantBitRatios[name] = kernelValue.bitRatio; - this.kernelConstants.push(kernelValue); - if (kernelValue.forceUploadEachRun) { - this.forceUploadKernelConstants.push(kernelValue); - } - } - } - - build() { - this.initExtensions(); - this.validateSettings(arguments); - this.setupConstants(arguments); - if (this.fallbackRequested) return; - this.setupArguments(arguments); - if (this.fallbackRequested) return; - this.updateMaxTexSize(); - this.translateSource(); - const failureResult = this.pickRenderStrategy(arguments); - if (failureResult) { - return failureResult; - } - const { texSize, context: gl, canvas } = this; - gl.enable(gl.SCISSOR_TEST); - if (this.pipeline && this.precision === 'single') { - gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - canvas.width = this.maxTexSize[0]; - canvas.height = this.maxTexSize[1]; - } else { - gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - canvas.width = this.maxTexSize[0]; - canvas.height = this.maxTexSize[1]; - } - const threadDim = this.threadDim = Array.from(this.output); - while (threadDim.length < 3) { - threadDim.push(1); - } - - const compiledVertexShader = this.getVertexShader(arguments); - const vertShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertShader, compiledVertexShader); - gl.compileShader(vertShader); - this.vertShader = vertShader; - - const compiledFragmentShader = this.getFragmentShader(arguments); - const fragShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragShader, compiledFragmentShader); - gl.compileShader(fragShader); - this.fragShader = fragShader; - - if (this.debug) { - console.log('GLSL Shader Output:'); - console.log(compiledFragmentShader); - } - - if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) { - throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader)); - } - if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) { - throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader)); - } - - const program = this.program = gl.createProgram(); - gl.attachShader(program, vertShader); - gl.attachShader(program, fragShader); - gl.linkProgram(program); - this.framebuffer = gl.createFramebuffer(); - this.framebuffer.width = texSize[0]; - this.framebuffer.height = texSize[1]; - - const vertices = new Float32Array([-1, -1, - 1, -1, -1, 1, - 1, 1 - ]); - const texCoords = new Float32Array([ - 0, 0, - 1, 0, - 0, 1, - 1, 1 - ]); - - const texCoordOffset = vertices.byteLength; - - let buffer = this.buffer; - if (!buffer) { - buffer = this.buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW); - } else { - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - } - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); - gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords); - - const aPosLoc = gl.getAttribLocation(this.program, 'aPos'); - gl.enableVertexAttribArray(aPosLoc); - gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0); - const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord'); - gl.enableVertexAttribArray(aTexCoordLoc); - gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - - let i = 0; - gl.useProgram(this.program); - for (let p in this.constants) { - this.kernelConstants[i++].updateValue(this.constants[p]); - } - - if (!this.immutable) { - this._setupOutputTexture(); - if ( - this.subKernels !== null && - this.subKernels.length > 0 - ) { - this._setupSubOutputTextures(); - } - } - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - - if (this.subKernels && this.subKernels.length > 0) { - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (!subKernel.returnType) { - subKernel.returnType = functionBuilder.getSubKernelResultType(i); - } - } - } - } - - run() { - const { kernelArguments, forceUploadKernelConstants } = this; - const texSize = this.texSize; - const gl = this.context; - - gl.useProgram(this.program); - gl.scissor(0, 0, texSize[0], texSize[1]); - - if (this.dynamicOutput) { - this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); - this.setUniform2iv('uTexSize', texSize); - } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.switchingKernels = false; - for (let i = 0; i < forceUploadKernelConstants.length; i++) { - const constant = forceUploadKernelConstants[i]; - constant.updateValue(this.constants[constant.name]); - if (this.switchingKernels) return; - } - for (let i = 0; i < kernelArguments.length; i++) { - kernelArguments[i].updateValue(arguments[i]); - if (this.switchingKernels) return; - } - - if (this.plugins) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.onBeforeRun) { - plugin.onBeforeRun(this); - } - } - } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); - } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return; - } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.immutable) { - this._setupOutputTexture(); - } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); - } - this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); - } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - getOutputTexture() { - return this.outputTexture; - } - - _setupOutputTexture() { - const gl = this.context; - const texSize = this.texSize; - const texture = this.outputTexture = this.context.createTexture(); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.precision === 'single') { - if (this.pipeline) { - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - if (this.optimizeFloatMemory) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } - break; - case 'Array(2)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - case 'Array(3)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - case 'Array(4)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - default: - if (!this.graphical) { - throw new Error('Unhandled return type'); - } - } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - _setupSubOutputTextures() { - const gl = this.context; - const texSize = this.texSize; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.precision === 'single') { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); - } - } - - getTextureCache(name) { - if (this.textureCache.hasOwnProperty(name)) { - return this.textureCache[name]; - } - return this.textureCache[name] = this.context.createTexture(); - } - - detachTextureCache(name) { - delete this.textureCache[name]; - } - - setUniform1f(name, value) { - if (this.uniform1fCache.hasOwnProperty(name)) { - const cache = this.uniform1fCache[name]; - if (value === cache) { - return; - } - } - this.uniform1fCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform1f(loc, value); - } - - setUniform1i(name, value) { - if (this.uniform1iCache.hasOwnProperty(name)) { - const cache = this.uniform1iCache[name]; - if (value === cache) { - return; - } - } - this.uniform1iCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform1i(loc, value); - } - - setUniform2f(name, value1, value2) { - if (this.uniform2fCache.hasOwnProperty(name)) { - const cache = this.uniform2fCache[name]; - if ( - value1 === cache[0] && - value2 === cache[1] - ) { - return; - } - } - this.uniform2fCache[name] = [value1, value2]; - const loc = this.getUniformLocation(name); - this.context.uniform2f(loc, value1, value2); - } - - setUniform2fv(name, value) { - if (this.uniform2fvCache.hasOwnProperty(name)) { - const cache = this.uniform2fvCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] - ) { - return; - } - } - this.uniform2fvCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform2fv(loc, value); - } - - setUniform2iv(name, value) { - if (this.uniform2ivCache.hasOwnProperty(name)) { - const cache = this.uniform2ivCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] - ) { - return; - } - } - this.uniform2ivCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform2iv(loc, value); - } - - setUniform3fv(name, value) { - if (this.uniform3fvCache.hasOwnProperty(name)) { - const cache = this.uniform3fvCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] - ) { - return; - } - } - this.uniform3fvCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform3fv(loc, value); - } - - setUniform3iv(name, value) { - if (this.uniform3ivCache.hasOwnProperty(name)) { - const cache = this.uniform3ivCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] - ) { - return; - } - } - this.uniform3ivCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform3iv(loc, value); - } - - setUniform3fv(name, value) { - if (this.uniform3fvCache.hasOwnProperty(name)) { - const cache = this.uniform3fvCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] - ) { - return; - } - } - this.uniform3fvCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform3fv(loc, value); - } - - setUniform4iv(name, value) { - if (this.uniform4ivCache.hasOwnProperty(name)) { - const cache = this.uniform4ivCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] && - value[3] === cache[3] - ) { - return; - } - } - this.uniform4ivCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform4iv(loc, value); - } - - setUniform4fv(name, value) { - if (this.uniform4fvCache.hasOwnProperty(name)) { - const cache = this.uniform4fvCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] && - value[3] === cache[3] - ) { - return; - } - } - this.uniform4fvCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform4fv(loc, value); - } - - getUniformLocation(name) { - if (this.programUniformLocationCache.hasOwnProperty(name)) { - return this.programUniformLocationCache[name]; - } - return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name); - } - - _getFragShaderArtifactMap(args) { - return { - HEADER: this._getHeaderString(), - LOOP_MAX: this._getLoopMaxString(), - PLUGINS: this._getPluginsString(), - CONSTANTS: this._getConstantsString(), - DECODE32_ENDIANNESS: this._getDecode32EndiannessString(), - ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(), - DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(), - INJECTED_NATIVE: this._getInjectedNative(), - MAIN_CONSTANTS: this._getMainConstantsString(), - MAIN_ARGUMENTS: this._getMainArgumentsString(args), - KERNEL: this.getKernelString(), - MAIN_RESULT: this.getMainResultString(), - FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), - INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), - SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), - SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), - }; - } - - _getVertShaderArtifactMap(args) { - return { - FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), - INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), - SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), - SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), - }; - } - - _getHeaderString() { - return ( - this.subKernels !== null ? - '#extension GL_EXT_draw_buffers : require\n' : - '' - ); - } - - _getLoopMaxString() { - return ( - this.loopMaxIterations ? - ` ${parseInt(this.loopMaxIterations)};\n` : - ' 1000;\n' - ); - } - - _getPluginsString() { - if (!this.plugins) return '\n'; - return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n'); - } - - _getConstantsString() { - const result = []; - const { threadDim, texSize } = this; - if (this.dynamicOutput) { - result.push( - 'uniform ivec3 uOutputDim', - 'uniform ivec2 uTexSize' - ); - } else { - result.push( - `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`, - `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})` - ); - } - return utils.linesToString(result); - } - - _getTextureCoordinate() { - const subKernels = this.subKernels; - if (subKernels === null || subKernels.length < 1) { - return 'varying vec2 vTexCoord;\n'; - } else { - return 'out vec2 vTexCoord;\n'; - } - } - - _getDecode32EndiannessString() { - return ( - this.endianness === 'LE' ? - '' : - ' texel.rgba = texel.abgr;\n' - ); - } - - _getEncode32EndiannessString() { - return ( - this.endianness === 'LE' ? - '' : - ' texel.rgba = texel.abgr;\n' - ); - } - - _getDivideWithIntegerCheckString() { - return this.fixIntegerDivisionAccuracy ? - `float div_with_int_check(float x, float y) { - if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { - return float(int(x)/int(y)); - } - return x / y; -}` : - ''; - } - - _getMainArgumentsString(args) { - const results = []; - const { argumentNames } = this; - for (let i = 0; i < argumentNames.length; i++) { - results.push(this.kernelArguments[i].getSource(args[i])); - } - return results.join(''); - } - - _getInjectedNative() { - return this.injectedNative || ''; - } - - _getMainConstantsString() { - const result = []; - const { constants } = this; - if (constants) { - let i = 0; - for (const name in constants) { - result.push(this.kernelConstants[i++].getSource(this.constants[name])); - } - } - return result.join(''); - } - - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; - } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); - } - } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration - ); - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - for (let i = 0; i < subKernels.length; i++) { - const subKernel = subKernels[i]; - result.push( - subKernel.returnType === 'Integer' ? - `int subKernelResult_${ subKernel.name } = 0` : - `float subKernelResult_${ subKernel.name } = 0.0` - ); - } - break; + const markupName = `${origin}_${name}`; + switch (type) { case 'Array(2)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec2 subKernelResult_${ subKernels[i].name }` - ); - } - break; case 'Array(3)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec3 subKernelResult_${ subKernels[i].name }` - ); - } - break; case 'Array(4)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec4 subKernelResult_${ subKernels[i].name }` - ); - } + this.astGeneric(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(xProperty)); + retArr.push(']'); break; - } - } else { - result.push( - kernelResultDeclaration - ); - } - - return utils.linesToString(result) + this.translatedSource; - } - - getMainResultGraphical() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragColor = actualColor', - ]); - } - - getMainResultPackedPixels() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return this.getMainResultKernelPackedPixels() + - this.getMainResultSubKernelPackedPixels(); - default: - throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); - } - } - - getMainResultKernelPackedPixels() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` - ]); - } - - getMainResultSubKernelPackedPixels() { - const result = []; - if (!this.subKernels) return ''; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` - ); - } else { - result.push( - ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` - ); - } - } - return utils.linesToString(result); - } - - getMainResultMemoryOptimizedFloats() { - const result = [ - ' index *= 4', - ]; - - switch (this.returnType) { - case 'Number': - case 'Integer': - case 'Float': - const channels = ['r', 'g', 'b', 'a']; - for (let i = 0; i < channels.length; i++) { - const channel = channels[i]; - this.getMainResultKernelMemoryOptimizedFloats(result, channel); - this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); - if (i + 1 < channels.length) { - result.push(' index += 1'); - } - } - break; - default: - throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); - } - - return utils.linesToString(result); - } - - getMainResultKernelMemoryOptimizedFloats(result, channel) { - result.push( - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` gl_FragData[0].${channel} = kernelResult`, - ); - } - - getMainResultSubKernelMemoryOptimizedFloats(result, channel) { - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`, - ); - } else { - result.push( - ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`, - ); - } - } - } - - getMainResultKernelNumberTexture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult', - ]; - } - - getMainResultSubKernelNumberTexture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`, - ); - } else { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`, - ); - } - } - return result; - } - - getMainResultKernelArray2Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult[0]', - ' gl_FragData[0][1] = kernelResult[1]', - ]; - } - - getMainResultSubKernelArray2Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ); - } - return result; - } - - getMainResultKernelArray3Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult[0]', - ' gl_FragData[0][1] = kernelResult[1]', - ' gl_FragData[0][2] = kernelResult[2]', - ]; - } - - getMainResultSubKernelArray3Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ); - } - return result; - } - - getMainResultKernelArray4Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0] = kernelResult', - ]; - } - - getMainResultSubKernelArray4Texture() { - const result = []; - if (!this.subKernels) return result; - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`, - ); + case 'HTMLImageArray': + retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(1)': + retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(2)': + case 'Array2D(2)': + case 'Array3D(2)': + retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(2)': + retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(3)': + case 'Array2D(3)': + case 'Array3D(3)': + retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(3)': + retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(4)': + case 'Array2D(4)': + case 'Array3D(4)': + retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(4)': + case 'HTMLImage': + case 'HTMLVideo': + retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'NumberTexture': + case 'Array': + case 'Array2D': + case 'Array3D': + case 'Array4D': + case 'Input': + case 'Number': + case 'Float': + case 'Integer': + if (this.precision === 'single') { + retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); } else { - result.push( - ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`, + const bitRatio = (origin === 'user' ? + this.lookupFunctionArgumentBitRatio(this.name, name) : + this.constantBitRatios[name] ); - } - } - break; - case 'Array(2)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ); - } - break; - case 'Array(3)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ); - } - break; - case 'Array(4)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`, - ); - } - break; - } - - return result; - } - - replaceArtifacts(src, map) { - return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => { - if (map.hasOwnProperty(artifact)) { - return map[artifact]; - } - throw `unhandled artifact ${artifact}`; - }); - } - - getFragmentShader(args) { - if (this.compiledFragmentShader !== null) { - return this.compiledFragmentShader; - } - return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args)); - } - - getVertexShader(args) { - if (this.compiledVertexShader !== null) { - return this.compiledVertexShader; - } - return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args)); - } - - toString() { - const setupContextString = utils.linesToString([ - `const gl = context`, - ]); - return glKernelString(this.constructor, arguments, this, setupContextString); - } - - destroy(removeCanvasReferences) { - if (this.outputTexture) { - this.context.deleteTexture(this.outputTexture); - } - if (this.buffer) { - this.context.deleteBuffer(this.buffer); - } - if (this.framebuffer) { - this.context.deleteFramebuffer(this.framebuffer); - } - if (this.vertShader) { - this.context.deleteShader(this.vertShader); - } - if (this.fragShader) { - this.context.deleteShader(this.fragShader); - } - if (this.program) { - this.context.deleteProgram(this.program); - } - - const keys = Object.keys(this.textureCache); - - for (let i = 0; i < keys.length; i++) { - const name = keys[i]; - this.context.deleteTexture(this.textureCache[name]); - } - - if (this.subKernelOutputTextures) { - for (let i = 0; i < this.subKernelOutputTextures.length; i++) { - this.context.deleteTexture(this.subKernelOutputTextures[i]); - } - } - if (removeCanvasReferences) { - const idx = canvases.indexOf(this.canvas); - if (idx >= 0) { - canvases[idx] = null; - maxTexSizes[idx] = null; - } - } - this.destroyExtensions(); - delete this.context; - delete this.canvas; - } - - destroyExtensions() { - this.extensions.OES_texture_float = null; - this.extensions.OES_texture_float_linear = null; - this.extensions.OES_element_index_uint = null; - this.extensions.WEBGL_draw_buffers = null; - } - - static destroyContext(context) { - const extension = context.getExtension('WEBGL_lose_context'); - if (extension) { - extension.loseContext(); - } - } - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); - return json; - } -} - -module.exports = { - WebGLKernel -}; -},{"../../plugins/triangle-noise":109,"../../utils":111,"../function-builder":8,"../gl/kernel":12,"../gl/kernel-string":11,"./fragment-shader":35,"./function-node":36,"./kernel-value-maps":37,"./vertex-shader":68}],68:[function(require,module,exports){ -const vertexShader = `__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -attribute vec2 aPos; -attribute vec2 aTexCoord; - -varying vec2 vTexCoord; -uniform vec2 ratio; - -void main(void) { - gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); - vTexCoord = aTexCoord; -}`; - -module.exports = { - vertexShader -}; -},{}],69:[function(require,module,exports){ -const fragmentShader = `#version 300 es -__HEADER__; -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; -__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; - -const int LOOP_MAX = __LOOP_MAX__; - -__PLUGINS__; -__CONSTANTS__; - -in vec2 vTexCoord; - -const int BIT_COUNT = 32; -int modi(int x, int y) { - return x - y * (x / y); -} - -int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; -} -int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; -} -int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; - } - } - return result; -} -int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; -} -int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); -} - -int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); -} - -int integerMod(int x, int y) { - return x - (y * int(x/y)); -} - -__DIVIDE_WITH_INTEGER_CHECK__; - -// Here be dragons! -// DO NOT OPTIMIZE THIS CODE -// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE -// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME -const vec2 MAGIC_VEC = vec2(1.0, -256.0); -const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); -const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 -float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; -} - -float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; -} - -float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - return texel[channel] * 255.0; -} - -vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; -} - -// https://github.com/gpujs/gpu.js/wiki/Encoder-details -vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; -} -// Dragons end here - -int index; -ivec3 threadId; - -ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); -} - -float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return decode32(texel); -} - -float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); -} - -float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); -} - -float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - index = index / 4; - vec4 texel = texture(tex, st / vec2(texSize)); - return texel[channel]; -} - -vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, st / vec2(texSize)); -} - -vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, vec3(st / vec2(texSize), z)); -} - -float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; -} - -vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); -} - -vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); -} - -vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); -} - -vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); - } - } -} - -vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); -} - -vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); -} - -vec4 actualColor; -void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); -} - -void color(float r, float g, float b) { - color(r,g,b,1.0); -} - -__INJECTED_NATIVE__; -__MAIN_CONSTANTS__; -__MAIN_ARGUMENTS__; -__KERNEL__; - -void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; -}`; - -module.exports = { - fragmentShader -}; -},{}],70:[function(require,module,exports){ -const { WebGLFunctionNode } = require('../web-gl/function-node'); - -class WebGL2FunctionNode extends WebGLFunctionNode { - - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput( - 'IdentifierExpression - not an Identifier', - idtNode - ); - } - - const type = this.getType(idtNode); - - if (idtNode.name === 'Infinity') { - retArr.push('intBitsToFloat(2139095039)'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${idtNode.name}`); - } - } else { - retArr.push(`user_${idtNode.name}`); - } - - return retArr; - } -} - -module.exports = { - WebGL2FunctionNode -}; -},{"../web-gl/function-node":36}],71:[function(require,module,exports){ -const { WebGL2KernelValueBoolean } = require('./kernel-value/boolean'); -const { WebGL2KernelValueFloat } = require('./kernel-value/float'); -const { WebGL2KernelValueInteger } = require('./kernel-value/integer'); - -const { WebGL2KernelValueHTMLImage } = require('./kernel-value/html-image'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image'); - -const { WebGL2KernelValueHTMLImageArray } = require('./kernel-value/html-image-array'); -const { WebGL2KernelValueDynamicHTMLImageArray } = require('./kernel-value/dynamic-html-image-array'); - -const { WebGL2KernelValueHTMLVideo } = require('./kernel-value/html-video'); -const { WebGL2KernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video'); - -const { WebGL2KernelValueSingleInput } = require('./kernel-value/single-input'); -const { WebGL2KernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input'); - -const { WebGL2KernelValueUnsignedInput } = require('./kernel-value/unsigned-input'); -const { WebGL2KernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input'); - -const { WebGL2KernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture'); -const { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture'); - -const { WebGL2KernelValueNumberTexture } = require('./kernel-value/number-texture'); -const { WebGL2KernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture'); - -const { WebGL2KernelValueSingleArray } = require('./kernel-value/single-array'); -const { WebGL2KernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array'); - -const { WebGL2KernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i'); -const { WebGL2KernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i'); - -const { WebGL2KernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i'); -const { WebGL2KernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i'); - -const { WebGL2KernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i'); -const { WebGL2KernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i'); - -const { WebGL2KernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGL2KernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGL2KernelValueSingleArray4 } = require('./kernel-value/single-array4'); - -const { WebGL2KernelValueUnsignedArray } = require('./kernel-value/unsigned-array'); -const { WebGL2KernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array'); - -const kernelValueMaps = { - unsigned: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGL2KernelValueDynamicUnsignedInput, - 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGL2KernelValueUnsignedInput, - 'NumberTexture': WebGL2KernelValueNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI, - 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI, - 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI, - 'Input': WebGL2KernelValueDynamicSingleInput, - 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - 'Array1D(2)': WebGL2KernelValueSingleArray1DI, - 'Array1D(3)': WebGL2KernelValueSingleArray1DI, - 'Array1D(4)': WebGL2KernelValueSingleArray1DI, - 'Array2D(2)': WebGL2KernelValueSingleArray2DI, - 'Array2D(3)': WebGL2KernelValueSingleArray2DI, - 'Array2D(4)': WebGL2KernelValueSingleArray2DI, - 'Array3D(2)': WebGL2KernelValueSingleArray3DI, - 'Array3D(3)': WebGL2KernelValueSingleArray3DI, - 'Array3D(4)': WebGL2KernelValueSingleArray3DI, - 'Input': WebGL2KernelValueSingleInput, - 'NumberTexture': WebGL2KernelValueNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, -}; - -function lookupKernelValueType(type, dynamic, precision, value) { - if (!type) { - throw new Error('type missing'); - } - if (!dynamic) { - throw new Error('dynamic missing'); - } - if (!precision) { - throw new Error('precision missing'); - } - if (value.type) { - type = value.type; - } - const types = kernelValueMaps[precision][dynamic]; - if (types[type] === false) { - return null; - } else if (types[type] === undefined) { - throw new Error(`Could not find a KernelValue for ${ type }`); - } - return types[type]; -} - -module.exports = { - kernelValueMaps, - lookupKernelValueType -}; -},{"./kernel-value/boolean":72,"./kernel-value/dynamic-html-image":74,"./kernel-value/dynamic-html-image-array":73,"./kernel-value/dynamic-html-video":75,"./kernel-value/dynamic-memory-optimized-number-texture":76,"./kernel-value/dynamic-number-texture":77,"./kernel-value/dynamic-single-array":78,"./kernel-value/dynamic-single-array1d-i":79,"./kernel-value/dynamic-single-array2d-i":80,"./kernel-value/dynamic-single-array3d-i":81,"./kernel-value/dynamic-single-input":82,"./kernel-value/dynamic-unsigned-array":83,"./kernel-value/dynamic-unsigned-input":84,"./kernel-value/float":85,"./kernel-value/html-image":87,"./kernel-value/html-image-array":86,"./kernel-value/html-video":88,"./kernel-value/integer":89,"./kernel-value/memory-optimized-number-texture":90,"./kernel-value/number-texture":91,"./kernel-value/single-array":92,"./kernel-value/single-array1d-i":93,"./kernel-value/single-array2":94,"./kernel-value/single-array2d-i":95,"./kernel-value/single-array3":96,"./kernel-value/single-array3d-i":97,"./kernel-value/single-array4":98,"./kernel-value/single-input":99,"./kernel-value/unsigned-array":100,"./kernel-value/unsigned-input":101}],72:[function(require,module,exports){ -const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean'); - -class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - -module.exports = { - WebGL2KernelValueBoolean -}; -},{"../../web-gl/kernel-value/boolean":38}],73:[function(require,module,exports){ -const { WebGL2KernelValueHTMLImageArray } = require('./html-image-array'); - -class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2DArray ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(images) { - const { width, height } = images[0]; - this.checkSize(width, height); - this.dimensions = [width, height, images.length]; - this.textureSize = [width, height]; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(images); - } -} - -module.exports = { - WebGL2KernelValueDynamicHTMLImageArray -}; -},{"./html-image-array":86}],74:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicHTMLImage } = require('../../web-gl/kernel-value/dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicHTMLImage -}; -},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-html-image":39}],75:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} - -module.exports = { - WebGL2KernelValueDynamicHTMLVideo -}; -},{"../../../utils":111,"./dynamic-html-image":74}],76:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/dynamic-memory-optimized-number-texture'); - -class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicMemoryOptimizedNumberTexture -}; -},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":41}],77:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicNumberTexture } = require('../../web-gl/kernel-value/dynamic-number-texture'); - -class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicNumberTexture -}; -},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-number-texture":42}],78:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray } = require('../../web-gl2/kernel-value/single-array'); - -class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray -}; -},{"../../../utils":111,"../../web-gl2/kernel-value/single-array":92}],79:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray1DI } = require('../../web-gl2/kernel-value/single-array1d-i'); - -class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray1DI -}; -},{"../../../utils":111,"../../web-gl2/kernel-value/single-array1d-i":93}],80:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray2DI } = require('../../web-gl2/kernel-value/single-array2d-i'); - -class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray2DI -}; -},{"../../../utils":111,"../../web-gl2/kernel-value/single-array2d-i":95}],81:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray3DI } = require('../../web-gl2/kernel-value/single-array3d-i'); - -class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray3DI -}; -},{"../../../utils":111,"../../web-gl2/kernel-value/single-array3d-i":97}],82:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleInput } = require('../../web-gl2/kernel-value/single-input'); - -class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleInput -}; -},{"../../../utils":111,"../../web-gl2/kernel-value/single-input":99}],83:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicUnsignedArray } = require('../../web-gl/kernel-value/dynamic-unsigned-array'); - -class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicUnsignedArray -}; -},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-unsigned-array":48}],84:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicUnsignedInput } = require('../../web-gl/kernel-value/dynamic-unsigned-input'); - -class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicUnsignedInput -}; -},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-unsigned-input":49}],85:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueFloat } = require('../../web-gl/kernel-value/float'); - -class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - -module.exports = { - WebGL2KernelValueFloat -}; -},{"../../../utils":111,"../../web-gl/kernel-value/float":50}],86:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('../../web-gl/kernel-value/index'); - -class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.checkSize(value[0].width, value[0].height); - this.requestTexture(); - this.dimensions = [value[0].width, value[0].height, value.length]; - this.textureSize = [value[0].width, value[0].height]; - } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2DArray ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(images) { - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - gl.texImage3D( - gl.TEXTURE_2D_ARRAY, - 0, - gl.RGBA, - images[0].width, - images[0].height, - images.length, - 0, - gl.RGBA, - gl.UNSIGNED_BYTE, - null - ); - for (let i = 0; i < images.length; i++) { - const xOffset = 0; - const yOffset = 0; - const imageDepth = 1; - gl.texSubImage3D( - gl.TEXTURE_2D_ARRAY, - 0, - xOffset, - yOffset, - i, - images[i].width, - images[i].height, - imageDepth, - gl.RGBA, - gl.UNSIGNED_BYTE, - this.uploadValue = images[i] - ); + switch (bitRatio) { + case 1: + retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + case 2: + retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + case 4: + case 0: + retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + default: + throw new Error(`unhandled bit ratio of ${bitRatio}`); + } + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + } + break; + case 'MemoryOptimizedNumberTexture': + retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + default: + throw new Error(`unhandled member expression "${ type }"`); + } + return retArr; } - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueHTMLImageArray -}; -},{"../../../utils":111,"../../web-gl/kernel-value/index":53}],87:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('../../web-gl/kernel-value/html-image'); - -class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueHTMLImage -}; -},{"../../../utils":111,"../../web-gl/kernel-value/html-image":51}],88:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueHTMLImage } = require('./html-image'); - -class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} - -module.exports = { - WebGL2KernelValueHTMLVideo -}; -},{"../../../utils":111,"./html-image":87}],89:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueInteger } = require('../../web-gl/kernel-value/integer'); - -class WebGL2KernelValueInteger extends WebGLKernelValueInteger { - getSource(value) { - const variablePrecision = this.getVariablePrecisionString(); - if (this.origin === 'constants') { - return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`; + astCallExpression(ast, retArr) { + if (!ast.callee) { + throw this.astErrorOutput('Unknown CallExpression', ast); + } + let functionName = null; + const isMathFunction = this.isAstMathFunction(ast); + if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) { + functionName = ast.callee.property.name; + } + else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) { + functionName = ast.callee.expressions[1].property.name; + } else { + functionName = ast.callee.name; + } + if (!functionName) { + throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); + } + if (functionName === 'atan2') { + functionName = 'atan'; + } + if (this.calledFunctions.indexOf(functionName) < 0) { + this.calledFunctions.push(functionName); + } + if (functionName === 'random' && this.plugins && this.plugins.length > 0) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) { + retArr.push(plugin.functionReplace); + return retArr; + } + } + } + if (this.onFunctionCall) { + this.onFunctionCall(this.name, functionName, ast.arguments); + } + retArr.push(functionName); + retArr.push('('); + if (isMathFunction) { + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + const argumentType = this.getType(argument); + if (i > 0) { + retArr.push(', '); + } + switch (argumentType) { + case 'Integer': + this.castValueToFloat(argument, retArr); + break; + default: + this.astGeneric(argument, retArr); + break; + } + } + } else { + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + let targetType = targetTypes[i]; + if (i > 0) { + retArr.push(', '); + } + const argumentType = this.getType(argument); + if (!targetType) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); + targetType = argumentType; + } + switch (argumentType) { + case 'Number': + case 'Float': + if (targetType === 'Integer') { + retArr.push('int('); + this.astGeneric(argument, retArr); + retArr.push(')'); + continue; + } else if (targetType === 'Number' || targetType === 'Float') { + this.astGeneric(argument, retArr); + continue; + } else if (targetType === 'LiteralInteger') { + this.castLiteralToFloat(argument, retArr); + continue; + } + break; + case 'Integer': + if (targetType === 'Number' || targetType === 'Float') { + retArr.push('float('); + this.astGeneric(argument, retArr); + retArr.push(')'); + continue; + } else if (targetType === 'Integer') { + this.astGeneric(argument, retArr); + continue; + } + break; + case 'LiteralInteger': + if (targetType === 'Integer') { + this.castLiteralToInteger(argument, retArr); + continue; + } else if (targetType === 'Number' || targetType === 'Float') { + this.castLiteralToFloat(argument, retArr); + continue; + } else if (targetType === 'LiteralInteger') { + this.astGeneric(argument, retArr); + continue; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + if (targetType === argumentType) { + if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name}`); + continue; + } + break; + case 'HTMLImage': + case 'HTMLImageArray': + case 'HTMLVideo': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'Array': + case 'Input': + if (targetType === argumentType) { + if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); + continue; + } + break; + } + throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); + } + } + retArr.push(')'); + return retArr; } - return `uniform ${ variablePrecision } int ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGL2KernelValueInteger -}; -},{"../../../utils":111,"../../web-gl/kernel-value/integer":54}],90:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/memory-optimized-number-texture'); - -class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { - getSource() { - const { id, sizeId, textureSize, dimensionsId, dimensions } = this; - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform sampler2D ${id}`, - `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, - `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueMemoryOptimizedNumberTexture -}; -},{"../../../utils":111,"../../web-gl/kernel-value/memory-optimized-number-texture":55}],91:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueNumberTexture } = require('../../web-gl/kernel-value/number-texture'); + astArrayExpression(arrNode, retArr) { + const arrLen = arrNode.elements.length; + retArr.push('vec' + arrLen + '('); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + this.astGeneric(subNode, retArr); + } + retArr.push(')'); + return retArr; + } + memberExpressionXYZ(x, y, z, retArr) { + if (z) { + retArr.push(this.memberExpressionPropertyMarkup(z), ', '); + } else { + retArr.push('0, '); + } + if (y) { + retArr.push(this.memberExpressionPropertyMarkup(y), ', '); + } else { + retArr.push('0, '); + } + retArr.push(this.memberExpressionPropertyMarkup(x)); + return retArr; + } + memberExpressionPropertyMarkup(property) { + if (!property) { + throw new Error('Property not set'); + } + const type = this.getType(property); + const result = []; + switch (type) { + case 'Number': + case 'Float': + this.castValueToInteger(property, result); + break; + case 'LiteralInteger': + this.castLiteralToInteger(property, result); + break; + default: + this.astGeneric(property, result); + } + return result.join(''); + } + } + const typeMap$2 = { + 'Array': 'sampler2D', + 'Array(2)': 'vec2', + 'Array(3)': 'vec3', + 'Array(4)': 'vec4', + 'Array2D': 'sampler2D', + 'Array3D': 'sampler2D', + 'Boolean': 'bool', + 'Float': 'float', + 'Input': 'sampler2D', + 'Integer': 'int', + 'Number': 'float', + 'LiteralInteger': 'float', + 'NumberTexture': 'sampler2D', + 'MemoryOptimizedNumberTexture': 'sampler2D', + 'ArrayTexture(1)': 'sampler2D', + 'ArrayTexture(2)': 'sampler2D', + 'ArrayTexture(3)': 'sampler2D', + 'ArrayTexture(4)': 'sampler2D', + 'HTMLVideo': 'sampler2D', + 'HTMLImage': 'sampler2D', + 'HTMLImageArray': 'sampler2DArray', + }; + const operatorMap = { + '===': '==', + '!==': '!=' + }; -class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture { - getSource() { - const { id, sizeId, textureSize, dimensionsId, dimensions } = this; - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${id}`, - `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, - `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, - ]); - } -} + const source = ` + +uniform highp float triangle_noise_seed; +highp float triangle_noise_shift = 0.000001; + +//https://www.shadertoy.com/view/4t2SDh +//note: uniformly distributed, normalized rand, [0;1[ +float nrand( vec2 n ) +{ + return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); +} +//note: remaps v to [0;1] in interval [a;b] +float remap( float a, float b, float v ) +{ + return clamp( (v-a) / (b-a), 0.0, 1.0 ); +} + +float n4rand( vec2 n ) +{ + float t = fract( triangle_noise_seed + triangle_noise_shift ); + float nrnd0 = nrand( n + 0.07*t ); + float nrnd1 = nrand( n + 0.11*t ); + float nrnd2 = nrand( n + 0.13*t ); + float nrnd3 = nrand( n + 0.17*t ); + float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; + triangle_noise_shift = result + 0.000001; + return result; +}`; + const name$1 = 'triangle-noise-noise'; + const functionMatch = 'Math.random()'; + const functionReplace = 'n4rand(vTexCoord)'; + const functionReturnType = 'Number'; + const onBeforeRun = (kernel) => { + kernel.setUniform1f('triangle_noise_seed', Math.random()); + }; + var triangleNoise = { + name: name$1, + onBeforeRun, + functionMatch, + functionReplace, + functionReturnType, + source + }; -module.exports = { - WebGL2KernelValueNumberTexture -}; -},{"../../../utils":111,"../../web-gl/kernel-value/number-texture":56}],92:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray } = require('../../web-gl/kernel-value/single-array'); + const fragmentShader = `__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +varying vec2 vTexCoord; + +vec4 round(vec4 x) { + return floor(x + 0.5); +} + +float round(float x) { + return floor(x + 0.5); +} + +const int BIT_COUNT = 32; +int modi(int x, int y) { + return x - y * (x / y); +} + +int bitwiseOr(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseXOR(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseAnd(int a, int b) { + int result = 0; + int n = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 && b > 0)) { + break; + } + } + return result; +} +int bitwiseNot(int a) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if (modi(a, 2) == 0) { + result += n; + } + a = a / 2; + n = n * 2; + } + return result; +} +int bitwiseZeroFillLeftShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n *= 2; + } + + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +int bitwiseSignedRightShift(int num, int shifts) { + return int(floor(float(num) / pow(2.0, float(shifts)))); +} + +int bitwiseZeroFillRightShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n /= 2; + } + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +vec2 integerMod(vec2 x, float y) { + vec2 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec3 integerMod(vec3 x, float y) { + vec3 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec4 integerMod(vec4 x, vec4 y) { + vec4 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +float integerMod(float x, float y) { + float res = floor(mod(x, y)); + return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); +} + +int integerMod(int x, int y) { + return x - (y * int(x / y)); +} + +__DIVIDE_WITH_INTEGER_CHECK__; + +// Here be dragons! +// DO NOT OPTIMIZE THIS CODE +// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE +// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME +const vec2 MAGIC_VEC = vec2(1.0, -256.0); +const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); +const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 +float decode32(vec4 texel) { + __DECODE32_ENDIANNESS__; + texel *= 255.0; + vec2 gte128; + gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; + gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; + float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); + float res = exp2(round(exponent)); + texel.b = texel.b - 128.0 * gte128.x; + res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; + res *= gte128.y * -2.0 + 1.0; + return res; +} + +float decode16(vec4 texel, int index) { + int channel = integerMod(index, 2); + if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; + if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; + return 0.0; +} + +float decode8(vec4 texel, int index) { + int channel = integerMod(index, 4); + if (channel == 0) return texel.r * 255.0; + if (channel == 1) return texel.g * 255.0; + if (channel == 2) return texel.b * 255.0; + if (channel == 3) return texel.a * 255.0; + return 0.0; +} + +vec4 legacyEncode32(float f) { + float F = abs(f); + float sign = f < 0.0 ? 1.0 : 0.0; + float exponent = floor(log2(F)); + float mantissa = (exp2(-exponent) * F); + // exponent += floor(log2(mantissa)); + vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; + texel.rg = integerMod(texel.rg, 256.0); + texel.b = integerMod(texel.b, 128.0); + texel.a = exponent*0.5 + 63.5; + texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; + texel = floor(texel); + texel *= 0.003921569; // 1/255 + __ENCODE32_ENDIANNESS__; + return texel; +} + +// https://github.com/gpujs/gpu.js/wiki/Encoder-details +vec4 encode32(float value) { + if (value == 0.0) return vec4(0, 0, 0, 0); + + float exponent; + float mantissa; + vec4 result; + float sgn; + + sgn = step(0.0, -value); + value = abs(value); + + exponent = floor(log2(value)); + + mantissa = value*pow(2.0, -exponent)-1.0; + exponent = exponent+127.0; + result = vec4(0,0,0,0); + + result.a = floor(exponent/2.0); + exponent = exponent - result.a*2.0; + result.a = result.a + 128.0*sgn; + + result.b = floor(mantissa * 128.0); + mantissa = mantissa - result.b / 128.0; + result.b = result.b + exponent*128.0; + + result.g = floor(mantissa*32768.0); + mantissa = mantissa - result.g/32768.0; + + result.r = floor(mantissa*8388608.0); + return result/255.0; +} +// Dragons end here + +int index; +ivec3 threadId; + +ivec3 indexTo3D(int idx, ivec3 texDim) { + int z = int(idx / (texDim.x * texDim.y)); + idx -= z * int(texDim.x * texDim.y); + int y = int(idx / texDim.x); + int x = int(integerMod(idx, texDim.x)); + return ivec3(x, y, z); +} + +float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + return decode32(texel); +} + +float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x * 2; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); + return decode16(texel, index); +} + +float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x * 4; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); + return decode8(texel, index); +} + +float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 4); + index = index / 4; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + if (channel == 0) return texel.r; + if (channel == 1) return texel.g; + if (channel == 2) return texel.b; + if (channel == 3) return texel.a; + return 0.0; +} + +vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture2D(tex, st / vec2(texSize)); +} + +float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return result[0]; +} + +vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec2(result[0], result[1]); +} + +vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int channel = integerMod(index, 2); + index = index / 2; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + if (channel == 0) return vec2(texel.r, texel.g); + if (channel == 1) return vec2(texel.b, texel.a); + return vec2(0.0, 0.0); +} + +vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec3(result[0], result[1], result[2]); +} + +vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); + int vectorIndex = fieldIndex / 4; + int vectorOffset = fieldIndex - vectorIndex * 4; + int readY = vectorIndex / texSize.x; + int readX = vectorIndex - readY * texSize.x; + vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); + + if (vectorOffset == 0) { + return tex1.xyz; + } else if (vectorOffset == 1) { + return tex1.yzw; + } else { + readX++; + if (readX >= texSize.x) { + readX = 0; + readY++; + } + vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); + if (vectorOffset == 2) { + return vec3(tex1.z, tex1.w, tex2.x); + } else { + return vec3(tex1.w, tex2.x, tex2.y); + } + } +} + +vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + return getImage2D(tex, texSize, texDim, z, y, x); +} + +vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + return vec4(texel.r, texel.g, texel.b, texel.a); +} + +vec4 actualColor; +void color(float r, float g, float b, float a) { + actualColor = vec4(r,g,b,a); +} + +void color(float r, float g, float b) { + color(r,g,b,1.0); +} + +void color(sampler2D image) { + actualColor = texture2D(image, vTexCoord); +} + +__INJECTED_NATIVE__; +__MAIN_CONSTANTS__; +__MAIN_ARGUMENTS__; +__KERNEL__; + +void main(void) { + index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; + __MAIN_RESULT__; +}`; -class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } + const vertexShader = `__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +attribute vec2 aPos; +attribute vec2 aTexCoord; + +varying vec2 vTexCoord; +uniform vec2 ratio; + +void main(void) { + gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); + vTexCoord = aTexCoord; +}`; - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; } -} - -module.exports = { - WebGL2KernelValueSingleArray -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-array":57}],93:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray1DI } = require('../../web-gl/kernel-value/single-array1d-i'); -class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); + var glWiretap_1 = createCommonjsModule(function (module) { + function glWiretap(gl, options = {}) { + const { + contextName = 'gl', + throwGetError, + useTrackablePrimitives, + readPixelsFile, + recording = [], + variables = {}, + onReadPixels, + onUnrecognizedArgumentLookup, + } = options; + const proxy = new Proxy(gl, { get: listen }); + const contextVariables = []; + const entityNames = {}; + let imageCount = 0; + let indent = ''; + let readPixelsVariableName; + return proxy; + function listen(obj, property) { + switch (property) { + case 'addComment': return addComment; + case 'checkThrowError': return checkThrowError; + case 'getReadPixelsVariableName': return readPixelsVariableName; + case 'insertVariable': return insertVariable; + case 'reset': return reset; + case 'setIndent': return setIndent; + case 'toString': return toString; + case 'getContextVariableName': return getContextVariableName; + } + if (typeof gl[property] === 'function') { + return function() { + switch (property) { + case 'getError': + if (throwGetError) { + recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`); + } else { + recording.push(`${indent}${contextName}.getError();`); + } + return gl.getError(); + case 'getExtension': { + const variableName = `${contextName}Variables${contextVariables.length}`; + recording.push(`${indent}const ${variableName} = ${contextName}.getExtension('${arguments[0]}');`); + const extension = gl.getExtension(arguments[0]); + if (extension && typeof extension === 'object') { + const tappedExtension = glExtensionWiretap(extension, { + getEntity, + useTrackablePrimitives, + recording, + contextName: variableName, + contextVariables, + variables, + indent, + onUnrecognizedArgumentLookup, + }); + contextVariables.push(tappedExtension); + return tappedExtension; + } else { + contextVariables.push(null); + } + return extension; + } + case 'readPixels': + const i = contextVariables.indexOf(arguments[6]); + let targetVariableName; + if (i === -1) { + const variableName = getVariableName(arguments[6]); + if (variableName) { + targetVariableName = variableName; + recording.push(`${indent}${variableName}`); + } else { + targetVariableName = `${contextName}Variable${contextVariables.length}`; + contextVariables.push(arguments[6]); + recording.push(`${indent}const ${targetVariableName} = new ${arguments[6].constructor.name}(${arguments[6].length});`); + } + } else { + targetVariableName = `${contextName}Variable${i}`; + } + readPixelsVariableName = targetVariableName; + const argumentAsStrings = [ + arguments[0], + arguments[1], + arguments[2], + arguments[3], + getEntity(arguments[4]), + getEntity(arguments[5]), + targetVariableName + ]; + recording.push(`${indent}${contextName}.readPixels(${argumentAsStrings.join(', ')});`); + if (readPixelsFile) { + writePPM(arguments[2], arguments[3]); + } + if (onReadPixels) { + onReadPixels(targetVariableName, argumentAsStrings); + } + return gl.readPixels.apply(gl, arguments); + case 'drawBuffers': + recording.push(`${indent}${contextName}.drawBuffers([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup } )}]);`); + return gl.drawBuffers(arguments[0]); + } + let result = gl[property].apply(gl, arguments); + switch (typeof result) { + case 'undefined': + recording.push(`${indent}${methodCallToString(property, arguments)};`); + return; + case 'number': + case 'boolean': + if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + contextVariables.push(result = trackablePrimitive(result)); + break; + } + default: + if (result === null) { + recording.push(`${methodCallToString(property, arguments)};`); + } else { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + } + contextVariables.push(result); + } + return result; + } + } + entityNames[gl[property]] = property; + return gl[property]; + } + function toString() { + return recording.join('\n'); + } + function reset() { + while (recording.length > 0) { + recording.pop(); + } + } + function insertVariable(name, value) { + variables[name] = value; + } + function getEntity(value) { + const name = entityNames[value]; + if (name) { + return contextName + '.' + name; + } + return value; + } + function setIndent(spaces) { + indent = ' '.repeat(spaces); + } + function addVariable(value, source) { + const variableName = `${contextName}Variable${contextVariables.length}`; + recording.push(`${indent}const ${variableName} = ${source};`); + contextVariables.push(value); + return variableName; + } + function writePPM(width, height) { + const sourceVariable = `${contextName}Variable${contextVariables.length}`; + const imageVariable = `imageDatum${imageCount}`; + recording.push(`${indent}let ${imageVariable} = ["P3\\n# ${readPixelsFile}.ppm\\n", ${width}, ' ', ${height}, "\\n255\\n"].join("");`); + recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`); + recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`); + recording.push(`${indent}}`); + recording.push(`${indent}if (typeof require !== "undefined") {`); + recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`); + recording.push(`${indent}}`); + imageCount++; + } + function addComment(value) { + recording.push(`${indent}// ${value}`); + } + function checkThrowError() { + recording.push(`${indent}(() => { +${indent}const error = ${contextName}.getError(); +${indent}if (error !== ${contextName}.NONE) { +${indent} const names = Object.getOwnPropertyNames(gl); +${indent} for (let i = 0; i < names.length; i++) { +${indent} const name = names[i]; +${indent} if (${contextName}[name] === error) { +${indent} throw new Error('${contextName} threw ' + name); +${indent} } +${indent} } +${indent}} +${indent}})();`); + } + function methodCallToString(method, args) { + return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; + } + function getVariableName(value) { + if (variables) { + for (const name in variables) { + if (variables[name] === value) { + return name; + } + } + } + return null; + } + function getContextVariableName(value) { + const i = contextVariables.indexOf(value); + if (i !== -1) { + return `${contextName}Variable${i}`; + } + return null; + } } -} - -module.exports = { - WebGL2KernelValueSingleArray1DI -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-array1d-i":58}],94:[function(require,module,exports){ -const { WebGLKernelValueSingleArray2 } = require('../../web-gl/kernel-value/single-array2'); - -class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} - -module.exports = { - WebGL2KernelValueSingleArray2 -}; -},{"../../web-gl/kernel-value/single-array2":59}],95:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray2DI } = require('../../web-gl/kernel-value/single-array2d-i'); - -class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); + function glExtensionWiretap(extension, options) { + const proxy = new Proxy(extension, { get: listen }); + const extensionEntityNames = {}; + const { + contextName, + contextVariables, + getEntity, + useTrackablePrimitives, + recording, + variables, + indent, + onUnrecognizedArgumentLookup, + } = options; + return proxy; + function listen(obj, property) { + if (typeof obj[property] === 'function') { + return function() { + switch (property) { + case 'drawBuffersWEBGL': + recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`); + return extension.drawBuffersWEBGL(arguments[0]); + } + let result = extension[property].apply(extension, arguments); + switch (typeof result) { + case 'undefined': + recording.push(`${indent}${methodCallToString(property, arguments)};`); + return; + case 'number': + case 'boolean': + if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + contextVariables.push(result = trackablePrimitive(result)); + } else { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + contextVariables.push(result); + } + break; + default: + if (result === null) { + recording.push(`${methodCallToString(property, arguments)};`); + } else { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + } + contextVariables.push(result); + } + return result; + }; + } + extensionEntityNames[extension[property]] = property; + return extension[property]; + } + function getExtensionEntity(value) { + if (extensionEntityNames.hasOwnProperty(value)) { + return `${contextName}.${extensionEntityNames[value]}`; + } + return getEntity(value); + } + function methodCallToString(method, args) { + return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; + } + function addVariable(value, source) { + const variableName = `${contextName}Variable${contextVariables.length}`; + contextVariables.push(value); + recording.push(`${indent}const ${variableName} = ${source};`); + return variableName; + } } -} - -module.exports = { - WebGL2KernelValueSingleArray2DI -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-array2d-i":60}],96:[function(require,module,exports){ -const { WebGLKernelValueSingleArray3 } = require('../../web-gl/kernel-value/single-array3'); - -class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} - -module.exports = { - WebGL2KernelValueSingleArray3 -}; -},{"../../web-gl/kernel-value/single-array3":61}],97:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray3DI } = require('../../web-gl/kernel-value/single-array3d-i'); - -class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); + function argumentsToString(args, options) { + const { variables, onUnrecognizedArgumentLookup } = options; + return (Array.from(args).map((arg) => { + const variableName = getVariableName(arg); + if (variableName) { + return variableName; + } + return argumentToString(arg, options); + }).join(', ')); + function getVariableName(value) { + if (variables) { + for (const name in variables) { + if (!variables.hasOwnProperty(name)) continue; + if (variables[name] === value) { + return name; + } + } + } + if (onUnrecognizedArgumentLookup) { + return onUnrecognizedArgumentLookup(value); + } + return null; + } } -} - -module.exports = { - WebGL2KernelValueSingleArray3DI -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-array3d-i":62}],98:[function(require,module,exports){ -const { WebGLKernelValueSingleArray4 } = require('../../web-gl/kernel-value/single-array4'); - -class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} - -module.exports = { - WebGL2KernelValueSingleArray4 -}; -},{"../../web-gl/kernel-value/single-array4":63}],99:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleInput } = require('../../web-gl/kernel-value/single-input'); - -class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); + function argumentToString(arg, options) { + const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options; + if (typeof arg === 'undefined') { + return 'undefined'; + } + if (arg === null) { + return 'null'; + } + const i = contextVariables.indexOf(arg); + if (i > -1) { + return `${contextName}Variable${i}`; + } + switch (arg.constructor.name) { + case 'String': + const hasLines = /\n/.test(arg); + const hasSingleQuotes = /'/.test(arg); + const hasDoubleQuotes = /"/.test(arg); + if (hasLines) { + return '`' + arg + '`'; + } else if (hasSingleQuotes && !hasDoubleQuotes) { + return '"' + arg + '"'; + } else if (!hasSingleQuotes && hasDoubleQuotes) { + return "'" + arg + "'"; + } else { + return '\'' + arg + '\''; + } + case 'Number': return getEntity(arg); + case 'Boolean': return getEntity(arg); + case 'Array': + return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`); + case 'Float32Array': + case 'Uint8Array': + case 'Uint16Array': + case 'Int32Array': + return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`); + default: + if (onUnrecognizedArgumentLookup) { + const instantiationString = onUnrecognizedArgumentLookup(arg); + if (instantiationString) { + return instantiationString; + } + } + throw new Error(`unrecognized argument type ${arg.constructor.name}`); + } } - - updateValue(input) { - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); + function trackablePrimitive(value) { + return new value.constructor(value); } -} - -module.exports = { - WebGL2KernelValueSingleInput -}; -},{"../../../utils":111,"../../web-gl/kernel-value/single-input":64}],100:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedArray } = require('../../web-gl/kernel-value/unsigned-array'); - -class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); + { + module.exports = { glWiretap, glExtensionWiretap }; } -} - -module.exports = { - WebGL2KernelValueUnsignedArray -}; -},{"../../../utils":111,"../../web-gl/kernel-value/unsigned-array":65}],101:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedInput } = require('../../web-gl/kernel-value/unsigned-input'); - -class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); + if (typeof window !== 'undefined') { + glWiretap.glExtensionWiretap = glExtensionWiretap; + window.glWiretap = glWiretap; } -} - -module.exports = { - WebGL2KernelValueUnsignedInput -}; -},{"../../../utils":111,"../../web-gl/kernel-value/unsigned-input":66}],102:[function(require,module,exports){ -const { WebGLKernel } = require('../web-gl/kernel'); -const { WebGL2FunctionNode } = require('./function-node'); -const { FunctionBuilder } = require('../function-builder'); -const { utils } = require('../../utils'); -const { fragmentShader } = require('./fragment-shader'); -const { vertexShader } = require('./vertex-shader'); -const { lookupKernelValueType } = require('./kernel-value-maps'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; - -let features = null; - -class WebGL2Kernel extends WebGLKernel { - static get isSupported() { - if (isSupported !== null) { - return isSupported; + }); + var glWiretap_2 = glWiretap_1.glWiretap; + var glWiretap_3 = glWiretap_1.glExtensionWiretap; + + function toStringWithoutUtils(fn) { + return fn.toString() + .replace('=>', '') + .replace(/^function /, '') + .replace(/utils[.]/g, '/*utils.*/'); + } + function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { + args = args ? Array.from(args).map(arg => { + switch (typeof arg) { + case 'boolean': + return new Boolean(arg); + case 'number': + return new Number(arg); + default: + return arg; + } + }) : null; + const postResult = []; + const context = glWiretap_2(originKernel.context, { + useTrackablePrimitives: true, + onReadPixels: (targetName) => { + if (kernel.subKernels) { + if (!subKernelsResultVariableSetup) { + postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`); + subKernelsResultVariableSetup = true; + } else { + const property = kernel.subKernels[subKernelsResultIndex++].property; + postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`); + } + if (subKernelsResultIndex === kernel.subKernels.length) { + postResult.push(' return result;'); + } + return; + } + if (targetName) { + postResult.push(` return ${getRenderString(targetName, kernel)};`); + } else { + postResult.push(` return null;`); + } + }, + onUnrecognizedArgumentLookup: (argument) => { + const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context); + if (argumentName) { + return argumentName; + } + const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context); + if (constantName) { + return constantName; + } + return null; + } + }); + let subKernelsResultVariableSetup = false; + let subKernelsResultIndex = 0; + const { + source, + canvas, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + kernelArguments, + kernelConstants, + } = originKernel; + const kernel = new Kernel(source, { + canvas, + context, + checkContext: false, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + }); + let result = []; + context.setIndent(2); + kernel.build.apply(kernel, args); + result.push(context.toString()); + context.reset(); + kernel.kernelArguments.forEach((kernelArgument, i) => { + switch (kernelArgument.type) { + case 'Integer': + case 'Boolean': + case 'Number': + case 'Float': + case 'Array': + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + case 'HTMLImage': + case 'HTMLVideo': + context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); + break; + case 'HTMLImageArray': + for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) { + const arg = args[i]; + context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]); + } + break; + case 'Input': + context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); + break; + case 'MemoryOptimizedNumberTexture': + case 'NumberTexture': + case 'Array1D(2)': + case 'Array1D(3)': + case 'Array1D(4)': + case 'Array2D(2)': + case 'Array2D(3)': + case 'Array2D(4)': + case 'Array3D(2)': + case 'Array3D(3)': + case 'Array3D(4)': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture); + break; + default: + throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`); + } + }); + result.push('/** start of injected functions **/'); + result.push(`function ${toStringWithoutUtils(utils$1.flattenTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten2dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten3dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten4dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.isArray)}`); + if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) { + result.push( + ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};` + ); } - this.setupFeatureChecks(); - isSupported = this.isContextMatch(testContext); - return isSupported; - } - - static setupFeatureChecks() { - if (typeof document !== 'undefined') { - testCanvas = document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - testCanvas = new OffscreenCanvas(0, 0); - } - if (!testCanvas) return; - testContext = testCanvas.getContext('webgl2'); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - }; - features = this.getFeatures(); + result.push('/** end of injected functions **/'); + result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`); + context.setIndent(4); + kernel.run.apply(kernel, args); + if (kernel.renderKernels) { + kernel.renderKernels(); + } else if (kernel.renderOutput) { + kernel.renderOutput(); + } + result.push(' /** start setup uploads for kernel values **/'); + kernel.kernelArguments.forEach(kernelArgument => { + result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n ')); + }); + result.push(' /** end setup uploads for kernel values **/'); + result.push(context.toString()); + if (kernel.renderOutput === kernel.renderTexture) { + context.reset(); + const results = kernel.renderKernels(); + const textureName = context.getContextVariableName(kernel.outputTexture); + result.push(` return { + result: { + texture: ${ textureName }, + type: '${ results.result.type }', + toArray: ${ getToArrayString(results.result, textureName) } + },`); + const { subKernels, subKernelOutputTextures } = kernel; + for (let i = 0; i < subKernels.length; i++) { + const texture = subKernelOutputTextures[i]; + const subKernel = subKernels[i]; + const subKernelResult = results[subKernel.property]; + const subKernelTextureName = context.getContextVariableName(texture); + result.push(` + ${subKernel.property}: { + texture: ${ subKernelTextureName }, + type: '${ subKernelResult.type }', + toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } + },`); + } + result.push(` };`); + } + result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`); + result.push(postResult.join('\n')); + result.push(' };'); + if (kernel.graphical) { + result.push(getGetPixelsString(kernel)); + result.push(` innerKernel.getPixels = getPixels;`); + } + result.push(' return innerKernel;'); + let constantsUpload = []; + kernelConstants.forEach((kernelConstant) => { + constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`); + }); + return `function kernel(settings) { + const { context, constants } = settings; + ${constantsUpload.join('')} + ${setupContextString ? setupContextString : ''} +${result.join('\n')} +}`; } - - static isContextMatch(context) { - if (typeof WebGL2RenderingContext !== 'undefined') { - return context instanceof WebGL2RenderingContext; + function getRenderString(targetName, kernel) { + const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`; + if (kernel.output[2]) { + return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`; } - return false; + if (kernel.output[1]) { + return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`; + } + return `renderOutput(${readBackValue}, ${kernel.output[0]})`; } - - static getFeatures() { - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - kernelMap: true, - isTextureFloat: true, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), + function getGetPixelsString(kernel) { + const getPixels = kernel.getPixels.toString(); + const useFunctionKeyword = !/^function/.test(getPixels); + return utils$1.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils$1[name].toString()};`; + } + return null; + }, + thisLookup: (property) => { + if (property === 'context') { + return null; + } + if (kernel.hasOwnProperty(property)) { + return JSON.stringify(kernel[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } }); } - - static getIsTextureFloat() { - return true; + function getToArrayString(kernelResult, textureName) { + const toArray = kernelResult.toArray.toString(); + const useFunctionKeyword = !/^function/.test(toArray); + const flattenedFunctions = utils$1.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils$1[name].toString()};`; + } else if (object === 'this') { + return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + } else { + throw new Error('unhandled fromObject'); + } + }, + thisLookup: (property) => { + if (property === 'texture') { + return textureName; + } + if (kernelResult.hasOwnProperty(property)) { + return JSON.stringify(kernelResult[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } + }); + return `() => { + ${flattenedFunctions} + return toArray(); + }`; } - - static getIsIntegerDivisionAccurate() { - return super.getIsIntegerDivisionAccurate(); + function findKernelValue(argument, kernelValues, values, context, uploadedValues) { + if (argument === null) return null; + switch (typeof argument) { + case 'boolean': + case 'number': + return null; + } + if ( + typeof HTMLImageElement !== 'undefined' && + argument instanceof HTMLImageElement + ) { + for (let i = 0; i < kernelValues.length; i++) { + const kernelValue = kernelValues[i]; + if (kernelValue.type !== 'HTMLImageArray') continue; + if (kernelValue.uploadValue !== argument) continue; + const variableIndex = values[i].indexOf(argument); + if (variableIndex === -1) continue; + const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`; + context.insertVariable(variableName, argument); + return variableName; + } + return null; + } + for (let i = 0; i < kernelValues.length; i++) { + const kernelValue = kernelValues[i]; + if (argument !== kernelValue.uploadValue) continue; + const variable = `uploadValue_${kernelValue.name}`; + context.insertVariable(variable, kernelValue); + return variable; + } + return null; } - static getChannelCount() { - return testContext.getParameter(testContext.MAX_DRAW_BUFFERS); + class KernelValue { + constructor(value, settings) { + const { + name, + kernel, + context, + checkContext, + onRequestContextHandle, + onUpdateValueMismatch, + origin, + strictIntegers, + type, + tactic, + } = settings; + if (!name) { + throw new Error('name not set'); + } + if (!type) { + throw new Error('type not set'); + } + if (!origin) { + throw new Error('origin not set'); + } + if (!tactic) { + throw new Error('tactic not set'); + } + if (origin !== 'user' && origin !== 'constants') { + throw new Error(`origin must be "user" or "constants" value is "${ origin }"`); + } + if (!onRequestContextHandle) { + throw new Error('onRequestContextHandle is not set'); + } + this.name = name; + this.origin = origin; + this.tactic = tactic; + this.id = `${this.origin}_${name}`; + this.varName = origin === 'constants' ? `constants.${name}` : name; + this.kernel = kernel; + this.strictIntegers = strictIntegers; + this.type = value.type || type; + this.size = value.size || null; + this.index = null; + this.context = context; + this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true; + this.contextHandle = null; + this.onRequestContextHandle = onRequestContextHandle; + this.onUpdateValueMismatch = onUpdateValueMismatch; + this.forceUploadEachRun = null; + } + getSource() { + throw new Error(`"getSource" not defined on ${ this.constructor.name }`); + } + updateValue(value) { + throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); + } + } + + class WebGLKernelValue extends KernelValue { + constructor(value, settings) { + super(value, settings); + this.dimensionsId = null; + this.sizeId = null; + this.initialValueConstructor = value.constructor; + this.onRequestTexture = settings.onRequestTexture; + this.onRequestIndex = settings.onRequestIndex; + this.uploadValue = null; + this.textureSize = null; + this.bitRatio = null; + } + checkSize(width, height) { + if (!this.kernel.validate) return; + const { maxTextureSize } = this.kernel.constructor.features; + if (width > maxTextureSize || height > maxTextureSize) { + if (width > height) { + throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); + } else { + throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); + } + } + } + requestTexture() { + this.texture = this.onRequestTexture(); + this.setupTexture(); + } + setupTexture() { + this.contextHandle = this.onRequestContextHandle(); + this.index = this.onRequestIndex(); + this.dimensionsId = this.id + 'Dim'; + this.sizeId = this.id + 'Size'; + } + getTransferArrayType(value) { + if (Array.isArray(value[0])) { + return this.getTransferArrayType(value[0]); + } + switch (value.constructor) { + case Array: + case Int32Array: + case Int16Array: + case Int8Array: + return Float32Array; + case Uint8ClampedArray: + case Uint8Array: + case Uint16Array: + case Uint32Array: + case Float32Array: + case Float64Array: + return value.constructor; + } + console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros'); + return value.constructor; + } + formatArrayTransfer(value, length, Type) { + if (utils$1.isArray(value[0]) || this.optimizeFloatMemory) { + const valuesFlat = new Float32Array(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } else { + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + case Uint16Array: + case Int16Array: + case Float32Array: + case Int32Array: { + const valuesFlat = new(Type || value.constructor)(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } + default: { + const valuesFlat = new Float32Array(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } + } + } + } + getBitRatio(value) { + if (Array.isArray(value[0])) { + return this.getBitRatio(value[0]); + } else if (value.constructor === Input) { + return this.getBitRatio(value.value); + } + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + return 1; + case Uint16Array: + case Int16Array: + return 2; + case Float32Array: + case Int32Array: + default: + return 4; + } + } + getStringValueHandler() { + throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); + } + getVariablePrecisionString() { + switch (this.tactic) { + case 'speed': + return 'lowp'; + case 'performance': + return 'highp'; + case 'balanced': + default: + return 'mediump'; + } + } } - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); + class WebGLKernelValueBoolean extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const bool ${this.id} = ${value};\n`; + } + return `uniform bool ${this.id};\n`; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); + } } - static lookupKernelValueType(type, dynamic, precision, value) { - return lookupKernelValueType(type, dynamic, precision, value); + class WebGLKernelValueFloat extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource(value) { + if (this.origin === 'constants') { + if (Number.isInteger(value)) { + return `const float ${this.id} = ${value}.0;\n`; + } + return `const float ${this.id} = ${value};\n`; + } + return `uniform float ${this.id};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1f(this.id, this.uploadValue = value); + } } - static get testCanvas() { - return testCanvas; + class WebGLKernelValueInteger extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource(value) { + if (this.origin === 'constants') { + return `const int ${this.id} = ${ parseInt(value) };\n`; + } + return `uniform int ${this.id};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); + } } - static get testContext() { - return testContext; + class WebGLKernelValueHTMLImage extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.requestTexture(); + this.textureSize = [width, height]; + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(inputImage) { + if (inputImage.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.textureSize = [width, height]; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} + + class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} + + class WebGLKernelValueSingleInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}.value, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(input) { + if (input.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(input.value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueUnsignedInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + const [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value.value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, + `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, + `flattenTo(${this.varName}.value, preUploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(input) { + if (input.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(input.value, this.preUploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + const Type = this.getTransferArrayType(value.value); + this.preUploadValue = new Type(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + this.dimensions = value.dimensions; + this.textureSize = value.size; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(inputTexture) { + if (inputTexture.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type }) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(inputTexture) { + this.checkSize(inputTexture.size[0], inputTexture.size[1]); + this.dimensions = inputTexture.dimensions; + this.textureSize = inputTexture.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(inputTexture); + } + } + + class WebGLKernelValueNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + const { size: textureSize, dimensions } = value; + this.bitRatio = this.getBitRatio(value); + this.dimensions = dimensions; + this.textureSize = textureSize; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(inputTexture) { + if (inputTexture.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type}) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = value.dimensions; + this.checkSize(value.size[0], value.size[1]); + this.textureSize = value.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], 1, 1]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flatten2dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flatten3dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flatten4dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } } - static get features() { - return features; + class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } - static get fragmentShader() { - return fragmentShader; - } - static get vertexShader() { - return vertexShader; + class WebGLKernelValueSingleArray2 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`; + } + return `uniform vec2 ${this.id};\n`; + } + getStringValueHandler() { + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform2fv(this.id, this.uploadValue = value); + } } - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - const context = this.canvas.getContext('webgl2', settings); - return context; + class WebGLKernelValueSingleArray3 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`; + } + return `uniform vec3 ${this.id};\n`; + } + getStringValueHandler() { + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform3fv(this.id, this.uploadValue = value); + } } - initExtensions() { - this.extensions = { - EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - }; + class WebGLKernelValueSingleArray4 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`; + } + return `uniform vec4 ${this.id};\n`; + } + getStringValueHandler() { + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform4fv(this.id, this.uploadValue = value); + } } - validateSettings(args) { - if (!this.validate) { - this.texSize = utils.getKernelTextureSize({ + class WebGLKernelValueUnsignedArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, + `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, + `flattenTo(${this.varName}, preUploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.preUploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + const Type = this.getTransferArrayType(value); + this.preUploadValue = new Type(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + const kernelValueMaps = { + unsigned: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGLKernelValueDynamicUnsignedInput, + 'NumberTexture': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGLKernelValueUnsignedInput, + 'NumberTexture': WebGLKernelValueNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI, + 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI, + 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI, + 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI, + 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI, + 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI, + 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI, + 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI, + 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI, + 'Input': WebGLKernelValueDynamicSingleInput, + 'NumberTexture': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + 'Array1D(2)': WebGLKernelValueSingleArray1DI, + 'Array1D(3)': WebGLKernelValueSingleArray1DI, + 'Array1D(4)': WebGLKernelValueSingleArray1DI, + 'Array2D(2)': WebGLKernelValueSingleArray2DI, + 'Array2D(3)': WebGLKernelValueSingleArray2DI, + 'Array2D(4)': WebGLKernelValueSingleArray2DI, + 'Array3D(2)': WebGLKernelValueSingleArray3DI, + 'Array3D(3)': WebGLKernelValueSingleArray3DI, + 'Array3D(4)': WebGLKernelValueSingleArray3DI, + 'Input': WebGLKernelValueSingleInput, + 'NumberTexture': WebGLKernelValueNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, + }; + function lookupKernelValueType(type, dynamic, precision, value) { + if (!type) { + throw new Error('type missing'); + } + if (!dynamic) { + throw new Error('dynamic missing'); + } + if (!precision) { + throw new Error('precision missing'); + } + if (value.type) { + type = value.type; + } + const types = kernelValueMaps[precision][dynamic]; + if (types[type] === false) { + return null; + } else if (types[type] === undefined) { + throw new Error(`Could not find a KernelValue for ${ type }`); + } + return types[type]; + } + + let isSupported = null; + let testCanvas = null; + let testContext = null; + let testExtensions = null; + let features = null; + const plugins = [triangleNoise]; + const canvases = []; + const maxTexSizes = {}; + class WebGLKernel extends GLKernel { + static get isSupported() { + if (isSupported !== null) { + return isSupported; + } + this.setupFeatureChecks(); + isSupported = this.isContextMatch(testContext); + return isSupported; + } + static setupFeatureChecks() { + if (typeof document !== 'undefined') { + testCanvas = document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + testCanvas = new OffscreenCanvas(0, 0); + } + if (!testCanvas) return; + testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); + if (!testContext || !testContext.getExtension) return; + testExtensions = { + OES_texture_float: testContext.getExtension('OES_texture_float'), + OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), + OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), + WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), + }; + features = this.getFeatures(); + } + static isContextMatch(context) { + if (typeof WebGLRenderingContext !== 'undefined') { + return context instanceof WebGLRenderingContext; + } + return false; + } + static getFeatures() { + const isDrawBuffers = this.getIsDrawBuffers(); + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + isTextureFloat: this.getIsTextureFloat(), + isDrawBuffers, + kernelMap: isDrawBuffers, + channelCount: this.getChannelCount(), + }); + } + static getIsTextureFloat() { + return Boolean(testExtensions.OES_texture_float); + } + static getIsDrawBuffers() { + return Boolean(testExtensions.WEBGL_draw_buffers); + } + static getChannelCount() { + return testExtensions.WEBGL_draw_buffers ? + testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : + 1; + } + static lookupKernelValueType(type, dynamic, precision, value) { + return lookupKernelValueType(type, dynamic, precision, value); + } + static get testCanvas() { + return testCanvas; + } + static get testContext() { + return testContext; + } + static get features() { + return features; + } + static get fragmentShader() { + return fragmentShader; + } + static get vertexShader() { + return vertexShader; + } + constructor(source, settings) { + super(source, settings); + this.program = null; + this.pipeline = settings.pipeline; + this.endianness = utils$1.systemEndianness(); + this.extensions = {}; + this.subKernelOutputTextures = null; + this.kernelArguments = null; + this.argumentTextureCount = 0; + this.constantTextureCount = 0; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + this.fragShader = null; + this.vertShader = null; + this.drawBuffersMap = null; + this.outputTexture = null; + this.maxTexSize = null; + this.switchingKernels = false; + this.onRequestSwitchKernel = null; + this.mergeSettings(source.settings || settings); + this.threadDim = null; + this.framebuffer = null; + this.buffer = null; + this.textureCache = {}; + this.programUniformLocationCache = {}; + this.uniform1fCache = {}; + this.uniform1iCache = {}; + this.uniform2fCache = {}; + this.uniform2fvCache = {}; + this.uniform2ivCache = {}; + this.uniform3fvCache = {}; + this.uniform3ivCache = {}; + this.uniform4fvCache = {}; + this.uniform4ivCache = {}; + } + initCanvas() { + if (typeof document !== 'undefined') { + const canvas = document.createElement('canvas'); + canvas.width = 2; + canvas.height = 2; + return canvas; + } else if (typeof OffscreenCanvas !== 'undefined') { + return new OffscreenCanvas(0, 0); + } + } + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings); + } + initPlugins(settings) { + const pluginsToUse = []; + const { source } = this; + if (typeof source === 'string') { + for (let i = 0; i < plugins.length; i++) { + const plugin = plugins[i]; + if (source.match(plugin.functionMatch)) { + pluginsToUse.push(plugin); + } + } + } else if (typeof source === 'object') { + if (settings.pluginNames) { + for (let i = 0; i < plugins.length; i++) { + const plugin = plugins[i]; + const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name); + if (usePlugin) { + pluginsToUse.push(plugin); + } + } + } + } + return pluginsToUse; + } + initExtensions() { + this.extensions = { + OES_texture_float: this.context.getExtension('OES_texture_float'), + OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), + OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), + WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), + WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'), + }; + } + validateSettings(args) { + if (!this.validate) { + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + return; + } + const { features } = this.constructor; + if (this.optimizeFloatMemory === true && !features.isTextureFloat) { + throw new Error('Float textures are not supported'); + } else if (this.precision === 'single' && !features.isFloatRead) { + throw new Error('Single precision not supported'); + } else if (!this.graphical && this.precision === null && features.isTextureFloat) { + this.precision = features.isFloatRead ? 'single' : 'unsigned'; + } + if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) { + throw new Error('could not instantiate draw buffers extension'); + } + if (this.fixIntegerDivisionAccuracy === null) { + this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; + } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { + this.fixIntegerDivisionAccuracy = false; + } + this.checkOutput(); + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + const argType = utils$1.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils$1.getDimensions(argType); + } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { + this.output = args[0].output; + } else { + throw new Error('Auto output not supported for input type: ' + argType); + } + } + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); + } + if (this.precision === 'precision') { + this.precision = 'unsigned'; + console.warn('Cannot use graphical mode and single precision at the same time'); + } + this.texSize = utils$1.clone(this.output); + return; + } else if (this.precision === null && features.isTextureFloat) { + this.precision = 'single'; + } + this.texSize = utils$1.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision, }, this.output); - return; + this.checkTextureSize(); } - - const features = this.constructor.features; - if (this.precision === 'single' && !features.isFloatRead) { - throw new Error('Float texture outputs are not supported'); - } else if (!this.graphical && this.precision === null) { - this.precision = features.isFloatRead ? 'single' : 'unsigned'; + updateMaxTexSize() { + const { texSize, canvas } = this; + if (this.maxTexSize === null) { + let canvasIndex = canvases.indexOf(canvas); + if (canvasIndex === -1) { + canvasIndex = canvases.length; + canvases.push(canvas); + maxTexSizes[canvasIndex] = [texSize[0], texSize[1]]; + } + this.maxTexSize = maxTexSizes[canvasIndex]; + } + if (this.maxTexSize[0] < texSize[0]) { + this.maxTexSize[0] = texSize[0]; + } + if (this.maxTexSize[1] < texSize[1]) { + this.maxTexSize[1] = texSize[1]; + } } - - if (this.fixIntegerDivisionAccuracy === null) { - this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; - } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { - this.fixIntegerDivisionAccuracy = false; + _oldtranslateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + const translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + let requiredChannels = 0; + const returnTypes = functionBuilder.getReturnTypes(); + for (let i = 0; i < returnTypes.length; i++) { + switch (returnTypes[i]) { + case 'Float': + case 'Number': + case 'Integer': + requiredChannels++; + break; + case 'Array(2)': + requiredChannels += 2; + break; + case 'Array(3)': + requiredChannels += 3; + break; + case 'Array(4)': + requiredChannels += 4; + break; + } + } + if (features && requiredChannels > features.channelCount) { + throw new Error('Too many channels!'); + } + return this.translatedSource = translatedSource; } - - this.checkOutput(); - - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); + setupArguments(args) { + this.kernelArguments = []; + this.argumentTextureCount = 0; + const needsArgumentTypes = this.argumentTypes === null; + if (needsArgumentTypes) { + this.argumentTypes = []; } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - switch (argType) { - case 'Array': - this.output = utils.getDimensions(argType); - break; - case 'NumberTexture': - case 'MemoryOptimizedNumberTexture': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - this.output = args[0].output; - break; - default: - throw new Error('Auto output not supported for input type: ' + argType); + this.argumentSizes = []; + this.argumentBitRatios = []; + if (args.length < this.argumentNames.length) { + throw new Error('not enough arguments for kernel'); + } else if (args.length > this.argumentNames.length) { + throw new Error('too many arguments for kernel'); + } + const { context: gl } = this; + let textureIndexes = 0; + for (let index = 0; index < args.length; index++) { + const value = args[index]; + const name = this.argumentNames[index]; + let type; + if (needsArgumentTypes) { + type = utils$1.getVariableType(value, this.strictIntegers); + this.argumentTypes.push(type); + } else { + type = this.argumentTypes[index]; + } + const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]); + if (KernelValue === null) { + return this.requestFallback(args); + } + const kernelArgument = new KernelValue(value, { + name, + type, + tactic: this.tactic, + origin: 'user', + context: gl, + checkContext: this.checkContext, + kernel: this, + strictIntegers: this.strictIntegers, + onRequestTexture: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onUpdateValueMismatch: () => { + this.switchingKernels = true; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + } + }); + this.kernelArguments.push(kernelArgument); + this.argumentSizes.push(kernelArgument.textureSize); + this.argumentBitRatios[index] = kernelArgument.bitRatio; } } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + setupConstants(args) { + const { context: gl } = this; + this.kernelConstants = []; + this.forceUploadKernelConstants = []; + let needsConstantTypes = this.constantTypes === null; + if (needsConstantTypes) { + this.constantTypes = {}; } - - if (this.precision === 'single') { - console.warn('Cannot use graphical mode and single precision at the same time'); - this.precision = 'unsigned'; + this.constantBitRatios = {}; + let textureIndexes = 0; + for (const name in this.constants) { + const value = this.constants[name]; + let type; + if (needsConstantTypes) { + type = utils$1.getVariableType(value, this.strictIntegers); + this.constantTypes[name] = type; + } else { + type = this.constantTypes[name]; + } + const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value); + if (KernelValue === null) { + return this.requestFallback(args); + } + const kernelValue = new KernelValue(value, { + name, + type, + tactic: this.tactic, + origin: 'constants', + context: this.context, + checkContext: this.checkContext, + kernel: this, + strictIntegers: this.strictIntegers, + onRequestTexture: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount++; + } + }); + this.constantBitRatios[name] = kernelValue.bitRatio; + this.kernelConstants.push(kernelValue); + if (kernelValue.forceUploadEachRun) { + this.forceUploadKernelConstants.push(kernelValue); + } } - - this.texSize = utils.clone(this.output); - return; - } else if (!this.graphical && this.precision === null && features.isTextureFloat) { - this.precision = 'single'; } - - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - - this.checkTextureSize(); - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + build() { + this.initExtensions(); + this.validateSettings(arguments); + this.setupConstants(arguments); + if (this.fallbackRequested) return; + this.setupArguments(arguments); + if (this.fallbackRequested) return; + this.updateMaxTexSize(); + this.translateSource(); + const failureResult = this.pickRenderStrategy(arguments); + if (failureResult) { + return failureResult; + } + const { texSize, context: gl, canvas } = this; + gl.enable(gl.SCISSOR_TEST); + if (this.pipeline && this.precision === 'single') { + gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + canvas.width = this.maxTexSize[0]; + canvas.height = this.maxTexSize[1]; + } else { + gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + canvas.width = this.maxTexSize[0]; + canvas.height = this.maxTexSize[1]; + } + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) { + threadDim.push(1); + } + const compiledVertexShader = this.getVertexShader(arguments); + const vertShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertShader, compiledVertexShader); + gl.compileShader(vertShader); + this.vertShader = vertShader; + const compiledFragmentShader = this.getFragmentShader(arguments); + const fragShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragShader, compiledFragmentShader); + gl.compileShader(fragShader); + this.fragShader = fragShader; + if (this.debug) { + console.log('GLSL Shader Output:'); + console.log(compiledFragmentShader); + } + if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) { + throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader)); + } + if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) { + throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader)); + } + const program = this.program = gl.createProgram(); + gl.attachShader(program, vertShader); + gl.attachShader(program, fragShader); + gl.linkProgram(program); + this.framebuffer = gl.createFramebuffer(); + this.framebuffer.width = texSize[0]; + this.framebuffer.height = texSize[1]; + const vertices = new Float32Array([-1, -1, + 1, -1, -1, 1, + 1, 1 + ]); + const texCoords = new Float32Array([ + 0, 0, + 1, 0, + 0, 1, + 1, 1 + ]); + const texCoordOffset = vertices.byteLength; + let buffer = this.buffer; + if (!buffer) { + buffer = this.buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW); + } else { + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + } + gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); + gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords); + const aPosLoc = gl.getAttribLocation(this.program, 'aPos'); + gl.enableVertexAttribArray(aPosLoc); + gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0); + const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord'); + gl.enableVertexAttribArray(aTexCoordLoc); + gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + let i = 0; + gl.useProgram(this.program); + for (let p in this.constants) { + this.kernelConstants[i++].updateValue(this.constants[p]); + } + if (!this.immutable) { + this._setupOutputTexture(); + if ( + this.subKernels !== null && + this.subKernels.length > 0 + ) { + this._setupSubOutputTextures(); + } + } } - - if (this.subKernels && this.subKernels.length > 0) { + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + if (this.subKernels && this.subKernels.length > 0) { + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (!subKernel.returnType) { + subKernel.returnType = functionBuilder.getSubKernelResultType(i); + } + } + } + } + run() { + const { kernelArguments, forceUploadKernelConstants } = this; + const texSize = this.texSize; + const gl = this.context; + gl.useProgram(this.program); + gl.scissor(0, 0, texSize[0], texSize[1]); + if (this.dynamicOutput) { + this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); + this.setUniform2iv('uTexSize', texSize); + } + this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); + this.switchingKernels = false; + for (let i = 0; i < forceUploadKernelConstants.length; i++) { + const constant = forceUploadKernelConstants[i]; + constant.updateValue(this.constants[constant.name]); + if (this.switchingKernels) return; + } + for (let i = 0; i < kernelArguments.length; i++) { + kernelArguments[i].updateValue(arguments[i]); + if (this.switchingKernels) return; + } + if (this.plugins) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.onBeforeRun) { + plugin.onBeforeRun(this); + } + } + } + if (this.graphical) { + if (this.pipeline) { + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (!this.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return; + } + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (this.immutable) { + this._setupOutputTexture(); + } + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + getOutputTexture() { + return this.outputTexture; + } + _setupOutputTexture() { + const gl = this.context; + const texSize = this.texSize; + const texture = this.outputTexture = this.context.createTexture(); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } + break; + case 'Array(2)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(3)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(4)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + default: + if (!this.graphical) { + throw new Error('Unhandled return type'); + } + } + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + } + _setupSubOutputTextures() { + const gl = this.context; + const texSize = this.texSize; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (!subKernel.returnType) { - subKernel.returnType = functionBuilder.getSubKernelResultType(i); + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); } } - } - - run() { - const { kernelArguments, texSize, forceUploadKernelConstants } = this; - const gl = this.context; - - gl.useProgram(this.program); - gl.scissor(0, 0, texSize[0], texSize[1]); - - if (this.dynamicOutput) { - this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); - this.setUniform2iv('uTexSize', texSize); + getTextureCache(name) { + if (this.textureCache.hasOwnProperty(name)) { + return this.textureCache[name]; + } + return this.textureCache[name] = this.context.createTexture(); } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.switchingKernels = false; - for (let i = 0; i < forceUploadKernelConstants.length; i++) { - const constant = forceUploadKernelConstants[i]; - constant.updateValue(this.constants[constant.name]); - if (this.switchingKernels) return; + detachTextureCache(name) { + delete this.textureCache[name]; } - for (let i = 0; i < kernelArguments.length; i++) { - kernelArguments[i].updateValue(arguments[i]); - if (this.switchingKernels) return; + setUniform1f(name, value) { + if (this.uniform1fCache.hasOwnProperty(name)) { + const cache = this.uniform1fCache[name]; + if (value === cache) { + return; + } + } + this.uniform1fCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform1f(loc, value); } - - if (this.plugins) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.onBeforeRun) { - plugin.onBeforeRun(this); + setUniform1i(name, value) { + if (this.uniform1iCache.hasOwnProperty(name)) { + const cache = this.uniform1iCache[name]; + if (value === cache) { + return; } } + this.uniform1iCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform1i(loc, value); } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); + setUniform2f(name, value1, value2) { + if (this.uniform2fCache.hasOwnProperty(name)) { + const cache = this.uniform2fCache[name]; + if ( + value1 === cache[0] && + value2 === cache[1] + ) { + return; } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context - }); } - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return; + this.uniform2fCache[name] = [value1, value2]; + const loc = this.getUniformLocation(name); + this.context.uniform2f(loc, value1, value2); + } + setUniform2fv(name, value) { + if (this.uniform2fvCache.hasOwnProperty(name)) { + const cache = this.uniform2fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] + ) { + return; + } + } + this.uniform2fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform2fv(loc, value); + } + setUniform2iv(name, value) { + if (this.uniform2ivCache.hasOwnProperty(name)) { + const cache = this.uniform2ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] + ) { + return; + } + } + this.uniform2ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform2iv(loc, value); + } + setUniform3fv(name, value) { + if (this.uniform3fvCache.hasOwnProperty(name)) { + const cache = this.uniform3fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3fv(loc, value); + } + setUniform3iv(name, value) { + if (this.uniform3ivCache.hasOwnProperty(name)) { + const cache = this.uniform3ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3iv(loc, value); + } + setUniform3fv(name, value) { + if (this.uniform3fvCache.hasOwnProperty(name)) { + const cache = this.uniform3fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3fv(loc, value); + } + setUniform4iv(name, value) { + if (this.uniform4ivCache.hasOwnProperty(name)) { + const cache = this.uniform4ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] && + value[3] === cache[3] + ) { + return; + } + } + this.uniform4ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform4iv(loc, value); + } + setUniform4fv(name, value) { + if (this.uniform4fvCache.hasOwnProperty(name)) { + const cache = this.uniform4fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] && + value[3] === cache[3] + ) { + return; + } + } + this.uniform4fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform4fv(loc, value); + } + getUniformLocation(name) { + if (this.programUniformLocationCache.hasOwnProperty(name)) { + return this.programUniformLocationCache[name]; + } + return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name); + } + _getFragShaderArtifactMap(args) { + return { + HEADER: this._getHeaderString(), + LOOP_MAX: this._getLoopMaxString(), + PLUGINS: this._getPluginsString(), + CONSTANTS: this._getConstantsString(), + DECODE32_ENDIANNESS: this._getDecode32EndiannessString(), + ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(), + DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(), + INJECTED_NATIVE: this._getInjectedNative(), + MAIN_CONSTANTS: this._getMainConstantsString(), + MAIN_ARGUMENTS: this._getMainArgumentsString(args), + KERNEL: this.getKernelString(), + MAIN_RESULT: this.getMainResultString(), + FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), + INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), + SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), + SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), + }; + } + _getVertShaderArtifactMap(args) { + return { + FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), + INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), + SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), + SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), + }; + } + _getHeaderString() { + return ( + this.subKernels !== null ? + '#extension GL_EXT_draw_buffers : require\n' : + '' + ); + } + _getLoopMaxString() { + return ( + this.loopMaxIterations ? + ` ${parseInt(this.loopMaxIterations)};\n` : + ' 1000;\n' + ); + } + _getPluginsString() { + if (!this.plugins) return '\n'; + return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n'); + } + _getConstantsString() { + const result = []; + const { threadDim, texSize } = this; + if (this.dynamicOutput) { + result.push( + 'uniform ivec3 uOutputDim', + 'uniform ivec2 uTexSize' + ); + } else { + result.push( + `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`, + `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})` + ); + } + return utils$1.linesToString(result); + } + _getTextureCoordinate() { + const subKernels = this.subKernels; + if (subKernels === null || subKernels.length < 1) { + return 'varying vec2 vTexCoord;\n'; + } else { + return 'out vec2 vTexCoord;\n'; + } + } + _getDecode32EndiannessString() { + return ( + this.endianness === 'LE' ? + '' : + ' texel.rgba = texel.abgr;\n' + ); + } + _getEncode32EndiannessString() { + return ( + this.endianness === 'LE' ? + '' : + ' texel.rgba = texel.abgr;\n' + ); + } + _getDivideWithIntegerCheckString() { + return this.fixIntegerDivisionAccuracy ? + `float div_with_int_check(float x, float y) { + if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { + return float(int(x)/int(y)); + } + return x / y; +}` : + ''; + } + _getMainArgumentsString(args) { + const results = []; + const { argumentNames } = this; + for (let i = 0; i < argumentNames.length; i++) { + results.push(this.kernelArguments[i].getSource(args[i])); + } + return results.join(''); } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.immutable) { - this._setupOutputTexture(); + _getInjectedNative() { + return this.injectedNative || ''; } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); + _getMainConstantsString() { + const result = []; + const { constants } = this; + if (constants) { + let i = 0; + for (const name in constants) { + result.push(this.kernelConstants[i++].getSource(this.constants[name])); + } } - gl.drawBuffers(this.drawBuffersMap); + return result.join(''); } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - drawBuffers() { - this.context.drawBuffers(this.drawBuffersMap); - } - - getOutputTexture() { - return this.outputTexture; - } - - _setupOutputTexture() { - const { texSize } = this; - const gl = this.context; - const texture = this.outputTexture = gl.createTexture(); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.precision === 'single') { - if (this.pipeline) { + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration + ); switch (this.returnType) { case 'Number': case 'Float': case 'Integer': - if (this.optimizeFloatMemory) { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + for (let i = 0; i < subKernels.length; i++) { + const subKernel = subKernels[i]; + result.push( + subKernel.returnType === 'Integer' ? + `int subKernelResult_${ subKernel.name } = 0` : + `float subKernelResult_${ subKernel.name } = 0.0` + ); } break; case 'Array(2)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec2 subKernelResult_${ subKernels[i].name }` + ); + } + break; + case 'Array(3)': + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec3 subKernelResult_${ subKernels[i].name }` + ); + } break; - case 'Array(3)': case 'Array(4)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec4 subKernelResult_${ subKernels[i].name }` + ); + } break; - default: - throw new Error('Unhandled return type'); } } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + result.push( + kernelResultDeclaration + ); } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + return utils$1.linesToString(result) + this.translatedSource; } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - _setupSubOutputTextures() { - const { texSize } = this; - const gl = this.context; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.precision === 'single') { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); + getMainResultGraphical() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragColor = actualColor', + ]); } - } - - _getHeaderString() { - return ''; - } - - _getTextureCoordinate() { - const subKernels = this.subKernels; - if (subKernels === null || subKernels.length < 1) { - switch (this.tactic) { - case 'speed': - return 'in lowp vec2 vTexCoord;\n'; - case 'performance': - return 'in highp vec2 vTexCoord;\n'; - case 'balanced': - default: - return 'in mediump vec2 vTexCoord;\n'; - } - } else { - switch (this.tactic) { - case 'speed': - return 'out lowp vec2 vTexCoord;\n'; - case 'performance': - return 'out highp vec2 vTexCoord;\n'; - case 'balanced': + getMainResultPackedPixels() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return this.getMainResultKernelPackedPixels() + + this.getMainResultSubKernelPackedPixels(); default: - return 'out mediump vec2 vTexCoord;\n'; + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); } } - } - - _getMainArgumentsString(args) { - const result = []; - const argumentNames = this.argumentNames; - for (let i = 0; i < argumentNames.length; i++) { - result.push(this.kernelArguments[i].getSource(args[i])); + getMainResultKernelPackedPixels() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); } - return result.join(''); - } - - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; + getMainResultSubKernelPackedPixels() { + const result = []; + if (!this.subKernels) return ''; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` + ); } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); + result.push( + ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` + ); } + } + return utils$1.linesToString(result); } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration, - 'layout(location = 0) out vec4 data0' - ); - for (let i = 0; i < subKernels.length; i++) { - const subKernel = subKernels[i]; - result.push( - subKernel.returnType === 'Integer' ? - `int subKernelResult_${ subKernel.name } = 0` : - `float subKernelResult_${ subKernel.name } = 0.0`, - `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }` - ); + getMainResultMemoryOptimizedFloats() { + const result = [ + ' index *= 4', + ]; + switch (this.returnType) { + case 'Number': + case 'Integer': + case 'Float': + const channels = ['r', 'g', 'b', 'a']; + for (let i = 0; i < channels.length; i++) { + const channel = channels[i]; + this.getMainResultKernelMemoryOptimizedFloats(result, channel); + this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); + if (i + 1 < channels.length) { + result.push(' index += 1'); + } + } + break; + default: + throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); } - } else { + return utils$1.linesToString(result); + } + getMainResultKernelMemoryOptimizedFloats(result, channel) { result.push( - 'out vec4 data0', - kernelResultDeclaration + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0].${channel} = kernelResult`, ); } - - return utils.linesToString(result) + this.translatedSource; - } - - getMainResultGraphical() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0 = actualColor', - ]); - } - - getMainResultPackedPixels() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return this.getMainResultKernelPackedPixels() + - this.getMainResultSubKernelPackedPixels(); - default: - throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); - } - } - - getMainResultKernelPackedPixels() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` - ]); - } - - getMainResultSubKernelPackedPixels() { - const result = []; - if (!this.subKernels) return ''; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` - ); - } else { - result.push( - ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` - ); + getMainResultSubKernelMemoryOptimizedFloats(result, channel) { + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`, + ); + } } } - return utils.linesToString(result); - } - - getMainResultMemoryOptimizedFloats() { - const result = [ - ' index *= 4', - ]; - - switch (this.returnType) { - case 'Number': - case 'Integer': - case 'Float': - const channels = ['r', 'g', 'b', 'a']; - for (let i = 0; i < channels.length; i++) { - const channel = channels[i]; - this.getMainResultKernelMemoryOptimizedFloats(result, channel); - this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); - if (i + 1 < channels.length) { - result.push(' index += 1'); - } - } - break; - default: - throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult', + ]; } - - return utils.linesToString(result); - } - - getMainResultKernelMemoryOptimizedFloats(result, channel) { - result.push( - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` data0.${channel} = kernelResult`, - ); - } - - getMainResultSubKernelMemoryOptimizedFloats(result, channel) { - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`, - ); - } else { - result.push( - ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`, - ); + getMainResultSubKernelNumberTexture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`, + ); + } } + return result; } - } - - getMainResultKernelNumberTexture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult', - ]; - } - - getMainResultSubKernelNumberTexture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { + getMainResultKernelArray2Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult[0]', + ' gl_FragData[0][1] = kernelResult[1]', + ]; + } + getMainResultSubKernelArray2Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { result.push( - ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`, + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, ); - } else { + } + return result; + } + getMainResultKernelArray3Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult[0]', + ' gl_FragData[0][1] = kernelResult[1]', + ' gl_FragData[0][2] = kernelResult[2]', + ]; + } + getMainResultSubKernelArray3Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}`, + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, ); } + return result; } - return result; - } - - getMainResultKernelArray2Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult[0]', - ' data0[1] = kernelResult[1]', - ]; - } - - getMainResultSubKernelArray2Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, - ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, - ); - } - return result; - } - - getMainResultKernelArray3Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult[0]', - ' data0[1] = kernelResult[1]', - ' data0[2] = kernelResult[2]', - ]; - } - - getMainResultSubKernelArray3Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, - ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, - ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`, - ); + getMainResultKernelArray4Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0] = kernelResult', + ]; } - return result; - } - - getMainResultKernelArray4Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0 = kernelResult', - ]; - } - - getMainResultSubKernelArray4Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`, - ); + getMainResultSubKernelArray4Texture() { + const result = []; + if (!this.subKernels) return result; + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`, + ); + } + } + break; + case 'Array(2)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ); + } + break; + case 'Array(3)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, + ); + } + break; + case 'Array(4)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, + ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`, + ); + } + break; + } + return result; } - return result; - } - - destroyExtensions() { - this.extensions.EXT_color_buffer_float = null; - this.extensions.OES_texture_float_linear = null; - } - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON(); - return json; - } -} - -module.exports = { - WebGL2Kernel -}; -},{"../../utils":111,"../function-builder":8,"../web-gl/kernel":67,"./fragment-shader":69,"./function-node":70,"./kernel-value-maps":71,"./vertex-shader":103}],103:[function(require,module,exports){ -const vertexShader = `#version 300 es -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -in vec2 aPos; -in vec2 aTexCoord; - -out vec2 vTexCoord; -uniform vec2 ratio; - -void main(void) { - gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); - vTexCoord = aTexCoord; -}`; - -module.exports = { - vertexShader -}; -},{}],104:[function(require,module,exports){ -const lib = require('./index'); -const GPU = lib.GPU; -for (const p in lib) { - if (!lib.hasOwnProperty(p)) continue; - if (p === 'GPU') continue; - GPU[p] = lib[p]; -} -module.exports = GPU; -},{"./index":106}],105:[function(require,module,exports){ -const { gpuMock } = require('gpu-mock.js'); -const { utils } = require('./utils'); -const { CPUKernel } = require('./backend/cpu/kernel'); -const { HeadlessGLKernel } = require('./backend/headless-gl/kernel'); -const { WebGL2Kernel } = require('./backend/web-gl2/kernel'); -const { WebGLKernel } = require('./backend/web-gl/kernel'); -const { kernelRunShortcut } = require('./kernel-run-shortcut'); - - -const kernelOrder = [HeadlessGLKernel, WebGL2Kernel, WebGLKernel]; - -const kernelTypes = ['gpu', 'cpu']; - -const internalKernels = { - 'headlessgl': HeadlessGLKernel, - 'webgl2': WebGL2Kernel, - 'webgl': WebGLKernel, -}; - -let validate = true; - -class GPU { - static disableValidation() { - validate = false; - } - - static enableValidation() { - validate = true; - } - - static get isGPUSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported); - } - - static get isKernelMapSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); - } - - static get isOffscreenCanvasSupported() { - return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined'; - } - - static get isWebGLSupported() { - return WebGLKernel.isSupported; - } - - static get isWebGL2Supported() { - return WebGL2Kernel.isSupported; - } - - static get isHeadlessGLSupported() { - return HeadlessGLKernel.isSupported; - } - - static get isCanvasSupported() { - return typeof HTMLCanvasElement !== 'undefined'; - } - - static get isGPUHTMLImageArraySupported() { - return WebGL2Kernel.isSupported; - } - - static get isSinglePrecisionSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); - } - - constructor(settings) { - settings = settings || {}; - this.canvas = settings.canvas || null; - this.context = settings.context || null; - this.mode = settings.mode; - this.Kernel = null; - this.kernels = []; - this.functions = []; - this.nativeFunctions = []; - this.injectedNative = null; - if (this.mode === 'dev') return; - this.chooseKernel(); - if (settings.functions) { - for (let i = 0; i < settings.functions.length; i++) { - this.addFunction(settings.functions[i]); + replaceArtifacts(src, map) { + return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => { + if (map.hasOwnProperty(artifact)) { + return map[artifact]; + } + throw `unhandled artifact ${artifact}`; + }); + } + getFragmentShader(args) { + if (this.compiledFragmentShader !== null) { + return this.compiledFragmentShader; } + return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args)); } - - if (settings.nativeFunctions) { - for (const p in settings.nativeFunctions) { - this.addNativeFunction(p, settings.nativeFunctions[p]); + getVertexShader(args) { + if (this.compiledVertexShader !== null) { + return this.compiledVertexShader; } + return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args)); } - } - - chooseKernel() { - if (this.Kernel) return; - - let Kernel = null; - - if (this.context) { - for (let i = 0; i < kernelOrder.length; i++) { - const ExternalKernel = kernelOrder[i]; - if (ExternalKernel.isContextMatch(this.context)) { - if (!ExternalKernel.isSupported) { - throw new Error(`Kernel type ${ExternalKernel.name} not supported`); - } - Kernel = ExternalKernel; - break; - } + toString() { + const setupContextString = utils$1.linesToString([ + `const gl = context`, + ]); + return glKernelString(this.constructor, arguments, this, setupContextString); + } + destroy(removeCanvasReferences) { + if (this.outputTexture) { + this.context.deleteTexture(this.outputTexture); } - if (Kernel === null) { - throw new Error('unknown Context'); + if (this.buffer) { + this.context.deleteBuffer(this.buffer); } - } else if (this.mode) { - if (this.mode in internalKernels) { - if (!validate || internalKernels[this.mode].isSupported) { - Kernel = internalKernels[this.mode]; - } - } else if (this.mode === 'gpu') { - for (let i = 0; i < kernelOrder.length; i++) { - if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; - } - } - } else if (this.mode === 'cpu') { - Kernel = CPUKernel; + if (this.framebuffer) { + this.context.deleteFramebuffer(this.framebuffer); } - if (!Kernel) { - throw new Error(`A requested mode of "${this.mode}" and is not supported`); + if (this.vertShader) { + this.context.deleteShader(this.vertShader); } - } else { - for (let i = 0; i < kernelOrder.length; i++) { - if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; + if (this.fragShader) { + this.context.deleteShader(this.fragShader); + } + if (this.program) { + this.context.deleteProgram(this.program); + } + const keys = Object.keys(this.textureCache); + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + this.context.deleteTexture(this.textureCache[name]); + } + if (this.subKernelOutputTextures) { + for (let i = 0; i < this.subKernelOutputTextures.length; i++) { + this.context.deleteTexture(this.subKernelOutputTextures[i]); } } - if (!Kernel) { - Kernel = CPUKernel; + if (removeCanvasReferences) { + const idx = canvases.indexOf(this.canvas); + if (idx >= 0) { + canvases[idx] = null; + maxTexSizes[idx] = null; + } } + this.destroyExtensions(); + delete this.context; + delete this.canvas; } - - if (!this.mode) { - this.mode = Kernel.mode; - } - this.Kernel = Kernel; - } - - createKernel(source, settings) { - if (typeof source === 'undefined') { - throw new Error('Missing source parameter'); - } - if (typeof source !== 'object' && !utils.isFunction(source) && typeof source !== 'string') { - throw new Error('source parameter not a function'); - } - - if (this.mode === 'dev') { - const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); - this.kernels.push(devKernel); - return devKernel; + destroyExtensions() { + this.extensions.OES_texture_float = null; + this.extensions.OES_texture_float_linear = null; + this.extensions.OES_element_index_uint = null; + this.extensions.WEBGL_draw_buffers = null; } - - source = typeof source === 'function' ? source.toString() : source; - const switchableKernels = {}; - const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {}; - if (settings && typeof settings.argumentTypes === 'object') { - settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + static destroyContext(context) { + const extension = context.getExtension('WEBGL_lose_context'); + if (extension) { + extension.loseContext(); + } } - - function onRequestFallback(args) { - const fallbackKernel = new CPUKernel(source, { - argumentTypes: kernelRun.argumentTypes, - constantTypes: kernelRun.constantTypes, - graphical: kernelRun.graphical, - loopMaxIterations: kernelRun.loopMaxIterations, - constants: kernelRun.constants, - dynamicOutput: kernelRun.dynamicOutput, - dynamicArgument: kernelRun.dynamicArguments, - output: kernelRun.output, - precision: kernelRun.precision, - pipeline: kernelRun.pipeline, - immutable: kernelRun.immutable, - optimizeFloatMemory: kernelRun.optimizeFloatMemory, - fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy, - functions: kernelRun.functions, - nativeFunctions: kernelRun.nativeFunctions, - injectedNative: kernelRun.injectedNative, - subKernels: kernelRun.subKernels, - strictIntegers: kernelRun.strictIntegers, - debug: kernelRun.debug, - warnVarUsage: kernelRun.warnVarUsage, - }); - fallbackKernel.build.apply(fallbackKernel, args); - const result = fallbackKernel.run.apply(fallbackKernel, args); - kernelRun.replaceKernel(fallbackKernel); - return result; + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); + return json; } + } - function onRequestSwitchKernel(args, kernel) { - const argumentTypes = new Array(args.length); - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - const type = kernel.argumentTypes[i]; - if (arg.type) { - argumentTypes[i] = arg.type; - } else { - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'ArrayTexture(1)': - argumentTypes[i] = utils.getVariableType(arg); - break; - default: - argumentTypes[i] = type; - } - } + class WebGL2FunctionNode extends WebGLFunctionNode { + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); } - const signature = argumentTypes.join(','); - const existingKernel = switchableKernels[signature]; - if (existingKernel) { - existingKernel.run.apply(existingKernel, args); - if (existingKernel.renderKernels) { - return existingKernel.renderKernels(); + const type = this.getType(idtNode); + if (idtNode.name === 'Infinity') { + retArr.push('intBitsToFloat(2139095039)'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); } else { - return existingKernel.renderOutput(); + retArr.push(`user_${idtNode.name}`); } - } - - const newKernel = switchableKernels[signature] = new kernel.constructor(source, { - argumentTypes, - constantTypes: kernel.constantTypes, - graphical: kernel.graphical, - loopMaxIterations: kernel.loopMaxIterations, - constants: kernel.constants, - dynamicOutput: kernel.dynamicOutput, - dynamicArgument: kernel.dynamicArguments, - context: kernel.context, - canvas: kernel.canvas, - output: kernel.output, - precision: kernel.precision, - pipeline: kernel.pipeline, - immutable: kernel.immutable, - optimizeFloatMemory: kernel.optimizeFloatMemory, - fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy, - functions: kernel.functions, - nativeFunctions: kernel.nativeFunctions, - injectedNative: kernel.injectedNative, - subKernels: kernel.subKernels, - strictIntegers: kernel.strictIntegers, - debug: kernel.debug, - gpu: kernel.gpu, - validate, - warnVarUsage: kernel.warnVarUsage, - returnType: kernel.returnType, - onRequestFallback, - onRequestSwitchKernel, - }); - newKernel.build.apply(newKernel, args); - newKernel.run.apply(newKernel, args); - kernelRun.replaceKernel(newKernel); - if (newKernel.renderKernels) { - return newKernel.renderKernels(); } else { - return newKernel.renderOutput(); - } - } - const mergedSettings = Object.assign({ - context: this.context, - canvas: this.canvas, - functions: this.functions, - nativeFunctions: this.nativeFunctions, - injectedNative: this.injectedNative, - gpu: this, - validate, - onRequestFallback, - onRequestSwitchKernel - }, settingsCopy); - - const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); - - if (!this.canvas) { - this.canvas = kernelRun.canvas; + retArr.push(`user_${idtNode.name}`); + } + return retArr; } + } - if (!this.context) { - this.context = kernelRun.context; - } + const fragmentShader$1 = `#version 300 es +__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; +__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +in vec2 vTexCoord; + +const int BIT_COUNT = 32; +int modi(int x, int y) { + return x - y * (x / y); +} + +int bitwiseOr(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseXOR(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseAnd(int a, int b) { + int result = 0; + int n = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 && b > 0)) { + break; + } + } + return result; +} +int bitwiseNot(int a) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if (modi(a, 2) == 0) { + result += n; + } + a = a / 2; + n = n * 2; + } + return result; +} +int bitwiseZeroFillLeftShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n *= 2; + } + + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +int bitwiseSignedRightShift(int num, int shifts) { + return int(floor(float(num) / pow(2.0, float(shifts)))); +} + +int bitwiseZeroFillRightShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n /= 2; + } + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +vec2 integerMod(vec2 x, float y) { + vec2 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec3 integerMod(vec3 x, float y) { + vec3 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec4 integerMod(vec4 x, vec4 y) { + vec4 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +float integerMod(float x, float y) { + float res = floor(mod(x, y)); + return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); +} + +int integerMod(int x, int y) { + return x - (y * int(x/y)); +} + +__DIVIDE_WITH_INTEGER_CHECK__; + +// Here be dragons! +// DO NOT OPTIMIZE THIS CODE +// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE +// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME +const vec2 MAGIC_VEC = vec2(1.0, -256.0); +const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); +const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 +float decode32(vec4 texel) { + __DECODE32_ENDIANNESS__; + texel *= 255.0; + vec2 gte128; + gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; + gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; + float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); + float res = exp2(round(exponent)); + texel.b = texel.b - 128.0 * gte128.x; + res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; + res *= gte128.y * -2.0 + 1.0; + return res; +} + +float decode16(vec4 texel, int index) { + int channel = integerMod(index, 2); + return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; +} + +float decode8(vec4 texel, int index) { + int channel = integerMod(index, 4); + return texel[channel] * 255.0; +} + +vec4 legacyEncode32(float f) { + float F = abs(f); + float sign = f < 0.0 ? 1.0 : 0.0; + float exponent = floor(log2(F)); + float mantissa = (exp2(-exponent) * F); + // exponent += floor(log2(mantissa)); + vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; + texel.rg = integerMod(texel.rg, 256.0); + texel.b = integerMod(texel.b, 128.0); + texel.a = exponent*0.5 + 63.5; + texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; + texel = floor(texel); + texel *= 0.003921569; // 1/255 + __ENCODE32_ENDIANNESS__; + return texel; +} + +// https://github.com/gpujs/gpu.js/wiki/Encoder-details +vec4 encode32(float value) { + if (value == 0.0) return vec4(0, 0, 0, 0); + + float exponent; + float mantissa; + vec4 result; + float sgn; + + sgn = step(0.0, -value); + value = abs(value); + + exponent = floor(log2(value)); + + mantissa = value*pow(2.0, -exponent)-1.0; + exponent = exponent+127.0; + result = vec4(0,0,0,0); + + result.a = floor(exponent/2.0); + exponent = exponent - result.a*2.0; + result.a = result.a + 128.0*sgn; + + result.b = floor(mantissa * 128.0); + mantissa = mantissa - result.b / 128.0; + result.b = result.b + exponent*128.0; + + result.g = floor(mantissa*32768.0); + mantissa = mantissa - result.g/32768.0; + + result.r = floor(mantissa*8388608.0); + return result/255.0; +} +// Dragons end here + +int index; +ivec3 threadId; + +ivec3 indexTo3D(int idx, ivec3 texDim) { + int z = int(idx / (texDim.x * texDim.y)); + idx -= z * int(texDim.x * texDim.y); + int y = int(idx / texDim.x); + int x = int(integerMod(idx, texDim.x)); + return ivec3(x, y, z); +} + +float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + return decode32(texel); +} + +float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int w = texSize.x * 2; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); + return decode16(texel, index); +} + +float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int w = texSize.x * 4; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); + return decode8(texel, index); +} + +float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int channel = integerMod(index, 4); + index = index / 4; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + index = index / 4; + vec4 texel = texture(tex, st / vec2(texSize)); + return texel[channel]; +} + +vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture(tex, st / vec2(texSize)); +} + +vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture(tex, vec3(st / vec2(texSize), z)); +} + +float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return result[0]; +} + +vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec2(result[0], result[1]); +} + +vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + index = index / 2; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + if (channel == 0) return vec2(texel.r, texel.g); + if (channel == 1) return vec2(texel.b, texel.a); + return vec2(0.0, 0.0); +} + +vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec3(result[0], result[1], result[2]); +} + +vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); + int vectorIndex = fieldIndex / 4; + int vectorOffset = fieldIndex - vectorIndex * 4; + int readY = vectorIndex / texSize.x; + int readX = vectorIndex - readY * texSize.x; + vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); + + if (vectorOffset == 0) { + return tex1.xyz; + } else if (vectorOffset == 1) { + return tex1.yzw; + } else { + readX++; + if (readX >= texSize.x) { + readX = 0; + readY++; + } + vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); + if (vectorOffset == 2) { + return vec3(tex1.z, tex1.w, tex2.x); + } else { + return vec3(tex1.w, tex2.x, tex2.y); + } + } +} + +vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + return getImage2D(tex, texSize, texDim, z, y, x); +} + +vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + return vec4(texel.r, texel.g, texel.b, texel.a); +} + +vec4 actualColor; +void color(float r, float g, float b, float a) { + actualColor = vec4(r,g,b,a); +} + +void color(float r, float g, float b) { + color(r,g,b,1.0); +} + +__INJECTED_NATIVE__; +__MAIN_CONSTANTS__; +__MAIN_ARGUMENTS__; +__KERNEL__; + +void main(void) { + index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; + __MAIN_RESULT__; +}`; - this.kernels.push(kernelRun); + const vertexShader$1 = `#version 300 es +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +in vec2 aPos; +in vec2 aTexCoord; + +out vec2 vTexCoord; +uniform vec2 ratio; + +void main(void) { + gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); + vTexCoord = aTexCoord; +}`; - return kernelRun; - } + class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - createKernelMap() { - let fn; - let settings; - if (typeof arguments[arguments.length - 2] === 'function') { - fn = arguments[arguments.length - 2]; - settings = arguments[arguments.length - 1]; - } else { - fn = arguments[arguments.length - 1]; - } + class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - if (this.mode !== 'dev') { - if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { - if (this.mode && kernelTypes.indexOf(this.mode) < 0) { - throw new Error(`kernelMap not supported on ${this.Kernel.name}`); - } + class WebGL2KernelValueInteger extends WebGLKernelValueInteger { + getSource(value) { + const variablePrecision = this.getVariablePrecisionString(); + if (this.origin === 'constants') { + return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`; } + return `uniform ${ variablePrecision } int ${this.id};\n`; } - - const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings); - if (settings && typeof settings.argumentTypes === 'object') { - settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); } + } - if (Array.isArray(arguments[0])) { - settingsCopy.subKernels = []; - const functions = arguments[0]; - for (let i = 0; i < functions.length; i++) { - const source = functions[i].toString(); - const name = utils.getFunctionNameFromString(source); - settingsCopy.subKernels.push({ - name, - source, - property: i, - }); - } - } else { - settingsCopy.subKernels = []; - const functions = arguments[0]; - for (let p in functions) { - if (!functions.hasOwnProperty(p)) continue; - const source = functions[p].toString(); - const name = utils.getFunctionNameFromString(source); - settingsCopy.subKernels.push({ - name: name || p, - source, - property: p, - }); - } + class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); } - const kernel = this.createKernel(fn, settingsCopy); - - return kernel; } - combineKernels() { - const firstKernel = arguments[0]; - const combinedKernel = arguments[arguments.length - 1]; - if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel; - const canvas = arguments[0].canvas; - const context = arguments[0].context; - const max = arguments.length - 1; - for (let i = 0; i < max; i++) { - arguments[i] - .setCanvas(canvas) - .setContext(context) - .setPipeline(true); + class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); } + } - return function() { - const texture = combinedKernel.apply(this, arguments); - if (texture.toArray) { - return texture.toArray(); + class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.checkSize(value[0].width, value[0].height); + this.requestTexture(); + this.dimensions = [value[0].width, value[0].height, value.length]; + this.textureSize = [value[0].width, value[0].height]; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2DArray ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(images) { + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage3D( + gl.TEXTURE_2D_ARRAY, + 0, + gl.RGBA, + images[0].width, + images[0].height, + images.length, + 0, + gl.RGBA, + gl.UNSIGNED_BYTE, + null + ); + for (let i = 0; i < images.length; i++) { + const xOffset = 0; + const yOffset = 0; + const imageDepth = 1; + gl.texSubImage3D( + gl.TEXTURE_2D_ARRAY, + 0, + xOffset, + yOffset, + i, + images[i].width, + images[i].height, + imageDepth, + gl.RGBA, + gl.UNSIGNED_BYTE, + this.uploadValue = images[i] + ); } - return texture; - }; + this.kernel.setUniform1i(this.id, this.index); + } } - addFunction(source, settings) { - this.functions.push(utils.functionToIFunction(source, settings)); - return this; + class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2DArray ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(images) { + const { width, height } = images[0]; + this.checkSize(width, height); + this.dimensions = [width, height, images.length]; + this.textureSize = [width, height]; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(images); + } } - addNativeFunction(name, source, settings) { - if (this.kernels.length > 0) { - throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); + class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} + + class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} + + class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(input) { + const { context: gl } = this; + utils$1.flattenTo(input.value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); } - settings = settings || {}; - const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; - this.nativeFunctions.push({ - name, - source, - settings, - argumentTypes, - argumentNames, - returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), - }); - return this; } - injectNative(source) { - this.injectedNative = source; - return this; + class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } - destroy() { - if (!this.kernels) return; - setTimeout(() => { - for (let i = 0; i < this.kernels.length; i++) { - this.kernels[i].destroy(true); - } - let firstKernel = this.kernels[0]; - if (firstKernel) { - if (firstKernel.kernel) { - firstKernel = firstKernel.kernel; - } - if (firstKernel.constructor.destroyContext) { - firstKernel.constructor.destroyContext(this.context); - } - } - }, 0); + class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } } -} - -function upgradeDeprecatedCreateKernelSettings(settings) { - if (!settings) { - return {}; + class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } } - const upgradedSettings = Object.assign({}, settings); - if (settings.hasOwnProperty('floatOutput')) { - utils.warnDeprecated('setting', 'floatOutput', 'precision'); - upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; - } - if (settings.hasOwnProperty('outputToTexture')) { - utils.warnDeprecated('setting', 'outputToTexture', 'pipeline'); - upgradedSettings.pipeline = Boolean(settings.outputToTexture); - } - if (settings.hasOwnProperty('outputImmutable')) { - utils.warnDeprecated('setting', 'outputImmutable', 'immutable'); - upgradedSettings.immutable = Boolean(settings.outputImmutable); - } - if (settings.hasOwnProperty('floatTextures')) { - utils.warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); - upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); + class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); + } } - return upgradedSettings; -} - -module.exports = { - GPU, - kernelOrder, - kernelTypes -}; -},{"./backend/cpu/kernel":7,"./backend/headless-gl/kernel":32,"./backend/web-gl/kernel":67,"./backend/web-gl2/kernel":102,"./kernel-run-shortcut":108,"./utils":111,"gpu-mock.js":3}],106:[function(require,module,exports){ -const { GPU } = require('./gpu'); -const { alias } = require('./alias'); -const { utils } = require('./utils'); -const { Input, input } = require('./input'); -const { Texture } = require('./texture'); -const { FunctionBuilder } = require('./backend/function-builder'); -const { FunctionNode } = require('./backend/function-node'); -const { CPUFunctionNode } = require('./backend/cpu/function-node'); -const { CPUKernel } = require('./backend/cpu/kernel'); - -const { HeadlessGLKernel } = require('./backend/headless-gl/kernel'); - -const { WebGLFunctionNode } = require('./backend/web-gl/function-node'); -const { WebGLKernel } = require('./backend/web-gl/kernel'); -const { kernelValueMaps: webGLKernelValueMaps } = require('./backend/web-gl/kernel-value-maps'); - -const { WebGL2FunctionNode } = require('./backend/web-gl2/function-node'); -const { WebGL2Kernel } = require('./backend/web-gl2/kernel'); -const { kernelValueMaps: webGL2KernelValueMaps } = require('./backend/web-gl2/kernel-value-maps'); - -const { GLKernel } = require('./backend/gl/kernel'); - -const { Kernel } = require('./backend/kernel'); - -const { FunctionTracer } = require('./backend/function-tracer'); -module.exports = { - alias, - CPUFunctionNode, - CPUKernel, - GPU, - FunctionBuilder, - FunctionNode, - HeadlessGLKernel, - Input, - input, - Texture, - utils, - - WebGL2FunctionNode, - WebGL2Kernel, - webGL2KernelValueMaps, - - WebGLFunctionNode, - WebGLKernel, - webGLKernelValueMaps, - - GLKernel, - Kernel, - FunctionTracer, -}; -},{"./alias":4,"./backend/cpu/function-node":5,"./backend/cpu/kernel":7,"./backend/function-builder":8,"./backend/function-node":9,"./backend/function-tracer":10,"./backend/gl/kernel":12,"./backend/headless-gl/kernel":32,"./backend/kernel":34,"./backend/web-gl/function-node":36,"./backend/web-gl/kernel":67,"./backend/web-gl/kernel-value-maps":37,"./backend/web-gl2/function-node":70,"./backend/web-gl2/kernel":102,"./backend/web-gl2/kernel-value-maps":71,"./gpu":105,"./input":107,"./texture":110,"./utils":111}],107:[function(require,module,exports){ -class Input { - constructor(value, size) { - this.value = value; - if (Array.isArray(size)) { - this.size = size; - } else { - this.size = new Int32Array(3); - if (size.z) { - this.size = new Int32Array([size.x, size.y, size.z]); - } else if (size.y) { - this.size = new Int32Array([size.x, size.y]); - } else { - this.size = new Int32Array([size.x]); - } + class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); } + } - const [w, h, d] = this.size; - if (d) { - if (this.value.length !== (w * h * d)) { - throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`); - } - } else if (h) { - if (this.value.length !== (w * h)) { - throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`); - } - } else { - if (this.value.length !== w) { - throw new Error(`Input size ${this.value.length} does not match ${w}`); - } + class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); } - } - toArray() { - const { utils } = require('./utils'); - const [w, h, d] = this.size; - if (d) { - return utils.erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); - } else if (h) { - return utils.erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h); - } else { - return this.value; + class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); } } -} - -function input(value, size) { - return new Input(value, size); -} - -module.exports = { - Input, - input -}; -},{"./utils":111}],108:[function(require,module,exports){ -const { utils } = require('./utils'); -function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - if (kernel.renderKernels) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderKernels(); - }; - } else if (kernel.renderOutput) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderOutput(); - }; - } else { - run = function() { - return kernel.run.apply(kernel, arguments); - }; + class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); } - return run.apply(kernel, arguments); - }; - const shortcut = function() { - return run.apply(kernel, arguments); - }; - shortcut.exec = function() { - return new Promise((accept, reject) => { - try { - accept(run.apply(this, arguments)); - } catch (e) { - reject(e); + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; } - }); - }; - shortcut.replaceKernel = function(replacementKernel) { - kernel = replacementKernel; - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - }; + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - return shortcut; -} + class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } -function bindKernelToShortcut(kernel, shortcut) { - const properties = utils.allPropertiesOf(kernel); - for (let i = 0; i < properties.length; i++) { - const property = properties[i]; - if (property[0] === '_' && property[1] === '_') continue; - if (typeof kernel[property] === 'function') { - if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') { - shortcut[property] = function() { - kernel[property].apply(kernel, arguments); - return shortcut; - }; - } else { - if (property === 'toString') { - shortcut.toString = function() { - return kernel.toString.apply(kernel, arguments); - }; - } else { - shortcut[property] = kernel[property].bind(kernel); - } + class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; } - } else { - shortcut.__defineGetter__(property, () => { - return kernel[property]; - }); - shortcut.__defineSetter__(property, (value) => { - kernel[property] = value; - }); + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); } } -} -module.exports = { - kernelRunShortcut -}; -},{"./utils":111}],109:[function(require,module,exports){ -const source = ` - -uniform highp float triangle_noise_seed; -highp float triangle_noise_shift = 0.000001; - -//https://www.shadertoy.com/view/4t2SDh -//note: uniformly distributed, normalized rand, [0;1[ -float nrand( vec2 n ) -{ - return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); -} -//note: remaps v to [0;1] in interval [a;b] -float remap( float a, float b, float v ) -{ - return clamp( (v-a) / (b-a), 0.0, 1.0 ); -} - -float n4rand( vec2 n ) -{ - float t = fract( triangle_noise_seed + triangle_noise_shift ); - float nrnd0 = nrand( n + 0.07*t ); - float nrnd1 = nrand( n + 0.11*t ); - float nrnd2 = nrand( n + 0.13*t ); - float nrnd3 = nrand( n + 0.17*t ); - float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; - triangle_noise_shift = result + 0.000001; - return result; -}`; - -const name = 'triangle-noise-noise'; - -const functionMatch = 'Math.random()'; -const functionReplace = 'n4rand(vTexCoord)'; - -const functionReturnType = 'Number'; - -const onBeforeRun = (kernel) => { - kernel.setUniform1f('triangle_noise_seed', Math.random()); -}; - -module.exports = { - name, - onBeforeRun, - functionMatch, - functionReplace, - functionReturnType, - source -}; -},{}],110:[function(require,module,exports){ -class Texture { - constructor(settings) { - const { - texture, - size, - dimensions, - output, - context, - type = 'NumberTexture', - } = settings; - if (!output) throw new Error('settings property "output" required.'); - if (!context) throw new Error('settings property "context" required.'); - this.texture = texture; - this.size = size; - this.dimensions = dimensions; - this.output = output; - this.context = context; - this.kernel = null; - this.type = type; + class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } - toArray() { - throw new Error(`Not implemented on ${this.constructor.name}`); + class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } } - delete() { - return this.context.deleteTexture(this.texture); + class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } -} - -module.exports = { - Texture -}; -},{}],111:[function(require,module,exports){ -const acorn = require('acorn'); -const { Input } = require('./input'); -const { Texture } = require('./texture'); - -const FUNCTION_NAME = /function ([^(]*)/; -const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; -const ARGUMENT_NAMES = /([^\s,]+)/g; - -const utils = { - systemEndianness() { - return _systemEndianness; - }, - getSystemEndianness() { - const b = new ArrayBuffer(4); - const a = new Uint32Array(b); - const c = new Uint8Array(b); - a[0] = 0xdeadbeef; - if (c[0] === 0xef) return 'LE'; - if (c[0] === 0xde) return 'BE'; - throw new Error('unknown endianness'); - }, - - isFunction(funcObj) { - return typeof(funcObj) === 'function'; - }, - isFunctionString(fn) { - if (typeof fn === 'string') { - return (fn - .slice(0, 'function'.length) - .toLowerCase() === 'function'); + class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} + + class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} + + class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} + + class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + } + + class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + } + + const kernelValueMaps$1 = { + unsigned: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGL2KernelValueDynamicUnsignedInput, + 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGL2KernelValueUnsignedInput, + 'NumberTexture': WebGL2KernelValueNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI, + 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI, + 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI, + 'Input': WebGL2KernelValueDynamicSingleInput, + 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + 'Array1D(2)': WebGL2KernelValueSingleArray1DI, + 'Array1D(3)': WebGL2KernelValueSingleArray1DI, + 'Array1D(4)': WebGL2KernelValueSingleArray1DI, + 'Array2D(2)': WebGL2KernelValueSingleArray2DI, + 'Array2D(3)': WebGL2KernelValueSingleArray2DI, + 'Array2D(4)': WebGL2KernelValueSingleArray2DI, + 'Array3D(2)': WebGL2KernelValueSingleArray3DI, + 'Array3D(3)': WebGL2KernelValueSingleArray3DI, + 'Array3D(4)': WebGL2KernelValueSingleArray3DI, + 'Input': WebGL2KernelValueSingleInput, + 'NumberTexture': WebGL2KernelValueNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + }; + function lookupKernelValueType$1(type, dynamic, precision, value) { + if (!type) { + throw new Error('type missing'); } - return false; - }, - - getFunctionNameFromString(funcStr) { - return FUNCTION_NAME.exec(funcStr)[1].trim(); - }, - - getFunctionBodyFromString(funcStr) { - return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); - }, - - getArgumentNamesFromString(fn) { - const fnStr = fn.replace(STRIP_COMMENTS, ''); - let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); - if (result === null) { - result = []; + if (!dynamic) { + throw new Error('dynamic missing'); + } + if (!precision) { + throw new Error('precision missing'); + } + if (value.type) { + type = value.type; + } + const types = kernelValueMaps$1[precision][dynamic]; + if (types[type] === false) { + return null; + } else if (types[type] === undefined) { + throw new Error(`Could not find a KernelValue for ${ type }`); + } + return types[type]; + } + + let isSupported$1 = null; + let testCanvas$1 = null; + let testContext$1 = null; + let testExtensions$1 = null; + let features$1 = null; + class WebGL2Kernel extends WebGLKernel { + static get isSupported() { + if (isSupported$1 !== null) { + return isSupported$1; + } + this.setupFeatureChecks(); + isSupported$1 = this.isContextMatch(testContext$1); + return isSupported$1; + } + static setupFeatureChecks() { + if (typeof document !== 'undefined') { + testCanvas$1 = document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + testCanvas$1 = new OffscreenCanvas(0, 0); + } + if (!testCanvas$1) return; + testContext$1 = testCanvas$1.getContext('webgl2'); + if (!testContext$1 || !testContext$1.getExtension) return; + testExtensions$1 = { + EXT_color_buffer_float: testContext$1.getExtension('EXT_color_buffer_float'), + OES_texture_float_linear: testContext$1.getExtension('OES_texture_float_linear'), + }; + features$1 = this.getFeatures(); } - return result; - }, - - clone(obj) { - if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj; - - const temp = obj.constructor(); - - for (let key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - obj.isActiveClone = null; - temp[key] = utils.clone(obj[key]); - delete obj.isActiveClone; + static isContextMatch(context) { + if (typeof WebGL2RenderingContext !== 'undefined') { + return context instanceof WebGL2RenderingContext; } + return false; } - - return temp; - }, - - isArray(array) { - return !isNaN(array.length); - }, - - getVariableType(value, strictIntegers) { - if (utils.isArray(value)) { - if (value[0].nodeName === 'IMG') { - return 'HTMLImageArray'; - } - return 'Array'; + static getFeatures() { + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + kernelMap: true, + isTextureFloat: true, + channelCount: this.getChannelCount(), + maxTextureSize: this.getMaxTextureSize(), + }); } - - switch (value.constructor) { - case Boolean: - return 'Boolean'; - case Number: - if (strictIntegers && Number.isInteger(value)) { - return 'Integer'; - } - return 'Float'; - case Texture: - return value.type; - case Input: - return 'Input'; + static getIsTextureFloat() { + return true; } - switch (value.nodeName) { - case 'IMG': - return 'HTMLImage'; - case 'VIDEO': - return 'HTMLVideo'; + static getIsIntegerDivisionAccurate() { + return super.getIsIntegerDivisionAccurate(); } - if (value.hasOwnProperty('type')) { - return value.type; + static getChannelCount() { + return testContext$1.getParameter(testContext$1.MAX_DRAW_BUFFERS); } - return 'Unknown'; - }, - - getKernelTextureSize(settings, dimensions) { - let [w, h, d] = dimensions; - let texelCount = (w || 1) * (h || 1) * (d || 1); - - if (settings.optimizeFloatMemory && settings.precision === 'single') { - w = texelCount = Math.ceil(texelCount / 4); + static getMaxTextureSize() { + return testContext$1.getParameter(testContext$1.MAX_TEXTURE_SIZE); } - if (h > 1 && w * h === texelCount) { - return new Int32Array([w, h]); + static lookupKernelValueType(type, dynamic, precision, value) { + return lookupKernelValueType$1(type, dynamic, precision, value); } - return utils.closestSquareDimensions(texelCount); - }, - - closestSquareDimensions(length) { - const sqrt = Math.sqrt(length); - let high = Math.ceil(sqrt); - let low = Math.floor(sqrt); - while (high * low < length) { - high--; - low = Math.ceil(length / high); - } - return new Int32Array([low, Math.ceil(length / low)]); - }, - - getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) { - const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4); - const texelCount = totalArea / bitRatio; - return utils.closestSquareDimensions(texelCount); - }, - - getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) { - const [w, h, d] = dimensions; - const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4); - const texelCount = totalArea / (4 / bitRatio); - return utils.closestSquareDimensions(texelCount); - }, - - roundTo(n, d) { - return Math.floor((n + d - 1) / d) * d; - }, - getDimensions(x, pad) { - let ret; - if (utils.isArray(x)) { - const dim = []; - let temp = x; - while (utils.isArray(temp)) { - dim.push(temp.length); - temp = temp[0]; - } - ret = dim.reverse(); - } else if (x instanceof Texture) { - ret = x.output; - } else if (x instanceof Input) { - ret = x.size; - } else { - throw new Error(`Unknown dimensions of ${x}`); + static get testCanvas() { + return testCanvas$1; } - - if (pad) { - ret = Array.from(ret); - while (ret.length < 3) { - ret.push(1); - } + static get testContext() { + return testContext$1; } - - return new Int32Array(ret); - }, - - flatten2dArrayTo(array, target) { - let offset = 0; - for (let y = 0; y < array.length; y++) { - target.set(array[y], offset); - offset += array[y].length; + static get features() { + return features$1; } - }, - - flatten3dArrayTo(array, target) { - let offset = 0; - for (let z = 0; z < array.length; z++) { - for (let y = 0; y < array[z].length; y++) { - target.set(array[z][y], offset); - offset += array[z][y].length; + static get fragmentShader() { + return fragmentShader$1; + } + static get vertexShader() { + return vertexShader$1; + } + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + const context = this.canvas.getContext('webgl2', settings); + return context; + } + initExtensions() { + this.extensions = { + EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'), + OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), + }; + } + validateSettings(args) { + if (!this.validate) { + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + return; + } + const features = this.constructor.features; + if (this.precision === 'single' && !features.isFloatRead) { + throw new Error('Float texture outputs are not supported'); + } else if (!this.graphical && this.precision === null) { + this.precision = features.isFloatRead ? 'single' : 'unsigned'; + } + if (this.fixIntegerDivisionAccuracy === null) { + this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; + } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { + this.fixIntegerDivisionAccuracy = false; + } + this.checkOutput(); + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + const argType = utils$1.getVariableType(args[0], this.strictIntegers); + switch (argType) { + case 'Array': + this.output = utils$1.getDimensions(argType); + break; + case 'NumberTexture': + case 'MemoryOptimizedNumberTexture': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + this.output = args[0].output; + break; + default: + throw new Error('Auto output not supported for input type: ' + argType); + } + } + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); + } + if (this.precision === 'single') { + console.warn('Cannot use graphical mode and single precision at the same time'); + this.precision = 'unsigned'; + } + this.texSize = utils$1.clone(this.output); + return; + } else if (!this.graphical && this.precision === null && features.isTextureFloat) { + this.precision = 'single'; } + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + this.checkTextureSize(); } - }, - - flatten4dArrayTo(array, target) { - let offset = 0; - for (let l = 0; l < array.length; l++) { - for (let z = 0; z < array[l].length; z++) { - for (let y = 0; y < array[l][z].length; y++) { - target.set(array[l][z][y], offset); - offset += array[l][z][y].length; + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + if (this.subKernels && this.subKernels.length > 0) { + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (!subKernel.returnType) { + subKernel.returnType = functionBuilder.getSubKernelResultType(i); + } } } } - }, - - flattenTo(array, target) { - if (utils.isArray(array[0])) { - if (utils.isArray(array[0][0])) { - if (utils.isArray(array[0][0][0])) { - utils.flatten4dArrayTo(array, target); + run() { + const { kernelArguments, texSize, forceUploadKernelConstants } = this; + const gl = this.context; + gl.useProgram(this.program); + gl.scissor(0, 0, texSize[0], texSize[1]); + if (this.dynamicOutput) { + this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); + this.setUniform2iv('uTexSize', texSize); + } + this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); + this.switchingKernels = false; + for (let i = 0; i < forceUploadKernelConstants.length; i++) { + const constant = forceUploadKernelConstants[i]; + constant.updateValue(this.constants[constant.name]); + if (this.switchingKernels) return; + } + for (let i = 0; i < kernelArguments.length; i++) { + kernelArguments[i].updateValue(arguments[i]); + if (this.switchingKernels) return; + } + if (this.plugins) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.onBeforeRun) { + plugin.onBeforeRun(this); + } + } + } + if (this.graphical) { + if (this.pipeline) { + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (!this.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context + }); + } + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return; + } + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (this.immutable) { + this._setupOutputTexture(); + } + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + gl.drawBuffers(this.drawBuffersMap); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + drawBuffers() { + this.context.drawBuffers(this.drawBuffersMap); + } + getOutputTexture() { + return this.outputTexture; + } + _setupOutputTexture() { + const { texSize } = this; + const gl = this.context; + const texture = this.outputTexture = gl.createTexture(); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + } else { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + } + break; + case 'Array(2)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + break; + case 'Array(3)': + case 'Array(4)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + break; + default: + throw new Error('Unhandled return type'); + } } else { - utils.flatten3dArrayTo(array, target); + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); } } else { - utils.flatten2dArrayTo(array, target); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); } - } else { - target.set(array); - } - }, - - splitArray(array, part) { - const result = []; - for (let i = 0; i < array.length; i += part) { - result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part)); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); } - return result; - }, - - getAstString(source, ast) { - const lines = Array.isArray(source) ? source : source.split(/\r?\n/g); - const start = ast.loc.start; - const end = ast.loc.end; - const result = []; - if (start.line === end.line) { - result.push(lines[start.line - 1].substring(start.column, end.column)); - } else { - result.push(lines[start.line - 1].slice(start.column)); - for (let i = start.line; i < end.line; i++) { - result.push(lines[i]); + _setupSubOutputTextures() { + const { texSize } = this; + const gl = this.context; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; + for (let i = 0; i < this.subKernels.length; i++) { + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); } - result.push(lines[end.line - 1].slice(0, end.column)); } - return result.join('\n'); - }, - - allPropertiesOf(obj) { - const props = []; - - do { - props.push.apply(props, Object.getOwnPropertyNames(obj)); - } while (obj = Object.getPrototypeOf(obj)); - - return props; - }, - - linesToString(lines) { - if (lines.length > 0) { - return lines.join(';\n') + ';\n'; - } else { - return '\n'; + _getHeaderString() { + return ''; } - }, - warnDeprecated(type, oldName, newName) { - if (newName) { - console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been replaced with "${ newName }". Fixing, but please upgrade as it will soon be removed.`); - } else { - console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been removed. Fixing, but please upgrade as it will soon be removed.`); + _getTextureCoordinate() { + const subKernels = this.subKernels; + if (subKernels === null || subKernels.length < 1) { + switch (this.tactic) { + case 'speed': + return 'in lowp vec2 vTexCoord;\n'; + case 'performance': + return 'in highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'in mediump vec2 vTexCoord;\n'; + } + } else { + switch (this.tactic) { + case 'speed': + return 'out lowp vec2 vTexCoord;\n'; + case 'performance': + return 'out highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'out mediump vec2 vTexCoord;\n'; + } + } } - }, - functionToIFunction(source, settings) { - settings = settings || {}; - if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function'); - const sourceString = typeof source === 'string' ? source : source.toString(); - - let argumentTypes = []; - - if (Array.isArray(settings.argumentTypes)) { - argumentTypes = settings.argumentTypes; - } else if (typeof settings.argumentTypes === 'object') { - argumentTypes = utils.getArgumentNamesFromString(sourceString) - .map(name => settings.argumentTypes[name]) || []; - } else { - argumentTypes = settings.argumentTypes || []; + _getMainArgumentsString(args) { + const result = []; + const argumentNames = this.argumentNames; + for (let i = 0; i < argumentNames.length; i++) { + result.push(this.kernelArguments[i].getSource(args[i])); + } + return result.join(''); } - - return { - source: sourceString, - argumentTypes, - returnType: settings.returnType || null, - }; - }, - flipPixels: (pixels, width, height) => { - const halfHeight = height / 2 | 0; - const bytesPerRow = width * 4; - const temp = new Uint8ClampedArray(width * 4); - const result = pixels.slice(0); - for (let y = 0; y < halfHeight; ++y) { - const topOffset = y * bytesPerRow; - const bottomOffset = (height - y - 1) * bytesPerRow; - - temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); - - result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); - - result.set(temp, bottomOffset); + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration, + 'layout(location = 0) out vec4 data0' + ); + for (let i = 0; i < subKernels.length; i++) { + const subKernel = subKernels[i]; + result.push( + subKernel.returnType === 'Integer' ? + `int subKernelResult_${ subKernel.name } = 0` : + `float subKernelResult_${ subKernel.name } = 0.0`, + `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }` + ); + } + } else { + result.push( + 'out vec4 data0', + kernelResultDeclaration + ); + } + return utils$1.linesToString(result) + this.translatedSource; } - return result; - }, - erectPackedFloat: (array, width) => { - return array.subarray(0, width); - }, - erect2DPackedFloat: (array, width, height) => { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xStart = y * width; - const xEnd = xStart + width; - yResults[y] = array.subarray(xStart, xEnd); + getMainResultGraphical() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0 = actualColor', + ]); } - return yResults; - }, - erect3DPackedFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xStart = (z * height * width) + y * width; - const xEnd = xStart + width; - yResults[y] = array.subarray(xStart, xEnd); + getMainResultPackedPixels() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return this.getMainResultKernelPackedPixels() + + this.getMainResultSubKernelPackedPixels(); + default: + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); } - zResults[z] = yResults; } - return zResults; - }, - erectMemoryOptimizedFloat: (array, width) => { - return array.subarray(0, width); - }, - erectMemoryOptimized2DFloat: (array, width, height) => { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const offset = y * width; - yResults[y] = array.subarray(offset, offset + width); + getMainResultKernelPackedPixels() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); } - return yResults; - }, - erectMemoryOptimized3DFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const offset = (z * height * width) + (y * width); - yResults[y] = array.subarray(offset, offset + width); + getMainResultSubKernelPackedPixels() { + const result = []; + if (!this.subKernels) return ''; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` + ); + } else { + result.push( + ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` + ); + } + } + return utils$1.linesToString(result); + } + getMainResultMemoryOptimizedFloats() { + const result = [ + ' index *= 4', + ]; + switch (this.returnType) { + case 'Number': + case 'Integer': + case 'Float': + const channels = ['r', 'g', 'b', 'a']; + for (let i = 0; i < channels.length; i++) { + const channel = channels[i]; + this.getMainResultKernelMemoryOptimizedFloats(result, channel); + this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); + if (i + 1 < channels.length) { + result.push(' index += 1'); + } + } + break; + default: + throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); } - zResults[z] = yResults; + return utils$1.linesToString(result); } - return zResults; - }, - erectFloat: (array, width) => { - const xResults = new Float32Array(width); - let i = 0; - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; - } - return xResults; - }, - erect2DFloat: (array, width, height) => { - const yResults = new Array(height); - let i = 0; - for (let y = 0; y < height; y++) { - const xResults = new Float32Array(width); - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; - } - yResults[y] = xResults; + getMainResultKernelMemoryOptimizedFloats(result, channel) { + result.push( + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0.${channel} = kernelResult`, + ); } - return yResults; - }, - erect3DFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - let i = 0; - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Float32Array(width); - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; + getMainResultSubKernelMemoryOptimizedFloats(result, channel) { + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`, + ); } - yResults[y] = xResults; } - zResults[z] = yResults; } - return zResults; - }, - erectArray2: (array, width) => { - const xResults = new Array(width); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 2); - } - return xResults; - }, - erect2DArray2: (array, width, height) => { - const yResults = new Array(height); - const XResultsMax = width * 4; - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * XResultsMax; - let i = 0; - for (let x = 0; x < XResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 2); - } - yResults[y] = xResults; + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult', + ]; } - return yResults; - }, - erect3DArray2: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 2); + getMainResultSubKernelNumberTexture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}`, + ); } - yResults[y] = xResults; } - zResults[z] = yResults; + return result; } - return zResults; - }, - erectArray3: (array, width) => { - const xResults = new Array(width); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 3); - } - return xResults; - }, - erect2DArray3: (array, width, height) => { - const xResultsMax = width * 4; - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * xResultsMax; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 3); + getMainResultKernelArray2Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult[0]', + ' data0[1] = kernelResult[1]', + ]; + } + getMainResultSubKernelArray2Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, + ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, + ); } - yResults[y] = xResults; + return result; } - return yResults; - }, - erect3DArray3: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 3); - } - yResults[y] = xResults; + getMainResultKernelArray3Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult[0]', + ' data0[1] = kernelResult[1]', + ' data0[2] = kernelResult[2]', + ]; + } + getMainResultSubKernelArray3Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, + ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, + ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`, + ); } - zResults[z] = yResults; + return result; } - return zResults; - }, - erectArray4: (array, width) => { - const xResults = new Array(array); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 4); - } - return xResults; - }, - erect2DArray4: (array, width, height) => { - const xResultsMax = width * 4; - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * xResultsMax; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 4); + getMainResultKernelArray4Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0 = kernelResult', + ]; + } + getMainResultSubKernelArray4Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`, + ); } - yResults[y] = xResults; + return result; } - return yResults; - }, - erect3DArray4: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 4); + destroyExtensions() { + this.extensions.EXT_color_buffer_float = null; + this.extensions.OES_texture_float_linear = null; + } + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON(); + return json; + } + } + + function kernelRunShortcut(kernel) { + let run = function() { + kernel.build.apply(kernel, arguments); + if (kernel.renderKernels) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderKernels(); + }; + } else if (kernel.renderOutput) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderOutput(); + }; + } else { + run = function() { + return kernel.run.apply(kernel, arguments); + }; + } + return run.apply(kernel, arguments); + }; + const shortcut = function() { + return run.apply(kernel, arguments); + }; + shortcut.exec = function() { + return new Promise((accept, reject) => { + try { + accept(run.apply(this, arguments)); + } catch (e) { + reject(e); } - yResults[y] = xResults; + }); + }; + shortcut.replaceKernel = function(replacementKernel) { + kernel = replacementKernel; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + }; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + return shortcut; + } + function bindKernelToShortcut(kernel, shortcut) { + const properties = utils$1.allPropertiesOf(kernel); + for (let i = 0; i < properties.length; i++) { + const property = properties[i]; + if (property[0] === '_' && property[1] === '_') continue; + if (typeof kernel[property] === 'function') { + if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') { + shortcut[property] = function() { + kernel[property].apply(kernel, arguments); + return shortcut; + }; + } else { + if (property === 'toString') { + shortcut.toString = function() { + return kernel.toString.apply(kernel, arguments); + }; + } else { + shortcut[property] = kernel[property].bind(kernel); + } + } + } else { + shortcut.__defineGetter__(property, () => { + return kernel[property]; + }); + shortcut.__defineSetter__(property, (value) => { + kernel[property] = value; + }); } - zResults[z] = yResults; } - return zResults; - }, - - flattenFunctionToString: (source, settings) => { - const { findDependency, thisLookup, doNotDefine } = settings; - let flattened = settings.flattened; - if (!flattened) { - flattened = settings.flattened = {}; - } - const ast = acorn.parse(source); - const functionDependencies = []; + } - function flatten(ast) { - if (Array.isArray(ast)) { - const results = []; - for (let i = 0; i < ast.length; i++) { - results.push(flatten(ast[i])); + const kernelOrder = [ WebGL2Kernel, WebGLKernel ]; + const kernelTypes = [ 'gpu', 'cpu' ]; + const internalKernels = { + 'webgl2': WebGL2Kernel, + 'webgl': WebGLKernel, + }; + let validate = true; + class GPU { + static disableValidation() { + validate = false; + } + static enableValidation() { + validate = true; + } + static get isGPUSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported); + } + static get isKernelMapSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); + } + static get isOffscreenCanvasSupported() { + return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined'; + } + static get isWebGLSupported() { + return WebGLKernel.isSupported; + } + static get isWebGL2Supported() { + return WebGL2Kernel.isSupported; + } + static get isHeadlessGLSupported() { + return false; + } + static get isCanvasSupported() { + return typeof HTMLCanvasElement !== 'undefined'; + } + static get isGPUHTMLImageArraySupported() { + return WebGL2Kernel.isSupported; + } + static get isSinglePrecisionSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + } + constructor(settings) { + settings = settings || {}; + this.canvas = settings.canvas || null; + this.context = settings.context || null; + this.mode = settings.mode; + this.Kernel = null; + this.kernels = []; + this.functions = []; + this.nativeFunctions = []; + this.injectedNative = null; + if (this.mode === 'dev') return; + this.chooseKernel(); + if (settings.functions) { + for (let i = 0; i < settings.functions.length; i++) { + this.addFunction(settings.functions[i]); } - return results.join(''); } - switch (ast.type) { - case 'Program': - return flatten(ast.body); - case 'FunctionDeclaration': - return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; - case 'BlockStatement': { - const result = []; - for (let i = 0; i < ast.body.length; i++) { - result.push(flatten(ast.body[i]), ';\n'); - } - return `{\n${result.join('')}}`; + if (settings.nativeFunctions) { + for (const p in settings.nativeFunctions) { + this.addNativeFunction(p, settings.nativeFunctions[p]); } - case 'VariableDeclaration': - switch (ast.declarations[0].id.type) { - case 'ObjectPattern': { - const source = flatten(ast.declarations[0].init); - const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; - if (/this/.test(source)) { - const result = []; - const lookups = properties.map(thisLookup); - for (let i = 0; i < lookups.length; i++) { - const lookup = lookups[i]; - if (lookup === null) continue; - const property = properties[i]; - result.push(`${ast.kind} ${ property } = ${ lookup };\n`); - } - - return result.join(''); - } - return `${ast.kind} { ${properties} } = ${source}`; + } + } + getValidate() { + return validate; + } + chooseKernel() { + if (this.Kernel) return; + let Kernel = null; + if (this.context) { + for (let i = 0; i < kernelOrder.length; i++) { + const ExternalKernel = kernelOrder[i]; + if (ExternalKernel.isContextMatch(this.context)) { + if (!ExternalKernel.isSupported) { + throw new Error(`Kernel type ${ExternalKernel.name} not supported`); } - case 'ArrayPattern': - return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; - } - if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { - return ''; - } - return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`; - case 'CallExpression': { - if (ast.callee.property.name === 'subarray') { - return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } - if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') { - return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } - if (ast.callee.object.type === 'ThisExpression') { - functionDependencies.push(findDependency('this', ast.callee.property.name)); - return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } else if (ast.callee.object.name) { - const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name); - if (foundSource === null) { - return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } else { - functionDependencies.push(foundSource); - return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + Kernel = ExternalKernel; + break; + } + } + if (Kernel === null) { + throw new Error('unknown Context'); + } + } else if (this.mode) { + if (this.mode in internalKernels) { + if (!validate || internalKernels[this.mode].isSupported) { + Kernel = internalKernels[this.mode]; + } + } else if (this.mode === 'gpu') { + for (let i = 0; i < kernelOrder.length; i++) { + if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; } - } else if (ast.callee.object.type === 'MemberExpression') { - return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + } else if (this.mode === 'cpu') { + Kernel = CPUKernel; + } + if (!Kernel) { + throw new Error(`A requested mode of "${this.mode}" and is not supported`); + } + } else { + for (let i = 0; i < kernelOrder.length; i++) { + if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + } + if (!Kernel) { + Kernel = CPUKernel; + } + } + if (!this.mode) { + this.mode = Kernel.mode; + } + this.Kernel = Kernel; + } + createKernel(source, settings) { + if (typeof source === 'undefined') { + throw new Error('Missing source parameter'); + } + if (typeof source !== 'object' && !isFunction(source) && typeof source !== 'string') { + throw new Error('source parameter not a function'); + } + if (this.mode === 'dev') { + const devKernel = gpuMock_js_1(source, upgradeDeprecatedCreateKernelSettings(settings)); + this.kernels.push(devKernel); + return devKernel; + } + source = typeof source === 'function' ? source.toString() : source; + const switchableKernels = {}; + const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {}; + if (settings && typeof settings.argumentTypes === 'object') { + settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + } + function onRequestFallback(args) { + const fallbackKernel = new CPUKernel(source, { + argumentTypes: kernelRun.argumentTypes, + constantTypes: kernelRun.constantTypes, + graphical: kernelRun.graphical, + loopMaxIterations: kernelRun.loopMaxIterations, + constants: kernelRun.constants, + dynamicOutput: kernelRun.dynamicOutput, + dynamicArgument: kernelRun.dynamicArguments, + output: kernelRun.output, + precision: kernelRun.precision, + pipeline: kernelRun.pipeline, + immutable: kernelRun.immutable, + optimizeFloatMemory: kernelRun.optimizeFloatMemory, + fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy, + functions: kernelRun.functions, + nativeFunctions: kernelRun.nativeFunctions, + injectedNative: kernelRun.injectedNative, + subKernels: kernelRun.subKernels, + strictIntegers: kernelRun.strictIntegers, + debug: kernelRun.debug, + warnVarUsage: kernelRun.warnVarUsage, + }); + fallbackKernel.build.apply(fallbackKernel, args); + const result = fallbackKernel.run.apply(fallbackKernel, args); + kernelRun.replaceKernel(fallbackKernel); + return result; + } + function onRequestSwitchKernel(args, kernel) { + const argumentTypes = new Array(args.length); + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + const type = kernel.argumentTypes[i]; + if (arg.type) { + argumentTypes[i] = arg.type; } else { - throw new Error('unknown ast.callee'); + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'ArrayTexture(1)': + argumentTypes[i] = getVariableType(arg); + break; + default: + argumentTypes[i] = type; + } } } - case 'ReturnStatement': - return `return ${flatten(ast.argument)}`; - case 'BinaryExpression': - return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`; - case 'UnaryExpression': - if (ast.prefix) { - return `${ast.operator} ${flatten(ast.argument)}`; + const signature = argumentTypes.join(','); + const existingKernel = switchableKernels[signature]; + if (existingKernel) { + existingKernel.run.apply(existingKernel, args); + if (existingKernel.renderKernels) { + return existingKernel.renderKernels(); } else { - return `${flatten(ast.argument)} ${ast.operator}`; + return existingKernel.renderOutput(); } - case 'ExpressionStatement': - return `(${flatten(ast.expression)})`; - case 'ArrowFunctionExpression': - return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`; - case 'Literal': - return ast.raw; - case 'Identifier': - return ast.name; - case 'MemberExpression': - if (ast.object.type === 'ThisExpression') { - return thisLookup(ast.property.name); - } - if (ast.computed) { - return `${flatten(ast.object)}[${flatten(ast.property)}]`; - } - return flatten(ast.object) + '.' + flatten(ast.property); - case 'ThisExpression': - return 'this'; - case 'NewExpression': - return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - case 'ForStatement': - return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`; - case 'AssignmentExpression': - return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`; - case 'UpdateExpression': - return `${flatten(ast.argument)}${ast.operator}`; - case 'IfStatement': - return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`; - case 'ThrowStatement': - return `throw ${flatten(ast.argument)}`; - case 'ObjectPattern': - return ast.properties.map(flatten).join(', '); - case 'ArrayPattern': - return ast.elements.map(flatten).join(', '); - case 'DebuggerStatement': - return 'debugger;'; - case 'ConditionalExpression': - return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`; - case 'Property': - if (ast.kind === 'init') { - return flatten(ast.key); - } + } + const newKernel = switchableKernels[signature] = new kernel.constructor(source, { + argumentTypes, + constantTypes: kernel.constantTypes, + graphical: kernel.graphical, + loopMaxIterations: kernel.loopMaxIterations, + constants: kernel.constants, + dynamicOutput: kernel.dynamicOutput, + dynamicArgument: kernel.dynamicArguments, + context: kernel.context, + canvas: kernel.canvas, + output: kernel.output, + precision: kernel.precision, + pipeline: kernel.pipeline, + immutable: kernel.immutable, + optimizeFloatMemory: kernel.optimizeFloatMemory, + fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy, + functions: kernel.functions, + nativeFunctions: kernel.nativeFunctions, + injectedNative: kernel.injectedNative, + subKernels: kernel.subKernels, + strictIntegers: kernel.strictIntegers, + debug: kernel.debug, + gpu: kernel.gpu, + validate, + warnVarUsage: kernel.warnVarUsage, + returnType: kernel.returnType, + onRequestFallback, + onRequestSwitchKernel, + }); + newKernel.build.apply(newKernel, args); + newKernel.run.apply(newKernel, args); + kernelRun.replaceKernel(newKernel); + if (newKernel.renderKernels) { + return newKernel.renderKernels(); + } else { + return newKernel.renderOutput(); + } + } + const mergedSettings = Object.assign({ + context: this.context, + canvas: this.canvas, + functions: this.functions, + nativeFunctions: this.nativeFunctions, + injectedNative: this.injectedNative, + gpu: this, + validate, + onRequestFallback, + onRequestSwitchKernel + }, settingsCopy); + const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); + if (!this.canvas) { + this.canvas = kernelRun.canvas; + } + if (!this.context) { + this.context = kernelRun.context; + } + this.kernels.push(kernelRun); + return kernelRun; + } + createKernelMap() { + let fn; + let settings; + if (typeof arguments[arguments.length - 2] === 'function') { + fn = arguments[arguments.length - 2]; + settings = arguments[arguments.length - 1]; + } else { + fn = arguments[arguments.length - 1]; } - throw new Error(`unhandled ast.type of ${ ast.type }`); + if (this.mode !== 'dev') { + if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { + if (this.mode && kernelTypes.indexOf(this.mode) < 0) { + throw new Error(`kernelMap not supported on ${this.Kernel.name}`); + } + } + } + const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings); + if (settings && typeof settings.argumentTypes === 'object') { + settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + } + if (Array.isArray(arguments[0])) { + settingsCopy.subKernels = []; + const functions = arguments[0]; + for (let i = 0; i < functions.length; i++) { + const source = functions[i].toString(); + const name = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name, + source, + property: i, + }); + } + } else { + settingsCopy.subKernels = []; + const functions = arguments[0]; + for (let p in functions) { + if (!functions.hasOwnProperty(p)) continue; + const source = functions[p].toString(); + const name = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name: name || p, + source, + property: p, + }); + } + } + const kernel = this.createKernel(fn, settingsCopy); + return kernel; } - const result = flatten(ast); - if (functionDependencies.length > 0) { - const flattenedFunctionDependencies = []; - for (let i = 0; i < functionDependencies.length; i++) { - const functionDependency = functionDependencies[i]; - if (!flattened[functionDependency]) { - flattened[functionDependency] = true; + combineKernels() { + const firstKernel = arguments[0]; + const combinedKernel = arguments[arguments.length - 1]; + if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel; + const canvas = arguments[0].canvas; + const context = arguments[0].context; + const max = arguments.length - 1; + for (let i = 0; i < max; i++) { + arguments[i] + .setCanvas(canvas) + .setContext(context) + .setPipeline(true); + } + return function() { + const texture = combinedKernel.apply(this, arguments); + if (texture.toArray) { + return texture.toArray(); } - flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\n'); + return texture; + }; + } + addFunction(source, settings) { + this.functions.push(functionToIFunction(source, settings)); + return this; + } + addNativeFunction(name, source, settings) { + if (this.kernels.length > 0) { + throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); } - return flattenedFunctionDependencies.join('') + result; + settings = settings || {}; + const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; + this.nativeFunctions.push({ + name, + source, + settings, + argumentTypes, + argumentNames, + returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), + }); + return this; + } + injectNative(source) { + this.injectedNative = source; + return this; + } + destroy() { + if (!this.kernels) return; + setTimeout(() => { + for (let i = 0; i < this.kernels.length; i++) { + this.kernels[i].destroy(true); + } + let firstKernel = this.kernels[0]; + if (firstKernel) { + if (firstKernel.kernel) { + firstKernel = firstKernel.kernel; + } + if (firstKernel.constructor.destroyContext) { + firstKernel.constructor.destroyContext(this.context); + } + } + }, 0); } - return result; - }, - - splitHTMLImageToRGB: (image, mode) => { - const gpu = new GPU({ mode }); - - const rKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.r * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const gKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.g * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const bKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.b * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const aKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.a * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const result = [ - rKernel(image), - gKernel(image), - bKernel(image), - aKernel(image), - ]; - result.rKernel = rKernel; - result.gKernel = gKernel; - result.bKernel = bKernel; - result.aKernel = aKernel; - result.gpu = gpu; - return result; - }, - - splitRGBAToCanvases: (rgba, width, height, mode) => { - const { GPU } = require('./gpu.js'); - - const visualGPUR = new GPU({ mode }); - const visualKernelR = visualGPUR.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(pixel.r / 255, 0, 0, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelR(rgba); - - const visualGPUG = new GPU({ mode }); - const visualKernelG = visualGPUG.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(0, pixel.g / 255, 0, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelG(rgba); - - const visualGPUB = new GPU({ mode }); - const visualKernelB = visualGPUB.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(0, 0, pixel.b / 255, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelB(rgba); - - const visualGPUA = new GPU({ mode }); - const visualKernelA = visualGPUA.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(255, 255, 255, pixel.a / 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelA(rgba); - - visualGPUR.destroy(); - visualGPUG.destroy(); - visualGPUB.destroy(); - visualGPUA.destroy(); - - return [ - visualKernelR.canvas, - visualKernelG.canvas, - visualKernelB.canvas, - visualKernelA.canvas, - ]; } -}; + function upgradeDeprecatedCreateKernelSettings(settings) { + if (!settings) { + return {}; + } + const upgradedSettings = Object.assign({}, settings); + if (settings.hasOwnProperty('floatOutput')) { + warnDeprecated('setting', 'floatOutput', 'precision'); + upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; + } + if (settings.hasOwnProperty('outputToTexture')) { + warnDeprecated('setting', 'outputToTexture', 'pipeline'); + upgradedSettings.pipeline = Boolean(settings.outputToTexture); + } + if (settings.hasOwnProperty('outputImmutable')) { + warnDeprecated('setting', 'outputImmutable', 'immutable'); + upgradedSettings.immutable = Boolean(settings.outputImmutable); + } + if (settings.hasOwnProperty('floatTextures')) { + warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); + upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); + } + return upgradedSettings; + } -const _systemEndianness = utils.getSystemEndianness(); + function alias(name, source) { + const fnString = source.toString(); + return new Function(`return function ${ name } (${ utils$1.getArgumentNamesFromString(fnString).join(', ') }) { + ${ utils$1.getFunctionBodyFromString(fnString) } +}`)(); + } -module.exports = { - utils -}; -},{"./gpu.js":105,"./input":107,"./texture":110,"acorn":1}]},{},[104])(104) -}); + class HeadlessGLKernel extends WebGLKernel { + static get isSupported() { return false } + static isContextMatch() { return false } + static getIsTextureFloat() { return false } + static getIsDrawBuffers() { return false } + static getChannelCount() { return 1 } + static get testCanvas() { return null } + static get testContext() { return null } + static get features() { return null } + static setupFeatureChecks() {} + static destroyContext() {} + initCanvas() { return {} } + initContext() { return null } + toString() { return '' } + initExtensions() {} + build() {} + destroyExtensions() {} + setOutput() {} + static getFeatures() { + return Object.freeze({ + isFloatRead: false, + isIntegerDivisionAccurate: false, + isTextureFloat: false, + isDrawBuffers: false, + kernelMap: false, + channelCount: 1, + }); + } + }const lib = GPU; + lib.alias = alias; + lib.CPUFunctionNode = CPUFunctionNode; + lib.CPUKernel = CPUKernel; + lib.FunctionBuilder = FunctionBuilder; + lib.FunctionNode = FunctionNode; + lib.HeadlessGLKernel = HeadlessGLKernel; + lib.Input = Input; + lib.input = input; + lib.Texture = Texture; + lib.utils = { ...common, ...utils$1 }; + lib.WebGL2FunctionNode = WebGL2FunctionNode; + lib.WebGL2Kernel = WebGL2Kernel; + lib.WebGLFunctionNode = WebGLFunctionNode; + lib.WebGLKernel = WebGLKernel; + lib.GLKernel = GLKernel; + lib.Kernel = Kernel; + + return lib; + +}(acorn)); +//# sourceMappingURL=gpu-browser-core.js.map diff --git a/dist/gpu-browser-core.js.map b/dist/gpu-browser-core.js.map new file mode 100644 index 00000000..8e8e4f3d --- /dev/null +++ b/dist/gpu-browser-core.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gpu-browser-core.js","sources":["../node_modules/gpu-mock.js/index.js","../src/common.js","../src/input.js","../src/texture.js","../src/utils.js","../src/backend/kernel.js","../src/backend/function-builder.js","../src/backend/function-tracer.js","../src/backend/function-node.js","../src/backend/cpu/function-node.js","../src/backend/cpu/kernel-string.js","../src/backend/cpu/kernel.js","../src/backend/gl/texture/float.js","../src/backend/gl/texture/array-2-float.js","../src/backend/gl/texture/array-2-float-2d.js","../src/backend/gl/texture/array-2-float-3d.js","../src/backend/gl/texture/array-3-float.js","../src/backend/gl/texture/array-3-float-2d.js","../src/backend/gl/texture/array-3-float-3d.js","../src/backend/gl/texture/array-4-float.js","../src/backend/gl/texture/array-4-float-2d.js","../src/backend/gl/texture/array-4-float-3d.js","../src/backend/gl/texture/float-2d.js","../src/backend/gl/texture/float-3d.js","../src/backend/gl/texture/memory-optimized.js","../src/backend/gl/texture/memory-optimized-2d.js","../src/backend/gl/texture/memory-optimized-3d.js","../src/backend/gl/texture/unsigned.js","../src/backend/gl/texture/unsigned-2d.js","../src/backend/gl/texture/unsigned-3d.js","../src/backend/gl/texture/graphical.js","../src/backend/gl/kernel.js","../src/backend/web-gl/function-node.js","../src/plugins/triangle-noise.js","../src/backend/web-gl/fragment-shader.js","../src/backend/web-gl/vertex-shader.js","../node_modules/gl-wiretap/index.js","../src/backend/gl/kernel-string.js","../src/backend/kernel-value.js","../src/backend/web-gl/kernel-value/index.js","../src/backend/web-gl/kernel-value/boolean.js","../src/backend/web-gl/kernel-value/float.js","../src/backend/web-gl/kernel-value/integer.js","../src/backend/web-gl/kernel-value/html-image.js","../src/backend/web-gl/kernel-value/dynamic-html-image.js","../src/backend/web-gl/kernel-value/html-video.js","../src/backend/web-gl/kernel-value/dynamic-html-video.js","../src/backend/web-gl/kernel-value/single-input.js","../src/backend/web-gl/kernel-value/dynamic-single-input.js","../src/backend/web-gl/kernel-value/unsigned-input.js","../src/backend/web-gl/kernel-value/dynamic-unsigned-input.js","../src/backend/web-gl/kernel-value/memory-optimized-number-texture.js","../src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js","../src/backend/web-gl/kernel-value/number-texture.js","../src/backend/web-gl/kernel-value/dynamic-number-texture.js","../src/backend/web-gl/kernel-value/single-array.js","../src/backend/web-gl/kernel-value/dynamic-single-array.js","../src/backend/web-gl/kernel-value/single-array1d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js","../src/backend/web-gl/kernel-value/single-array2d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js","../src/backend/web-gl/kernel-value/single-array3d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js","../src/backend/web-gl/kernel-value/single-array2.js","../src/backend/web-gl/kernel-value/single-array3.js","../src/backend/web-gl/kernel-value/single-array4.js","../src/backend/web-gl/kernel-value/unsigned-array.js","../src/backend/web-gl/kernel-value/dynamic-unsigned-array.js","../src/backend/web-gl/kernel-value-maps.js","../src/backend/web-gl/kernel.js","../src/backend/web-gl2/function-node.js","../src/backend/web-gl2/fragment-shader.js","../src/backend/web-gl2/vertex-shader.js","../src/backend/web-gl2/kernel-value/boolean.js","../src/backend/web-gl2/kernel-value/float.js","../src/backend/web-gl2/kernel-value/integer.js","../src/backend/web-gl2/kernel-value/html-image.js","../src/backend/web-gl2/kernel-value/dynamic-html-image.js","../src/backend/web-gl2/kernel-value/html-image-array.js","../src/backend/web-gl2/kernel-value/dynamic-html-image-array.js","../src/backend/web-gl2/kernel-value/html-video.js","../src/backend/web-gl2/kernel-value/dynamic-html-video.js","../src/backend/web-gl2/kernel-value/single-input.js","../src/backend/web-gl2/kernel-value/dynamic-single-input.js","../src/backend/web-gl2/kernel-value/unsigned-input.js","../src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js","../src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js","../src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js","../src/backend/web-gl2/kernel-value/number-texture.js","../src/backend/web-gl2/kernel-value/dynamic-number-texture.js","../src/backend/web-gl2/kernel-value/single-array.js","../src/backend/web-gl2/kernel-value/dynamic-single-array.js","../src/backend/web-gl2/kernel-value/single-array1d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js","../src/backend/web-gl2/kernel-value/single-array2d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js","../src/backend/web-gl2/kernel-value/single-array3d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js","../src/backend/web-gl2/kernel-value/single-array2.js","../src/backend/web-gl2/kernel-value/single-array3.js","../src/backend/web-gl2/kernel-value/single-array4.js","../src/backend/web-gl2/kernel-value/unsigned-array.js","../src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js","../src/backend/web-gl2/kernel-value-maps.js","../src/backend/web-gl2/kernel.js","../src/kernel-run-shortcut.js","../src/base-gpu.js","../src/alias.js","../src/browser.js"],"sourcesContent":["function setupArguments(args) {\n const newArguments = new Array(args.length);\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg.toArray) {\n newArguments[i] = arg.toArray();\n } else {\n newArguments[i] = arg;\n }\n }\n return newArguments;\n}\n\nfunction mock1D() {\n const args = setupArguments(arguments);\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n row[x] = this._fn.apply(this, args);\n }\n return row;\n}\n\nfunction mock2D() {\n const args = setupArguments(arguments);\n const matrix = new Array(this.output.y);\n for (let y = 0; y < this.output.y; y++) {\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = 0;\n row[x] = this._fn.apply(this, args);\n }\n matrix[y] = row;\n }\n return matrix;\n}\n\nfunction mock2DGraphical() {\n const args = setupArguments(arguments);\n for (let y = 0; y < this.output.y; y++) {\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = 0;\n this._fn.apply(this, args);\n }\n }\n}\n\nfunction mock3D() {\n const args = setupArguments(arguments);\n const cube = new Array(this.output.z);\n for (let z = 0; z < this.output.z; z++) {\n const matrix = new Array(this.output.y);\n for (let y = 0; y < this.output.y; y++) {\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = z;\n row[x] = this._fn.apply(this, args);\n }\n matrix[y] = row;\n }\n cube[z] = matrix;\n }\n return cube;\n}\n\nfunction apiDecorate(kernel) {\n kernel.setOutput = (output) => {\n kernel.output = setupOutput(output);\n if (kernel.graphical) {\n setupGraphical(kernel);\n }\n };\n kernel.toJSON = () => {\n throw new Error('Not usable with gpuMock');\n };\n kernel.setConstants = (flag) => {\n kernel.constants = flag;\n return kernel;\n };\n kernel.setGraphical = (flag) => {\n kernel.graphical = flag;\n return kernel;\n };\n kernel.setCanvas = (flag) => {\n kernel.canvas = flag;\n return kernel;\n };\n kernel.setContext = (flag) => {\n kernel.context = flag;\n return kernel;\n };\n kernel.exec = function() {\n return new Promise((resolve, reject) => {\n try {\n resolve(kernel.apply(kernel, arguments));\n } catch(e) {\n reject(e);\n }\n });\n };\n kernel.getPixels = (flip) => {\n const {x, y} = kernel.output;\n // cpu is not flipped by default\n return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0);\n };\n kernel.color = function(r, g, b, a) {\n if (typeof a === 'undefined') {\n a = 1;\n }\n\n r = Math.floor(r * 255);\n g = Math.floor(g * 255);\n b = Math.floor(b * 255);\n a = Math.floor(a * 255);\n\n const width = kernel.output.x;\n const height = kernel.output.y;\n\n const x = kernel.thread.x;\n const y = height - kernel.thread.y - 1;\n\n const index = x + y * width;\n\n kernel._colorData[index * 4 + 0] = r;\n kernel._colorData[index * 4 + 1] = g;\n kernel._colorData[index * 4 + 2] = b;\n kernel._colorData[index * 4 + 3] = a;\n };\n\n // these are added for api compatibility, but have no affect\n kernel.setWarnVarUsage = () => {\n return kernel;\n };\n kernel.setOptimizeFloatMemory = () => {\n return kernel;\n };\n kernel.setArgumentTypes = () => {\n return kernel;\n };\n kernel.setDebug = () => {\n return kernel;\n };\n kernel.setLoopMaxIterations = () => {\n return kernel;\n };\n kernel.setPipeline = () => {\n return kernel;\n };\n kernel.setPrecision = () => {\n return kernel;\n };\n kernel.setImmutable = () => {\n return kernel;\n };\n kernel.setFunctions = () => {\n return kernel;\n };\n kernel.addSubKernel = () => {\n return kernel;\n };\n kernel.destroy = () => {};\n kernel.validateSettings = () => {};\n if (kernel.graphical && kernel.output) {\n setupGraphical(kernel);\n }\n return kernel;\n}\n\nfunction setupGraphical(kernel) {\n const {x, y} = kernel.output;\n if (kernel.context && kernel.context.createImageData) {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = kernel.context.createImageData(x, y);\n kernel._colorData = data;\n } else {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = { data };\n kernel._colorData = data;\n }\n}\n\nfunction setupOutput(output) {\n let result = null;\n if (output.length) {\n if (output.length === 3) {\n const [x,y,z] = output;\n result = { x, y, z };\n } else if (output.length === 2) {\n const [x,y] = output;\n result = { x, y };\n } else {\n const [x] = output;\n result = { x };\n }\n } else {\n result = output;\n }\n return result;\n}\n\nfunction gpuMock(fn, settings = {}) {\n const output = settings.output ? setupOutput(settings.output) : null;\n function kernel() {\n if (kernel.output.z) {\n return mock3D.apply(kernel, arguments);\n } else if (kernel.output.y) {\n if (kernel.graphical) {\n return mock2DGraphical.apply(kernel, arguments);\n }\n return mock2D.apply(kernel, arguments);\n } else {\n return mock1D.apply(kernel, arguments);\n }\n }\n kernel._fn = fn;\n kernel.constants = settings.constants || null;\n kernel.context = settings.context || null;\n kernel.canvas = settings.canvas || null;\n kernel.graphical = settings.graphical || false;\n kernel._imageData = null;\n kernel._colorData = null;\n kernel.output = output;\n kernel.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n return apiDecorate(kernel);\n}\n\nfunction flipPixels(pixels, width, height) {\n // https://stackoverflow.com/a/41973289/1324039\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\n const bytesPerRow = width * 4;\n // make a temp buffer to hold one row\n const temp = new Uint8ClampedArray(width * 4);\n const result = pixels.slice(0);\n for (let y = 0; y < halfHeight; ++y) {\n const topOffset = y * bytesPerRow;\n const bottomOffset = (height - y - 1) * bytesPerRow;\n\n // make copy of a row on the top half\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\n\n // copy a row from the bottom half to the top\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\n\n // copy the copy of the top half row to the bottom half\n result.set(temp, bottomOffset);\n }\n return result;\n}\n\nmodule.exports = {\n gpuMock\n};\n","/**\r\n * @fileoverview Branch of utils to prevent circular dependencies.\r\n */\r\n\r\nconst ARGUMENT_NAMES = /([^\\s,]+)/g;\r\nconst FUNCTION_NAME = /function ([^(]*)/;\r\nconst STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\r\n\r\n/**\r\n * @descReturn TRUE, on a JS function\r\n * @param {Function} funcObj - Object to validate if its a function\r\n * @returns {Boolean} TRUE if the object is a JS function\r\n */\r\nexport function isFunction(funcObj) {\r\n return typeof(funcObj) === 'function';\r\n};\r\n\r\n/**\r\n * @desc Return the function name from a JS function string\r\n * @param {String} funcStr - String of JS function to validate\r\n * @returns {String} Function name string (if found)\r\n */\r\nexport function getFunctionNameFromString(funcStr) {\r\n return FUNCTION_NAME.exec(funcStr)[1].trim();\r\n};\r\n\r\n/**\r\n *\r\n * @param {String|Function} source\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {IFunction}\r\n */\r\nexport function functionToIFunction(source, settings) {\r\n settings = settings || {};\r\n if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');\r\n const sourceString = typeof source === 'string' ? source : source.toString();\r\n\r\n let argumentTypes = [];\r\n\r\n if (Array.isArray(settings.argumentTypes)) {\r\n argumentTypes = settings.argumentTypes;\r\n } else if (typeof settings.argumentTypes === 'object') {\r\n argumentTypes = getArgumentNamesFromString(sourceString)\r\n .map(name => settings.argumentTypes[name]) || [];\r\n } else {\r\n argumentTypes = settings.argumentTypes || [];\r\n }\r\n\r\n return {\r\n source: sourceString,\r\n argumentTypes,\r\n returnType: settings.returnType || null,\r\n };\r\n};\r\n\r\nexport function warnDeprecated(type, oldName, newName) {\r\n const msg = newName\r\n ? `It has been replaced with \"${ newName }\"`\r\n : 'It has been removed';\r\n console.warn(`You are using a deprecated ${ type } \"${ oldName }\". ${msg}. Fixing, but please upgrade as it will soon be removed.`)\r\n};\r\n\r\n/**\r\n * @desc Return TRUE, on a valid JS function string\r\n * Note: This does just a VERY simply sanity check. And may give false positives.\r\n *\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {Boolean} TRUE if the string passes basic validation\r\n */\r\nexport function isFunctionString(fn) {\r\n if (typeof fn === 'string') {\r\n return (fn\r\n .slice(0, 'function'.length)\r\n .toLowerCase() === 'function');\r\n }\r\n return false;\r\n};\r\n\r\n/**\r\n * @desc Return list of argument names extracted from a javascript function\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {String[]} Array representing all the parameter names\r\n */\r\nexport function getArgumentNamesFromString(fn) {\r\n const fnStr = fn.replace(STRIP_COMMENTS, '');\r\n let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);\r\n if (result === null) {\r\n result = [];\r\n }\r\n return result;\r\n};\r\n\r\n/**\r\n * @desc Checks if is an array or Array-like object\r\n * @param {Object} array - The argument object to check if is array\r\n * @returns {Boolean} true if is array or Array-like object\r\n */\r\nexport function isArray(array) {\r\n return !isNaN(array.length);\r\n};\r\n\r\nexport function erectMemoryOptimized2DFloat(array, width, height) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = y * width;\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n return yResults;\r\n};\r\n\r\nexport function erectMemoryOptimized3DFloat(array, width, height, depth) {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = (z * height * width) + (y * width);\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n};\r\n\r\nexport function getAstString(source, ast) {\r\n const lines = Array.isArray(source) ? source : source.split(/\\r?\\n/g);\r\n const start = ast.loc.start;\r\n const end = ast.loc.end;\r\n const result = [];\r\n if (start.line === end.line) {\r\n result.push(lines[start.line - 1].substring(start.column, end.column));\r\n } else {\r\n result.push(lines[start.line - 1].slice(start.column));\r\n for (let i = start.line; i < end.line; i++) {\r\n result.push(lines[i]);\r\n }\r\n result.push(lines[end.line - 1].slice(0, end.column));\r\n }\r\n return result.join('\\n');\r\n};\r\n","import { erectMemoryOptimized2DFloat, erectMemoryOptimized3DFloat } from './common';\r\n\r\nexport class Input {\r\n constructor(value, size) {\r\n this.value = value;\r\n if (Array.isArray(size)) {\r\n this.size = size;\r\n } else {\r\n this.size = new Int32Array(3);\r\n if (size.z) {\r\n this.size = new Int32Array([size.x, size.y, size.z]);\r\n } else if (size.y) {\r\n this.size = new Int32Array([size.x, size.y]);\r\n } else {\r\n this.size = new Int32Array([size.x]);\r\n }\r\n }\r\n\r\n const [w, h, d] = this.size;\r\n if (d) {\r\n if (this.value.length !== (w * h * d)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`);\r\n }\r\n } else if (h) {\r\n if (this.value.length !== (w * h)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`);\r\n }\r\n } else {\r\n if (this.value.length !== w) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w}`);\r\n }\r\n }\r\n\r\n }\r\n\r\n toArray() {\r\n const [ w, h, d ] = this.size;\r\n if (d) {\r\n return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d);\r\n } else if (h) {\r\n return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h);\r\n } else {\r\n return this.value;\r\n }\r\n }\r\n};\r\n\r\nexport function input(value, size) {\r\n return new Input(value, size);\r\n};\r\n","/**\r\n * @desc WebGl Texture implementation in JS\r\n * @param {ITextureSettings} settings\r\n */\r\nexport class Texture {\r\n constructor(settings) {\r\n const {\r\n texture,\r\n size,\r\n dimensions,\r\n output,\r\n context,\r\n type = 'NumberTexture',\r\n } = settings;\r\n if (!output) throw new Error('settings property \"output\" required.');\r\n if (!context) throw new Error('settings property \"context\" required.');\r\n this.texture = texture;\r\n this.size = size;\r\n this.dimensions = dimensions;\r\n this.output = output;\r\n this.context = context;\r\n this.kernel = null;\r\n this.type = type;\r\n }\r\n\r\n /**\r\n * @desc Converts the Texture into a JavaScript Array\r\n * @returns {Number[]|Number[][]|Number[][][]}\r\n */\r\n toArray() {\r\n throw new Error(`Not implemented on ${this.constructor.name}`);\r\n }\r\n\r\n /**\r\n * @desc Deletes the Texture\r\n */\r\n delete() {\r\n return this.context.deleteTexture(this.texture);\r\n }\r\n};\r\n","import { parse } from 'acorn';\r\nimport { Texture } from './texture';\r\nimport { Input } from './input';\r\nimport {\r\n getAstString,\r\n erectMemoryOptimized2DFloat,\r\n erectMemoryOptimized3DFloat,\r\n functionToIFunction,\r\n getArgumentNamesFromString,\r\n getFunctionNameFromString,\r\n isArray,\r\n isFunction,\r\n isFunctionString,\r\n warnDeprecated\r\n} from './common';\r\n\r\nexport function getSystemEndianness() {\r\n const b = new ArrayBuffer(4);\r\n const a = new Uint32Array(b);\r\n const c = new Uint8Array(b);\r\n a[0] = 0xdeadbeef;\r\n if (c[0] === 0xef) return 'LE';\r\n if (c[0] === 0xde) return 'BE';\r\n throw new Error('unknown endianness');\r\n};\r\n\r\nconst _systemEndianness = getSystemEndianness();\r\n\r\n/**\r\n *\r\n * @desc Gets the system endianness, and cache it\r\n * @returns {String} 'LE' or 'BE' depending on system architecture\r\n * Credit: https://gist.github.com/TooTallNate/4750953\r\n */\r\nexport function systemEndianness() {\r\n return _systemEndianness;\r\n};\r\n\r\n/**\r\n * @desc Evaluate the argument type, to apply respective logic for it\r\n * @param {Object} value - The argument object to evaluate type\r\n * @returns {String} Argument type Array/Number/Float/Texture/Unknown\r\n */\r\nexport function getVariableType(value, strictIntegers) {\r\n if (isArray(value)) {\r\n if (value[0].nodeName === 'IMG') {\r\n return 'HTMLImageArray';\r\n }\r\n return 'Array';\r\n }\r\n\r\n switch (value.constructor) {\r\n case Boolean:\r\n return 'Boolean';\r\n case Number:\r\n return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float';\r\n case Texture:\r\n return value.type;\r\n case Input:\r\n return 'Input';\r\n }\r\n\r\n switch (value.nodeName) {\r\n case 'IMG':\r\n return 'HTMLImage';\r\n case 'VIDEO':\r\n return 'HTMLVideo';\r\n }\r\n\r\n return value.hasOwnProperty('type') ? value.type : 'Unknown';\r\n};\r\n\r\n/**\r\n * @desc Various utility functions / snippets of code that GPU.JS uses internally.\r\n * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere)\r\n */\r\nconst utils = {\r\n systemEndianness,\r\n getSystemEndianness,\r\n isFunction,\r\n isFunctionString,\r\n getFunctionNameFromString,\r\n\r\n getFunctionBodyFromString(funcStr) {\r\n return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));\r\n },\r\n\r\n getArgumentNamesFromString,\r\n\r\n /**\r\n * @desc Returns a clone\r\n * @param {Object} obj - Object to clone\r\n * @returns {Object|Array} Cloned object\r\n */\r\n clone(obj) {\r\n if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;\r\n\r\n const temp = obj.constructor(); // changed\r\n\r\n for (let key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n obj.isActiveClone = null;\r\n temp[key] = utils.clone(obj[key]);\r\n delete obj.isActiveClone;\r\n }\r\n }\r\n\r\n return temp;\r\n },\r\n\r\n isArray,\r\n getVariableType,\r\n\r\n getKernelTextureSize(settings, dimensions) {\r\n let [w, h, d] = dimensions;\r\n let texelCount = (w || 1) * (h || 1) * (d || 1);\r\n\r\n if (settings.optimizeFloatMemory && settings.precision === 'single') {\r\n w = texelCount = Math.ceil(texelCount / 4);\r\n }\r\n // if given dimensions == a 2d image\r\n if (h > 1 && w * h === texelCount) {\r\n return new Int32Array([w, h]);\r\n }\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n /**\r\n *\r\n * @param {Number} length\r\n * @returns {TextureDimensions}\r\n */\r\n closestSquareDimensions(length) {\r\n const sqrt = Math.sqrt(length);\r\n let high = Math.ceil(sqrt);\r\n let low = Math.floor(sqrt);\r\n while (high * low < length) {\r\n high--;\r\n low = Math.ceil(length / high);\r\n }\r\n return new Int32Array([low, Math.ceil(length / low)]);\r\n },\r\n\r\n /**\r\n * A texture takes up four\r\n * @param {OutputDimensions} dimensions\r\n * @param {Number} bitRatio\r\n * @returns {TextureDimensions}\r\n */\r\n getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) {\r\n const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4);\r\n const texelCount = totalArea / bitRatio;\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n /**\r\n *\r\n * @param dimensions\r\n * @param bitRatio\r\n * @returns {*|TextureDimensions}\r\n */\r\n getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) {\r\n const [w, h, d] = dimensions;\r\n const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4);\r\n const texelCount = totalArea / (4 / bitRatio);\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n roundTo(n, d) {\r\n return Math.floor((n + d - 1) / d) * d;\r\n },\r\n /**\r\n * @desc Return the dimension of an array.\r\n * @param {Array|String|Texture|Input} x - The array\r\n * @param {Boolean} [pad] - To include padding in the dimension calculation\r\n * @returns {OutputDimensions}\r\n */\r\n getDimensions(x, pad) {\r\n let ret;\r\n if (isArray(x)) {\r\n const dim = [];\r\n let temp = x;\r\n while (isArray(temp)) {\r\n dim.push(temp.length);\r\n temp = temp[0];\r\n }\r\n ret = dim.reverse();\r\n } else if (x instanceof Texture) {\r\n ret = x.output;\r\n } else if (x instanceof Input) {\r\n ret = x.size;\r\n } else {\r\n throw new Error(`Unknown dimensions of ${x}`);\r\n }\r\n\r\n if (pad) {\r\n ret = Array.from(ret);\r\n while (ret.length < 3) {\r\n ret.push(1);\r\n }\r\n }\r\n\r\n return new Int32Array(ret);\r\n },\r\n\r\n /**\r\n * Puts a nested 2d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten2dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let y = 0; y < array.length; y++) {\r\n target.set(array[y], offset);\r\n offset += array[y].length;\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 3d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten3dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let z = 0; z < array.length; z++) {\r\n for (let y = 0; y < array[z].length; y++) {\r\n target.set(array[z][y], offset);\r\n offset += array[z][y].length;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 4d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten4dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let l = 0; l < array.length; l++) {\r\n for (let z = 0; z < array[l].length; z++) {\r\n for (let y = 0; y < array[l][z].length; y++) {\r\n target.set(array[l][z][y], offset);\r\n offset += array[l][z][y].length;\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array\r\n * @param {Float32Array|Uint16Array|Uint8Array} array\r\n * @param {Float32Array} target\r\n */\r\n flattenTo(array, target) {\r\n if (isArray(array[0])) {\r\n if (isArray(array[0][0])) {\r\n if (isArray(array[0][0][0])) {\r\n utils.flatten4dArrayTo(array, target);\r\n } else {\r\n utils.flatten3dArrayTo(array, target);\r\n }\r\n } else {\r\n utils.flatten2dArrayTo(array, target);\r\n }\r\n } else {\r\n target.set(array);\r\n }\r\n },\r\n\r\n /**\r\n *\r\n * @desc Splits an array into smaller arrays.\r\n * Number of elements in one small chunk is given by `part`\r\n *\r\n * @param {Number[]} array - The array to split into chunks\r\n * @param {Number} part - elements in one chunk\r\n *\r\n * @returns {Number[]} An array of smaller chunks\r\n */\r\n splitArray(array, part) {\r\n const result = [];\r\n for (let i = 0; i < array.length; i += part) {\r\n result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part));\r\n }\r\n return result;\r\n },\r\n\r\n getAstString,\r\n\r\n allPropertiesOf(obj) {\r\n const props = [];\r\n\r\n do {\r\n props.push.apply(props, Object.getOwnPropertyNames(obj));\r\n } while (obj = Object.getPrototypeOf(obj));\r\n\r\n return props;\r\n },\r\n\r\n /**\r\n * @param {Array} lines - An Array of strings\r\n * @returns {String} Single combined String, separated by *\\n*\r\n */\r\n linesToString(lines) {\r\n if (lines.length > 0) {\r\n return lines.join(';\\n') + ';\\n';\r\n } else {\r\n return '\\n';\r\n }\r\n },\r\n\r\n warnDeprecated,\r\n functionToIFunction,\r\n\r\n flipPixels(pixels, width, height) {\r\n // https://stackoverflow.com/a/41973289/1324039\r\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\r\n const bytesPerRow = width * 4;\r\n // make a temp buffer to hold one row\r\n const temp = new Uint8ClampedArray(width * 4);\r\n const result = pixels.slice(0);\r\n for (let y = 0; y < halfHeight; ++y) {\r\n const topOffset = y * bytesPerRow;\r\n const bottomOffset = (height - y - 1) * bytesPerRow;\r\n\r\n // make copy of a row on the top half\r\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\r\n\r\n // copy a row from the bottom half to the top\r\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\r\n\r\n // copy the copy of the top half row to the bottom half\r\n result.set(temp, bottomOffset);\r\n }\r\n return result;\r\n },\r\n\r\n erectPackedFloat: (array, width) => {\r\n return array.subarray(0, width);\r\n },\r\n erect2DPackedFloat: (array, width, height) => {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xStart = y * width;\r\n const xEnd = xStart + width;\r\n yResults[y] = array.subarray(xStart, xEnd);\r\n }\r\n return yResults;\r\n },\r\n erect3DPackedFloat: (array, width, height, depth) => {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xStart = (z * height * width) + y * width;\r\n const xEnd = xStart + width;\r\n yResults[y] = array.subarray(xStart, xEnd);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectMemoryOptimizedFloat: (array, width) => {\r\n return array.subarray(0, width);\r\n },\r\n erectMemoryOptimized2DFloat,\r\n erectMemoryOptimized3DFloat,\r\n erectFloat: (array, width) => {\r\n const xResults = new Float32Array(width);\r\n let i = 0;\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n return xResults;\r\n },\r\n erect2DFloat: (array, width, height) => {\r\n const yResults = new Array(height);\r\n let i = 0;\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Float32Array(width);\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DFloat: (array, width, height, depth) => {\r\n const zResults = new Array(depth);\r\n let i = 0;\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Float32Array(width);\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray2: (array, width) => {\r\n const xResults = new Array(width);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 2);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray2: (array, width, height) => {\r\n const yResults = new Array(height);\r\n const XResultsMax = width * 4;\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * XResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < XResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 2);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray2: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 2);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray3: (array, width) => {\r\n const xResults = new Array(width);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 3);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray3: (array, width, height) => {\r\n const xResultsMax = width * 4;\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * xResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 3);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray3: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 3);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray4: (array, width) => {\r\n const xResults = new Array(array);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 4);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray4: (array, width, height) => {\r\n const xResultsMax = width * 4;\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * xResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 4);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray4: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 4);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n\r\n /**\r\n * @param {String} source\r\n * @param {Object} settings\r\n * @return {String}\r\n */\r\n flattenFunctionToString: (source, settings) => {\r\n const { findDependency, thisLookup, doNotDefine } = settings;\r\n let flattened = settings.flattened;\r\n if (!flattened) {\r\n flattened = settings.flattened = {};\r\n }\r\n\r\n const ast = parse(source);\r\n const functionDependencies = [];\r\n\r\n function flatten(ast) {\r\n if (Array.isArray(ast)) {\r\n const results = [];\r\n for (let i = 0; i < ast.length; i++) {\r\n results.push(flatten(ast[i]));\r\n }\r\n return results.join('');\r\n }\r\n switch (ast.type) {\r\n case 'Program':\r\n return flatten(ast.body);\r\n case 'FunctionDeclaration':\r\n return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`;\r\n case 'BlockStatement': {\r\n const result = [];\r\n for (let i = 0; i < ast.body.length; i++) {\r\n result.push(flatten(ast.body[i]), ';\\n');\r\n }\r\n return `{\\n${result.join('')}}`;\r\n }\r\n case 'VariableDeclaration':\r\n switch (ast.declarations[0].id.type) {\r\n case 'ObjectPattern': {\r\n const source = flatten(ast.declarations[0].init);\r\n const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0];\r\n if (/this/.test(source)) {\r\n const result = [];\r\n const lookups = properties.map(thisLookup);\r\n for (let i = 0; i < lookups.length; i++) {\r\n const lookup = lookups[i];\r\n if (lookup === null) continue;\r\n const property = properties[i];\r\n result.push(`${ast.kind} ${ property } = ${ lookup };\\n`);\r\n }\r\n\r\n return result.join('');\r\n }\r\n return `${ast.kind} { ${properties} } = ${source}`;\r\n }\r\n case 'ArrayPattern':\r\n return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`;\r\n }\r\n if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) {\r\n return '';\r\n }\r\n return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`;\r\n case 'CallExpression': {\r\n if (ast.callee.property.name === 'subarray') {\r\n return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') {\r\n return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n if (ast.callee.object.type === 'ThisExpression') {\r\n functionDependencies.push(findDependency('this', ast.callee.property.name));\r\n return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else if (ast.callee.object.name) {\r\n const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name);\r\n if (foundSource === null) {\r\n // we're not flattening it\r\n return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else {\r\n functionDependencies.push(foundSource);\r\n // we're flattening it\r\n return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n } else if (ast.callee.object.type === 'MemberExpression') {\r\n return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else {\r\n throw new Error('unknown ast.callee');\r\n }\r\n }\r\n case 'ReturnStatement':\r\n return `return ${flatten(ast.argument)}`;\r\n case 'BinaryExpression':\r\n return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`;\r\n case 'UnaryExpression':\r\n if (ast.prefix) {\r\n return `${ast.operator} ${flatten(ast.argument)}`;\r\n } else {\r\n return `${flatten(ast.argument)} ${ast.operator}`;\r\n }\r\n case 'ExpressionStatement':\r\n return `(${flatten(ast.expression)})`;\r\n case 'ArrowFunctionExpression':\r\n return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`;\r\n case 'Literal':\r\n return ast.raw;\r\n case 'Identifier':\r\n return ast.name;\r\n case 'MemberExpression':\r\n if (ast.object.type === 'ThisExpression') {\r\n return thisLookup(ast.property.name);\r\n }\r\n if (ast.computed) {\r\n return `${flatten(ast.object)}[${flatten(ast.property)}]`;\r\n }\r\n return flatten(ast.object) + '.' + flatten(ast.property);\r\n case 'ThisExpression':\r\n return 'this';\r\n case 'NewExpression':\r\n return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n case 'ForStatement':\r\n return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`;\r\n case 'AssignmentExpression':\r\n return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`;\r\n case 'UpdateExpression':\r\n return `${flatten(ast.argument)}${ast.operator}`;\r\n case 'IfStatement':\r\n return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`;\r\n case 'ThrowStatement':\r\n return `throw ${flatten(ast.argument)}`;\r\n case 'ObjectPattern':\r\n return ast.properties.map(flatten).join(', ');\r\n case 'ArrayPattern':\r\n return ast.elements.map(flatten).join(', ');\r\n case 'DebuggerStatement':\r\n return 'debugger;';\r\n case 'ConditionalExpression':\r\n return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`;\r\n case 'Property':\r\n if (ast.kind === 'init') {\r\n return flatten(ast.key);\r\n }\r\n }\r\n throw new Error(`unhandled ast.type of ${ ast.type }`);\r\n }\r\n const result = flatten(ast);\r\n if (functionDependencies.length > 0) {\r\n const flattenedFunctionDependencies = [];\r\n for (let i = 0; i < functionDependencies.length; i++) {\r\n const functionDependency = functionDependencies[i];\r\n if (!flattened[functionDependency]) {\r\n flattened[functionDependency] = true;\r\n }\r\n flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\\n');\r\n }\r\n return flattenedFunctionDependencies.join('') + result;\r\n }\r\n return result;\r\n },\r\n};\r\n\r\nexport { utils };\r\n","import { Input } from '../input';\r\nimport {\r\n functionToIFunction,\r\n getArgumentNamesFromString,\r\n isArray,\r\n isFunctionString,\r\n warnDeprecated\r\n} from '../common';\r\nimport { getVariableType } from '../utils';\r\n\r\nexport class Kernel {\r\n /**\r\n * @type {Boolean}\r\n */\r\n static get isSupported() {\r\n throw new Error(`\"isSupported\" not implemented on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {Boolean}\r\n */\r\n static isContextMatch(context) {\r\n throw new Error(`\"isContextMatch\" not implemented on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {IKernelFeatures}\r\n * Used internally to populate the kernel.feature, which is a getter for the output of this value\r\n */\r\n static getFeatures() {\r\n throw new Error(`\"getFeatures\" not implemented on ${ this.name }`);\r\n }\r\n\r\n static destroyContext(context) {\r\n throw new Error(`\"destroyContext\" called on ${ this.name }`);\r\n }\r\n\r\n static nativeFunctionArguments() {\r\n throw new Error(`\"nativeFunctionArguments\" called on ${ this.name }`);\r\n }\r\n\r\n static nativeFunctionReturnType() {\r\n throw new Error(`\"nativeFunctionReturnType\" called on ${ this.name }`);\r\n }\r\n\r\n static combineKernels() {\r\n throw new Error(`\"combineKernels\" called on ${ this.name }`);\r\n }\r\n\r\n /**\r\n *\r\n * @param {string|object} source\r\n * @param [settings]\r\n */\r\n constructor(source, settings) {\r\n if (typeof source !== 'object') {\r\n if (typeof source !== 'string') {\r\n throw new Error('source not a string');\r\n }\r\n if (!isFunctionString(source)) {\r\n throw new Error('source not a function string');\r\n }\r\n }\r\n this.useLegacyEncoder = false;\r\n this.fallbackRequested = false;\r\n this.onRequestFallback = null;\r\n\r\n /**\r\n * Name of the arguments found from parsing source argument\r\n * @type {String[]}\r\n */\r\n this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null;\r\n this.argumentTypes = null;\r\n this.argumentSizes = null;\r\n this.argumentBitRatios = null;\r\n this.kernelArguments = null;\r\n this.kernelConstants = null;\r\n\r\n\r\n /**\r\n * The function source\r\n * @type {String}\r\n */\r\n this.source = source;\r\n\r\n /**\r\n * The size of the kernel's output\r\n * @type {Number[]}\r\n */\r\n this.output = null;\r\n\r\n /**\r\n * Debug mode\r\n * @type {Boolean}\r\n */\r\n this.debug = false;\r\n\r\n /**\r\n * Graphical mode\r\n * @type {Boolean}\r\n */\r\n this.graphical = false;\r\n\r\n /**\r\n * Maximum loops when using argument values to prevent infinity\r\n * @type {Number}\r\n */\r\n this.loopMaxIterations = 0;\r\n\r\n /**\r\n * Constants used in kernel via `this.constants`\r\n * @type {Object}\r\n */\r\n this.constants = null;\r\n this.constantTypes = null;\r\n this.constantBitRatios = null;\r\n this.dynamicArguments = false;\r\n this.dynamicOutput = false;\r\n\r\n /**\r\n *\r\n * @type {Object}\r\n */\r\n this.canvas = null;\r\n\r\n /**\r\n *\r\n * @type {WebGLRenderingContext}\r\n */\r\n this.context = null;\r\n\r\n /**\r\n *\r\n * @type {Boolean}\r\n */\r\n this.checkContext = null;\r\n\r\n /**\r\n *\r\n * @type {GPU}\r\n */\r\n this.gpu = null;\r\n\r\n /**\r\n *\r\n * @type {IGPUFunction[]}\r\n */\r\n this.functions = null;\r\n\r\n /**\r\n *\r\n * @type {IGPUNativeFunction[]}\r\n */\r\n this.nativeFunctions = null;\r\n\r\n /**\r\n *\r\n * @type {String}\r\n */\r\n this.injectedNative = null;\r\n\r\n /**\r\n *\r\n * @type {ISubKernel[]}\r\n */\r\n this.subKernels = null;\r\n\r\n /**\r\n *\r\n * @type {Boolean}\r\n */\r\n this.validate = true;\r\n\r\n /**\r\n * Enforces kernel to write to a new array or texture on run\r\n * @type {Boolean}\r\n */\r\n this.immutable = false;\r\n\r\n /**\r\n * Enforces kernel to write to a texture on run\r\n * @type {Boolean}\r\n */\r\n this.pipeline = false;\r\n\r\n /**\r\n * Make GPU use single precison or unsigned. Acceptable values: 'single' or 'unsigned'\r\n * @type {String|null}\r\n * @enum 'single' | 'unsigned'\r\n */\r\n this.precision = null;\r\n\r\n /**\r\n *\r\n * @type {String|null}\r\n * @enum 'speed' | 'balanced' | 'precision'\r\n */\r\n this.tactic = 'balanced';\r\n\r\n this.plugins = null;\r\n\r\n this.returnType = null;\r\n this.leadingReturnStatement = null;\r\n this.followingReturnStatement = null;\r\n this.optimizeFloatMemory = null;\r\n this.strictIntegers = false;\r\n this.fixIntegerDivisionAccuracy = null;\r\n this.warnVarUsage = true;\r\n }\r\n\r\n mergeSettings(settings) {\r\n for (let p in settings) {\r\n if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;\r\n switch (p) {\r\n case 'output':\r\n if (!Array.isArray(settings.output)) {\r\n this.setOutput(settings.output); // Flatten output object\r\n continue;\r\n }\r\n break;\r\n case 'functions':\r\n if (typeof settings.functions[0] === 'function') {\r\n this.functions = settings.functions.map(source => functionToIFunction(source));\r\n continue;\r\n }\r\n break;\r\n case 'graphical':\r\n if (settings[p] && !settings.hasOwnProperty('precision')) {\r\n this.precision = 'unsigned';\r\n }\r\n this[p] = settings[p];\r\n continue;\r\n }\r\n this[p] = settings[p];\r\n }\r\n\r\n if (!this.canvas) this.canvas = this.initCanvas();\r\n if (!this.context) this.context = this.initContext();\r\n if (!this.plugins) this.plugins = this.initPlugins(settings);\r\n }\r\n /**\r\n * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders,\r\n * and instantiates the program.\r\n * @abstract\r\n */\r\n build() {\r\n throw new Error(`\"build\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Run the kernel program, and send the output to renderOutput\r\n *

This method calls a helper method *renderOutput* to return the result.

\r\n * @returns {Float32Array|Float32Array[]|Float32Array[][]|void} Result The final output of the program, as float, and as Textures for reuse.\r\n * @abstract\r\n */\r\n run() {\r\n throw new Error(`\"run\" not defined on ${ this.constructor.name }`)\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @return {Object}\r\n */\r\n initCanvas() {\r\n throw new Error(`\"initCanvas\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @return {Object}\r\n */\r\n initContext() {\r\n throw new Error(`\"initContext\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @param {IFunctionSettings} settings\r\n * @return {Object};\r\n * @abstract\r\n */\r\n initPlugins(settings) {\r\n throw new Error(`\"initPlugins\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Setup the parameter types for the parameters\r\n * supplied to the Kernel function\r\n *\r\n * @param {IArguments} args - The actual parameters sent to the Kernel\r\n */\r\n setupArguments(args) {\r\n this.kernelArguments = [];\r\n if (!this.argumentTypes) {\r\n if (!this.argumentTypes) {\r\n this.argumentTypes = [];\r\n for (let i = 0; i < args.length; i++) {\r\n const argType = getVariableType(args[i], this.strictIntegers);\r\n const type = argType === 'Integer' ? 'Number' : argType;\r\n this.argumentTypes.push(type);\r\n this.kernelArguments.push({\r\n type\r\n });\r\n }\r\n }\r\n } else {\r\n for (let i = 0; i < this.argumentTypes.length; i++) {\r\n this.kernelArguments.push({\r\n type: this.argumentTypes[i]\r\n });\r\n }\r\n }\r\n\r\n // setup sizes\r\n this.argumentSizes = new Array(args.length);\r\n this.argumentBitRatios = new Int32Array(args.length);\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n this.argumentSizes[i] = arg.constructor === Input ? arg.size : null;\r\n this.argumentBitRatios[i] = this.getBitRatio(arg);\r\n }\r\n\r\n if (this.argumentNames.length !== args.length) {\r\n throw new Error(`arguments are miss-aligned`);\r\n }\r\n }\r\n\r\n /**\r\n * Setup constants\r\n */\r\n setupConstants() {\r\n this.kernelConstants = [];\r\n let needsConstantTypes = this.constantTypes === null;\r\n if (needsConstantTypes) {\r\n this.constantTypes = {};\r\n }\r\n this.constantBitRatios = {};\r\n if (this.constants) {\r\n for (let name in this.constants) {\r\n if (needsConstantTypes) {\r\n const type = getVariableType(this.constants[name], this.strictIntegers);\r\n this.constantTypes[name] = type;\r\n this.kernelConstants.push({\r\n name,\r\n type\r\n });\r\n } else {\r\n this.kernelConstants.push({\r\n name,\r\n type: this.constantTypes[name]\r\n });\r\n }\r\n this.constantBitRatios[name] = this.getBitRatio(this.constants[name]);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setOptimizeFloatMemory(flag) {\r\n this.optimizeFloatMemory = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set output dimensions of the kernel function\r\n * @param {Array|Object} output - The output array to set the kernel output size to\r\n */\r\n setOutput(output) {\r\n if (output.hasOwnProperty('x')) {\r\n if (output.hasOwnProperty('y')) {\r\n if (output.hasOwnProperty('z')) {\r\n this.output = [output.x, output.y, output.z];\r\n } else {\r\n this.output = [output.x, output.y];\r\n }\r\n } else {\r\n this.output = [output.x];\r\n }\r\n } else {\r\n this.output = output;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle debug mode\r\n * @param {Boolean} flag - true to enable debug\r\n */\r\n setDebug(flag) {\r\n this.debug = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle graphical output mode\r\n * @param {Boolean} flag - true to enable graphical output\r\n */\r\n setGraphical(flag) {\r\n this.graphical = flag;\r\n this.precision = 'unsigned';\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set the maximum number of loop iterations\r\n * @param {number} max - iterations count\r\n *\r\n */\r\n setLoopMaxIterations(max) {\r\n this.loopMaxIterations = max;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set Constants\r\n */\r\n setConstants(constants) {\r\n this.constants = constants;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [IKernelValueTypes] constantTypes\r\n * @return {Kernel}\r\n */\r\n setConstantTypes(constantTypes) {\r\n this.constantTypes = constantTypes;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IFunction[]|KernelFunction[]} functions\r\n * @return {Kernel}\r\n */\r\n setFunctions(functions) {\r\n if (typeof functions[0] === 'function') {\r\n this.functions = functions.map(source => functionToIFunction(source));\r\n } else {\r\n this.functions = functions;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IGPUNativeFunction} nativeFunctions\r\n * @return {Kernel}\r\n */\r\n setNativeFunctions(nativeFunctions) {\r\n this.nativeFunctions = nativeFunctions;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {String} injectedNative\r\n * @return {Kernel}\r\n */\r\n setInjectedNative(injectedNative) {\r\n this.injectedNative = injectedNative;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set writing to texture on/off\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setPipeline(flag) {\r\n this.pipeline = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set precision to 'unsigned' or 'single'\r\n * @param {String} flag 'unsigned' or 'single'\r\n * @return {Kernel}\r\n */\r\n setPrecision(flag) {\r\n this.precision = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param flag\r\n * @return {Kernel}\r\n * @deprecated\r\n */\r\n setOutputToTexture(flag) {\r\n warnDeprecated('method', 'setOutputToTexture', 'setPipeline');\r\n this.pipeline = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set to immutable\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setImmutable(flag) {\r\n this.immutable = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Bind the canvas to kernel\r\n * @param {Object} canvas\r\n */\r\n setCanvas(canvas) {\r\n this.canvas = canvas;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setStrictIntegers(flag) {\r\n this.strictIntegers = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setDynamicOutput(flag) {\r\n this.dynamicOutput = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setHardcodeConstants(flag) {\r\n warnDeprecated('method', 'setHardcodeConstants');\r\n this.setDynamicOutput(flag);\r\n this.setDynamicArguments(flag);\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setDynamicArguments(flag) {\r\n this.dynamicArguments = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setUseLegacyEncoder(flag) {\r\n this.useLegacyEncoder = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setWarnVarUsage(flag) {\r\n this.warnVarUsage = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @returns {Object}\r\n */\r\n getCanvas() {\r\n warnDeprecated('method', 'getCanvas');\r\n return this.canvas;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @returns {Object}\r\n */\r\n getWebGl() {\r\n warnDeprecated('method', 'getWebGl');\r\n return this.context;\r\n }\r\n\r\n /**\r\n * @desc Bind the webGL instance to kernel\r\n * @param {WebGLRenderingContext} context - webGl instance to bind\r\n */\r\n setContext(context) {\r\n this.context = context;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [IKernelValueTypes|GPUVariableType[]] argumentTypes\r\n * @return {Kernel}\r\n */\r\n setArgumentTypes(argumentTypes) {\r\n if (Array.isArray(argumentTypes)) {\r\n this.argumentTypes = argumentTypes;\r\n } else {\r\n this.argumentTypes = [];\r\n for (const p in argumentTypes) {\r\n const argumentIndex = this.argumentNames.indexOf(p);\r\n if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`);\r\n this.argumentTypes[argumentIndex] = argumentTypes[p];\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [Tactic] tactic\r\n * @return {Kernel}\r\n */\r\n setTactic(tactic) {\r\n this.tactic = tactic;\r\n return this;\r\n }\r\n\r\n requestFallback(args) {\r\n if (!this.onRequestFallback) {\r\n throw new Error(`\"onRequestFallback\" not defined on ${ this.constructor.name }`);\r\n }\r\n this.fallbackRequested = true;\r\n return this.onRequestFallback(args);\r\n }\r\n\r\n /**\r\n * @desc Validate settings\r\n * @abstract\r\n */\r\n validateSettings() {\r\n throw new Error(`\"validateSettings\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Add a sub kernel to the root kernel instance.\r\n * This is what `createKernelMap` uses.\r\n *\r\n * @param {ISubKernel} subKernel - function (as a String) of the subKernel to add\r\n */\r\n addSubKernel(subKernel) {\r\n if (this.subKernels === null) {\r\n this.subKernels = [];\r\n }\r\n if (!subKernel.source) throw new Error('subKernel missing \"source\" property');\r\n if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing \"property\" property');\r\n if (!subKernel.name) throw new Error('subKernel missing \"name\" property');\r\n this.subKernels.push(subKernel);\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Destroys all memory associated with this kernel\r\n * @param {Boolean} [removeCanvasReferences] remove any associated canvas references\r\n */\r\n destroy(removeCanvasReferences) {\r\n throw new Error(`\"destroy\" called on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4\r\n * @param value\r\n * @returns {number}\r\n */\r\n getBitRatio(value) {\r\n if (this.precision === 'single') {\r\n // 8 and 16 are upconverted to float32\r\n return 4;\r\n } else if (Array.isArray(value[0])) {\r\n return this.getBitRatio(value[0]);\r\n } else if (value.constructor === Input) {\r\n return this.getBitRatio(value.value);\r\n }\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n return 1;\r\n case Uint16Array:\r\n case Int16Array:\r\n return 2;\r\n case Float32Array:\r\n case Int32Array:\r\n default:\r\n return 4;\r\n }\r\n }\r\n\r\n /**\r\n * @returns {number[]}\r\n */\r\n getPixels() {\r\n throw new Error(`\"getPixels\" called on ${ this.constructor.name }`);\r\n }\r\n\r\n checkOutput() {\r\n if (!this.output || !isArray(this.output)) throw new Error('kernel.output not an array');\r\n if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value');\r\n for (let i = 0; i < this.output.length; i++) {\r\n if (isNaN(this.output[i]) || this.output[i] < 1) {\r\n throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \\`${ this.output[i] }\\`, needs to be numeric, and greater than 0`);\r\n }\r\n }\r\n }\r\n\r\n toJSON() {\r\n const settings = {\r\n output: this.output,\r\n threadDim: this.threadDim,\r\n pipeline: this.pipeline,\r\n argumentNames: this.argumentNames,\r\n argumentsTypes: this.argumentTypes,\r\n constants: this.constants,\r\n pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null,\r\n returnType: this.returnType,\r\n };\r\n return {\r\n settings\r\n };\r\n }\r\n}\r\n","/**\r\n * @desc This handles all the raw state, converted state, etc. of a single function.\r\n * [INTERNAL] A collection of functionNodes.\r\n * @class\r\n */\r\nexport class FunctionBuilder {\r\n /**\r\n *\r\n * @param {Kernel} kernel\r\n * @param {FunctionNode} FunctionNode\r\n * @param {object} [extraNodeOptions]\r\n * @returns {FunctionBuilder}\r\n * @static\r\n */\r\n static fromKernel(kernel, FunctionNode, extraNodeOptions) {\r\n const {\r\n kernelArguments,\r\n kernelConstants,\r\n argumentNames,\r\n argumentSizes,\r\n argumentBitRatios,\r\n constants,\r\n constantBitRatios,\r\n debug,\r\n loopMaxIterations,\r\n nativeFunctions,\r\n output,\r\n optimizeFloatMemory,\r\n precision,\r\n plugins,\r\n source,\r\n subKernels,\r\n functions,\r\n leadingReturnStatement,\r\n followingReturnStatement,\r\n dynamicArguments,\r\n dynamicOutput,\r\n warnVarUsage,\r\n } = kernel;\r\n\r\n const argumentTypes = new Array(kernelArguments.length);\r\n const constantTypes = {};\r\n\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n argumentTypes[i] = kernelArguments[i].type;\r\n }\r\n\r\n for (let i = 0; i < kernelConstants.length; i++) {\r\n const kernelConstant = kernelConstants[i]\r\n constantTypes[kernelConstant.name] = kernelConstant.type;\r\n }\r\n\r\n const needsArgumentType = (functionName, index) => {\r\n return functionBuilder.needsArgumentType(functionName, index);\r\n };\r\n\r\n const assignArgumentType = (functionName, index, type) => {\r\n functionBuilder.assignArgumentType(functionName, index, type);\r\n };\r\n\r\n const lookupReturnType = (functionName, ast, requestingNode) => {\r\n return functionBuilder.lookupReturnType(functionName, ast, requestingNode);\r\n };\r\n\r\n const lookupFunctionArgumentTypes = (functionName) => {\r\n return functionBuilder.lookupFunctionArgumentTypes(functionName);\r\n };\r\n\r\n const lookupFunctionArgumentName = (functionName, argumentIndex) => {\r\n return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex);\r\n };\r\n\r\n const lookupFunctionArgumentBitRatio = (functionName, argumentName) => {\r\n return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName);\r\n };\r\n\r\n const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => {\r\n functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode);\r\n };\r\n\r\n const triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => {\r\n functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex);\r\n };\r\n\r\n const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => {\r\n return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName);\r\n };\r\n\r\n const onFunctionCall = (functionName, calleeFunctionName, args) => {\r\n functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args);\r\n };\r\n\r\n const onNestedFunction = (ast, returnType) => {\r\n const argumentNames = [];\r\n for (let i = 0; i < ast.params.length; i++) {\r\n argumentNames.push(ast.params[i].name);\r\n }\r\n const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, {\r\n returnType: null,\r\n ast,\r\n name: ast.id.name,\r\n argumentNames,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n warnVarUsage,\r\n }));\r\n nestedFunction.traceFunctionAST(ast);\r\n functionBuilder.addFunctionNode(nestedFunction);\r\n };\r\n\r\n const nodeOptions = Object.assign({\r\n isRootKernel: false,\r\n onNestedFunction,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n optimizeFloatMemory,\r\n precision,\r\n constants,\r\n constantTypes,\r\n constantBitRatios,\r\n debug,\r\n loopMaxIterations,\r\n output,\r\n plugins,\r\n dynamicArguments,\r\n dynamicOutput,\r\n }, extraNodeOptions || {});\r\n\r\n const rootNodeOptions = Object.assign({}, nodeOptions, {\r\n isRootKernel: true,\r\n name: 'kernel',\r\n argumentNames,\r\n argumentTypes,\r\n argumentSizes,\r\n argumentBitRatios,\r\n leadingReturnStatement,\r\n followingReturnStatement,\r\n });\r\n\r\n if (typeof source === 'object' && source.functionNodes) {\r\n return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode);\r\n }\r\n\r\n const rootNode = new FunctionNode(source, rootNodeOptions);\r\n\r\n let functionNodes = null;\r\n if (functions) {\r\n functionNodes = functions.map((fn) => new FunctionNode(fn.source, {\r\n returnType: fn.returnType,\r\n argumentTypes: fn.argumentTypes,\r\n output,\r\n plugins,\r\n constants,\r\n constantTypes,\r\n constantBitRatios,\r\n optimizeFloatMemory,\r\n precision,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n }));\r\n }\r\n\r\n let subKernelNodes = null;\r\n if (subKernels) {\r\n subKernelNodes = subKernels.map((subKernel) => {\r\n const { name, source } = subKernel;\r\n return new FunctionNode(source, Object.assign({}, nodeOptions, {\r\n name,\r\n isSubKernel: true,\r\n isRootKernel: false,\r\n }));\r\n });\r\n }\r\n\r\n const functionBuilder = new FunctionBuilder({\r\n kernel,\r\n rootNode,\r\n functionNodes,\r\n nativeFunctions,\r\n subKernelNodes\r\n });\r\n\r\n return functionBuilder;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IFunctionBuilderSettings} [settings]\r\n */\r\n constructor(settings) {\r\n settings = settings || {};\r\n this.kernel = settings.kernel;\r\n this.rootNode = settings.rootNode;\r\n this.functionNodes = settings.functionNodes || [];\r\n this.subKernelNodes = settings.subKernelNodes || [];\r\n this.nativeFunctions = settings.nativeFunctions || [];\r\n this.functionMap = {};\r\n this.nativeFunctionNames = [];\r\n this.lookupChain = [];\r\n this.argumentChain = [];\r\n this.functionNodeDependencies = {};\r\n this.functionCalls = {};\r\n\r\n if (this.rootNode) {\r\n this.functionMap['kernel'] = this.rootNode;\r\n }\r\n\r\n if (this.functionNodes) {\r\n for (let i = 0; i < this.functionNodes.length; i++) {\r\n this.functionMap[this.functionNodes[i].name] = this.functionNodes[i];\r\n }\r\n }\r\n\r\n if (this.subKernelNodes) {\r\n for (let i = 0; i < this.subKernelNodes.length; i++) {\r\n this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i];\r\n }\r\n }\r\n\r\n if (this.nativeFunctions) {\r\n for (let i = 0; i < this.nativeFunctions.length; i++) {\r\n const nativeFunction = this.nativeFunctions[i];\r\n this.nativeFunctionNames.push(nativeFunction.name);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @desc Add the function node directly\r\n *\r\n * @param {FunctionNode} functionNode - functionNode to add\r\n *\r\n */\r\n addFunctionNode(functionNode) {\r\n if (!functionNode.name) throw new Error('functionNode.name needs set');\r\n this.functionMap[functionNode.name] = functionNode;\r\n if (functionNode.isRootKernel) {\r\n this.rootNode = functionNode;\r\n }\r\n }\r\n\r\n /**\r\n * @desc Trace all the depending functions being called, from a single function\r\n *\r\n * This allow for 'unneeded' functions to be automatically optimized out.\r\n * Note that the 0-index, is the starting function trace.\r\n *\r\n * @param {String} functionName - Function name to trace from, default to 'kernel'\r\n * @param {String[]} [retList] - Returning list of function names that is traced. Including itself.\r\n *\r\n * @returns {String[]} Returning list of function names that is traced. Including itself.\r\n */\r\n traceFunctionCalls(functionName, retList) {\r\n functionName = functionName || 'kernel';\r\n retList = retList || [];\r\n\r\n if (this.nativeFunctionNames.indexOf(functionName) > -1) {\r\n if (retList.indexOf(functionName) === -1) {\r\n retList.push(functionName);\r\n }\r\n return retList;\r\n }\r\n\r\n const functionNode = this.functionMap[functionName];\r\n if (functionNode) {\r\n // Check if function already exists\r\n const functionIndex = retList.indexOf(functionName);\r\n if (functionIndex === -1) {\r\n retList.push(functionName);\r\n functionNode.toString(); //ensure JS trace is done\r\n for (let i = 0; i < functionNode.calledFunctions.length; ++i) {\r\n this.traceFunctionCalls(functionNode.calledFunctions[i], retList);\r\n }\r\n } else {\r\n /**\r\n * https://github.com/gpujs/gpu.js/issues/207\r\n * if dependent function is already in the list, because a function depends on it, and because it has\r\n * already been traced, we know that we must move the dependent function to the end of the the retList.\r\n * */\r\n const dependantFunctionName = retList.splice(functionIndex, 1)[0];\r\n retList.push(dependantFunctionName);\r\n }\r\n }\r\n\r\n return retList;\r\n }\r\n\r\n /**\r\n * @desc Return the string for a function\r\n * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {String} The full string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getPrototypeString(functionName) {\r\n return this.getPrototypes(functionName).join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Return the string for a function\r\n * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getPrototypes(functionName) {\r\n if (this.rootNode) {\r\n this.rootNode.toString();\r\n }\r\n if (functionName) {\r\n return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());\r\n }\r\n return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap));\r\n }\r\n\r\n /**\r\n * @desc Get string from function names\r\n * @param {String[]} functionList - List of function to build string\r\n * @returns {String} The string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getStringFromFunctionNames(functionList) {\r\n const ret = [];\r\n for (let i = 0; i < functionList.length; ++i) {\r\n const node = this.functionMap[functionList[i]];\r\n if (node) {\r\n ret.push(this.functionMap[functionList[i]].toString());\r\n }\r\n }\r\n return ret.join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Return string of all functions converted\r\n * @param {String[]} functionList - List of function names to build the string.\r\n * @returns {Array} Prototypes of all functions converted\r\n */\r\n getPrototypesFromFunctionNames(functionList) {\r\n const ret = [];\r\n for (let i = 0; i < functionList.length; ++i) {\r\n const functionName = functionList[i];\r\n const functionIndex = this.nativeFunctionNames.indexOf(functionName);\r\n if (functionIndex > -1) {\r\n ret.push(this.nativeFunctions[functionIndex].source);\r\n continue;\r\n }\r\n const node = this.functionMap[functionName];\r\n if (node) {\r\n ret.push(node.toString());\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n toJSON() {\r\n return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => {\r\n const nativeIndex = this.nativeFunctions.indexOf(name);\r\n if (nativeIndex > -1) {\r\n return {\r\n name,\r\n source: this.nativeFunctions[nativeIndex].source\r\n };\r\n } else if (this.functionMap[name]) {\r\n return this.functionMap[name].toJSON();\r\n } else {\r\n throw new Error(`function ${ name } not found`);\r\n }\r\n });\r\n }\r\n\r\n fromJSON(jsonFunctionNodes, FunctionNode) {\r\n this.functionMap = {};\r\n for (let i = 0; i < jsonFunctionNodes.length; i++) {\r\n const jsonFunctionNode = jsonFunctionNodes[i];\r\n this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Get string for a particular function name\r\n * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {String} settings - The string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getString(functionName) {\r\n if (functionName) {\r\n return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse());\r\n }\r\n return this.getStringFromFunctionNames(Object.keys(this.functionMap));\r\n }\r\n\r\n lookupReturnType(functionName, ast, requestingNode) {\r\n if (ast.type !== 'CallExpression') {\r\n throw new Error(`expected ast type of \"CallExpression\", but is ${ ast.type }`);\r\n }\r\n if (this._isNativeFunction(functionName)) {\r\n return this._lookupNativeFunctionReturnType(functionName);\r\n } else if (this._isFunction(functionName)) {\r\n const node = this._getFunction(functionName);\r\n if (node.returnType) {\r\n return node.returnType;\r\n } else {\r\n for (let i = 0; i < this.lookupChain.length; i++) {\r\n // detect circlical logic\r\n if (this.lookupChain[i].ast === ast) {\r\n // detect if arguments have not resolved, preventing a return type\r\n // if so, go ahead and resolve them, so we can resolve the return type\r\n if (node.argumentTypes.length === 0 && ast.arguments.length > 0) {\r\n const args = ast.arguments;\r\n for (let j = 0; j < args.length; j++) {\r\n this.lookupChain.push({\r\n name: requestingNode.name,\r\n ast: args[i],\r\n requestingNode\r\n });\r\n node.argumentTypes[j] = requestingNode.getType(args[j]);\r\n this.lookupChain.pop();\r\n }\r\n return node.returnType = node.getType(node.getJsAST());\r\n }\r\n\r\n throw new Error('circlical logic detected!');\r\n }\r\n }\r\n // get ready for a ride!\r\n this.lookupChain.push({\r\n name: requestingNode.name,\r\n ast,\r\n requestingNode\r\n });\r\n const type = node.getType(node.getJsAST());\r\n this.lookupChain.pop();\r\n return node.returnType = type;\r\n }\r\n }\r\n\r\n // function not found, maybe native?\r\n return null;\r\n\r\n /**\r\n * first iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = null\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = null\r\n * calcErrorOutput.targets = null\r\n * calcErrorOutput.returns = null\r\n * calcDeltasSigmoid.error = null\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = null\r\n *\r\n * resolvable are:\r\n * calcErrorOutput.output\r\n * calcErrorOutput.targets\r\n * calcErrorOutput.returns\r\n *\r\n * second iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = null\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = Number\r\n * calcErrorOutput.targets = Array\r\n * calcErrorOutput.returns = Number\r\n * calcDeltasSigmoid.error = null\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = null\r\n *\r\n * resolvable are:\r\n * calcDeltasSigmoid.error\r\n * calcDeltasSigmoid.returns\r\n * kernel.returns\r\n *\r\n * third iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = Number\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = Number\r\n * calcErrorOutput.targets = Array\r\n * calcErrorOutput.returns = Number\r\n * calcDeltasSigmoid.error = Number\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = Number\r\n *\r\n *\r\n */\r\n }\r\n\r\n _getFunction(functionName) {\r\n if (!this._isFunction(functionName)) {\r\n new Error(`Function ${functionName} not found`);\r\n }\r\n return this.functionMap[functionName];\r\n }\r\n\r\n _isFunction(functionName) {\r\n return Boolean(this.functionMap[functionName]);\r\n }\r\n\r\n _getNativeFunction(functionName) {\r\n for (let i = 0; i < this.nativeFunctions.length; i++) {\r\n if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i];\r\n }\r\n return null;\r\n }\r\n\r\n _isNativeFunction(functionName) {\r\n return Boolean(this._getNativeFunction(functionName));\r\n }\r\n\r\n _lookupNativeFunctionReturnType(functionName) {\r\n let nativeFunction = this._getNativeFunction(functionName);\r\n if (nativeFunction) {\r\n return nativeFunction.returnType;\r\n }\r\n throw new Error(`Native function ${ functionName } not found`);\r\n }\r\n\r\n lookupFunctionArgumentTypes(functionName) {\r\n if (this._isNativeFunction(functionName)) {\r\n return this._getNativeFunction(functionName).argumentTypes;\r\n } else if (this._isFunction(functionName)) {\r\n return this._getFunction(functionName).argumentTypes;\r\n }\r\n return null;\r\n }\r\n\r\n lookupFunctionArgumentName(functionName, argumentIndex) {\r\n return this._getFunction(functionName).argumentNames[argumentIndex];\r\n }\r\n\r\n lookupFunctionArgumentBitRatio(functionName, argumentName) {\r\n if (!this._isFunction(functionName)) {\r\n throw new Error('function not found');\r\n }\r\n if (this.rootNode.name === functionName) {\r\n const i = this.rootNode.argumentNames.indexOf(argumentName);\r\n if (i !== -1) {\r\n return this.rootNode.argumentBitRatios[i];\r\n } else {\r\n throw new Error('argument bit ratio not found');\r\n }\r\n } else {\r\n const node = this._getFunction(functionName);\r\n const argumentSynonym = node.argumentSynonym[node.synonymIndex];\r\n if (!argumentSynonym) {\r\n throw new Error('argument synonym not found');\r\n }\r\n return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName);\r\n }\r\n }\r\n\r\n needsArgumentType(functionName, i) {\r\n if (!this._isFunction(functionName)) return false;\r\n const fnNode = this._getFunction(functionName);\r\n return !fnNode.argumentTypes[i];\r\n }\r\n\r\n assignArgumentType(functionName, i, argumentType, requestingNode) {\r\n if (!this._isFunction(functionName)) return;\r\n const fnNode = this._getFunction(functionName);\r\n if (!fnNode.argumentTypes[i]) {\r\n fnNode.argumentTypes[i] = argumentType;\r\n }\r\n }\r\n\r\n trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) {\r\n if (!this._isFunction(calleeFunctionName)) return;\r\n const node = this._getFunction(calleeFunctionName);\r\n if (!node.argumentSynonym) {\r\n node.argumentSynonym = {};\r\n }\r\n const calleeArgumentName = node.argumentNames[argumentIndex];\r\n if (!node.argumentSynonym[calleeArgumentName]) {\r\n node.argumentSynonym[calleeArgumentName] = {};\r\n }\r\n node.synonymIndex++;\r\n node.argumentSynonym[node.synonymIndex] = {\r\n functionName,\r\n argumentName,\r\n calleeArgumentName,\r\n calleeFunctionName,\r\n };\r\n }\r\n\r\n lookupArgumentSynonym(originFunctionName, functionName, argumentName) {\r\n if (originFunctionName === functionName) return argumentName;\r\n if (!this._isFunction(functionName)) return null;\r\n const node = this._getFunction(functionName);\r\n const argumentSynonym = node.argumentSynonym[node.synonymUseIndex];\r\n if (!argumentSynonym) return null;\r\n if (argumentSynonym.calleeArgumentName !== argumentName) return null;\r\n node.synonymUseIndex++;\r\n if (originFunctionName !== functionName) {\r\n return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName);\r\n }\r\n return argumentSynonym.argumentName;\r\n }\r\n\r\n trackFunctionCall(functionName, calleeFunctionName, args) {\r\n if (!this.functionNodeDependencies[functionName]) {\r\n this.functionNodeDependencies[functionName] = new Set();\r\n this.functionCalls[functionName] = [];\r\n }\r\n this.functionNodeDependencies[functionName].add(calleeFunctionName);\r\n this.functionCalls[functionName].push(args);\r\n }\r\n\r\n getKernelResultType() {\r\n return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast);\r\n }\r\n\r\n getSubKernelResultType(index) {\r\n const subKernelNode = this.subKernelNodes[index];\r\n let called = false;\r\n for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) {\r\n const functionCall = this.rootNode.functionCalls[functionCallIndex];\r\n if (functionCall.ast.callee.name === subKernelNode.name) {\r\n called = true;\r\n }\r\n }\r\n if (!called) {\r\n throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`);\r\n }\r\n return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST());\r\n }\r\n\r\n getReturnTypes() {\r\n const result = {\r\n [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast),\r\n };\r\n const list = this.traceFunctionCalls(this.rootNode.name);\r\n for (let i = 0; i < list.length; i++) {\r\n const functionName = list[i];\r\n const functionNode = this.functionMap[functionName];\r\n result[functionName] = functionNode.getType(functionNode.ast);\r\n }\r\n return result;\r\n }\r\n}\r\n","export class FunctionTracer {\r\n constructor(ast) {\r\n this.runningContexts = [];\r\n this.contexts = [];\r\n this.functionCalls = [];\r\n this.declarations = [];\r\n this.identifiers = [];\r\n this.functions = [];\r\n this.returnStatements = [];\r\n this.inLoopInit = false;\r\n this.scan(ast);\r\n }\r\n\r\n get currentContext() {\r\n return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null;\r\n }\r\n\r\n newContext(run) {\r\n const newContext = Object.assign({}, this.currentContext);\r\n this.contexts.push(newContext);\r\n this.runningContexts.push(newContext);\r\n run();\r\n this.runningContexts.pop();\r\n }\r\n\r\n /**\r\n * Recursively scans AST for declarations and functions, and add them to their respective context\r\n * @param ast\r\n */\r\n scan(ast) {\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.scan(ast[i]);\r\n }\r\n return;\r\n }\r\n switch (ast.type) {\r\n case 'Program':\r\n this.scan(ast.body);\r\n break;\r\n case 'BlockStatement':\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n });\r\n break;\r\n case 'AssignmentExpression':\r\n case 'LogicalExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'BinaryExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'UpdateExpression':\r\n case 'UnaryExpression':\r\n this.scan(ast.argument);\r\n break;\r\n case 'VariableDeclaration':\r\n this.scan(ast.declarations);\r\n break;\r\n case 'VariableDeclarator':\r\n const { currentContext } = this;\r\n const declaration = {\r\n ast: ast,\r\n context: currentContext,\r\n name: ast.id.name,\r\n origin: 'declaration',\r\n forceInteger: this.inLoopInit,\r\n assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name),\r\n };\r\n currentContext[ast.id.name] = declaration;\r\n this.declarations.push(declaration);\r\n this.scan(ast.id);\r\n this.scan(ast.init);\r\n break;\r\n case 'FunctionExpression':\r\n case 'FunctionDeclaration':\r\n if (this.runningContexts.length === 0) {\r\n this.scan(ast.body);\r\n } else {\r\n this.functions.push(ast);\r\n }\r\n break;\r\n case 'IfStatement':\r\n this.scan(ast.test);\r\n this.scan(ast.consequent);\r\n if (ast.alternate) this.scan(ast.alternate);\r\n break;\r\n case 'ForStatement':\r\n this.newContext(() => {\r\n this.inLoopInit = true;\r\n this.scan(ast.init);\r\n this.inLoopInit = false;\r\n this.scan(ast.test);\r\n this.scan(ast.update);\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n });\r\n });\r\n break;\r\n case 'DoWhileStatement':\r\n case 'WhileStatement':\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n this.scan(ast.test);\r\n });\r\n break;\r\n case 'Identifier':\r\n this.identifiers.push({\r\n context: this.currentContext,\r\n ast,\r\n });\r\n break;\r\n case 'ReturnStatement':\r\n this.returnStatements.push(ast);\r\n this.scan(ast.argument);\r\n break;\r\n case 'MemberExpression':\r\n this.scan(ast.object);\r\n this.scan(ast.property);\r\n break;\r\n case 'ExpressionStatement':\r\n this.scan(ast.expression);\r\n break;\r\n case 'CallExpression':\r\n this.functionCalls.push({\r\n context: this.currentContext,\r\n ast,\r\n });\r\n this.scan(ast.arguments);\r\n break;\r\n case 'ArrayExpression':\r\n this.scan(ast.elements);\r\n break;\r\n case 'ConditionalExpression':\r\n this.scan(ast.test);\r\n this.scan(ast.alternate);\r\n this.scan(ast.consequent);\r\n break;\r\n case 'SwitchStatement':\r\n this.scan(ast.discriminant);\r\n this.scan(ast.cases);\r\n break;\r\n case 'SwitchCase':\r\n this.scan(ast.test);\r\n this.scan(ast.consequent);\r\n break;\r\n case 'ThisExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'Literal':\r\n case 'DebuggerStatement':\r\n case 'EmptyStatement':\r\n case 'BreakStatement':\r\n case 'ContinueStatement':\r\n break;\r\n default:\r\n throw new Error(`unhandled type \"${ast.type}\"`);\r\n }\r\n }\r\n}\r\n","import { parse } from 'acorn';\r\nimport { FunctionTracer } from './function-tracer';\r\nimport {\r\n getArgumentNamesFromString,\r\n getAstString,\r\n getFunctionNameFromString,\r\n isFunctionString,\r\n} from '../common';\r\n\r\n/**\r\n *\r\n * @desc Represents a single function, inside JS, webGL, or openGL.\r\n *

This handles all the raw state, converted state, etc. Of a single function.

\r\n */\r\nexport class FunctionNode {\r\n /**\r\n *\r\n * @param {string|object} source\r\n * @param {IFunctionSettings} [settings]\r\n */\r\n constructor(source, settings) {\r\n if (!source && !settings.ast) {\r\n throw new Error('source parameter is missing');\r\n }\r\n settings = settings || {};\r\n this.source = source;\r\n this.ast = null;\r\n this.name = typeof source === 'string' ? settings.isRootKernel ?\r\n 'kernel' :\r\n (settings.name || getFunctionNameFromString(source)) : null;\r\n this.calledFunctions = [];\r\n this.constants = {};\r\n this.constantTypes = {};\r\n this.constantBitRatios = {};\r\n this.isRootKernel = false;\r\n this.isSubKernel = false;\r\n this.debug = null;\r\n this.declarations = null;\r\n this.functions = null;\r\n this.identifiers = null;\r\n this.contexts = null;\r\n this.functionCalls = null;\r\n this.states = [];\r\n this.needsArgumentType = null;\r\n this.assignArgumentType = null;\r\n this.lookupReturnType = null;\r\n this.lookupFunctionArgumentTypes = null;\r\n this.lookupFunctionArgumentBitRatio = null;\r\n this.triggerImplyArgumentType = null;\r\n this.triggerImplyArgumentBitRatio = null;\r\n this.onNestedFunction = null;\r\n this.onFunctionCall = null;\r\n this.optimizeFloatMemory = null;\r\n this.precision = null;\r\n this.loopMaxIterations = null;\r\n this.argumentNames = (typeof this.source === 'string' ? getArgumentNamesFromString(this.source) : null);\r\n this.argumentTypes = [];\r\n this.argumentSizes = [];\r\n this.argumentBitRatios = null;\r\n this.returnType = null;\r\n this.output = [];\r\n this.plugins = null;\r\n this.leadingReturnStatement = null;\r\n this.followingReturnStatement = null;\r\n this.dynamicOutput = null;\r\n this.dynamicArguments = null;\r\n this.strictTypingChecking = false;\r\n this.fixIntegerDivisionAccuracy = null;\r\n this.warnVarUsage = true;\r\n\r\n if (settings) {\r\n for (const p in settings) {\r\n if (!settings.hasOwnProperty(p)) continue;\r\n if (!this.hasOwnProperty(p)) continue;\r\n this[p] = settings[p];\r\n }\r\n }\r\n\r\n this.literalTypes = {};\r\n\r\n this.validate();\r\n this._string = null;\r\n this._internalVariableNames = {};\r\n }\r\n\r\n validate() {\r\n if (typeof this.source !== 'string' && !this.ast) {\r\n throw new Error('this.source not a string');\r\n }\r\n\r\n if (!this.ast && !isFunctionString(this.source)) {\r\n throw new Error('this.source not a function string');\r\n }\r\n\r\n if (!this.name) {\r\n throw new Error('this.name could not be set');\r\n }\r\n\r\n if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) {\r\n throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`);\r\n }\r\n\r\n if (this.output.length < 1) {\r\n throw new Error('this.output is not big enough');\r\n }\r\n }\r\n\r\n /**\r\n * @param {String} name\r\n * @returns {boolean}\r\n */\r\n isIdentifierConstant(name) {\r\n if (!this.constants) return false;\r\n return this.constants.hasOwnProperty(name);\r\n }\r\n\r\n isInput(argumentName) {\r\n return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input';\r\n }\r\n\r\n pushState(state) {\r\n this.states.push(state);\r\n }\r\n\r\n popState(state) {\r\n if (this.state !== state) {\r\n throw new Error(`Cannot popState ${ state } when in ${ this.state }`);\r\n }\r\n this.states.pop();\r\n }\r\n\r\n isState(state) {\r\n return this.state === state;\r\n }\r\n\r\n get state() {\r\n return this.states[this.states.length - 1];\r\n }\r\n\r\n /**\r\n * @function\r\n * @name astMemberExpressionUnroll\r\n * @desc Parses the abstract syntax tree for binary expression.\r\n *\r\n *

Utility function for astCallExpression.

\r\n *\r\n * @param {Object} ast - the AST object to parse\r\n *\r\n * @returns {String} the function namespace call, unrolled\r\n */\r\n astMemberExpressionUnroll(ast) {\r\n if (ast.type === 'Identifier') {\r\n return ast.name;\r\n } else if (ast.type === 'ThisExpression') {\r\n return 'this';\r\n }\r\n\r\n if (ast.type === 'MemberExpression') {\r\n if (ast.object && ast.property) {\r\n //babel sniffing\r\n if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') {\r\n return this.astMemberExpressionUnroll(ast.property);\r\n }\r\n\r\n return (\r\n this.astMemberExpressionUnroll(ast.object) +\r\n '.' +\r\n this.astMemberExpressionUnroll(ast.property)\r\n );\r\n }\r\n }\r\n\r\n //babel sniffing\r\n if (ast.hasOwnProperty('expressions')) {\r\n const firstExpression = ast.expressions[0];\r\n if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {\r\n return this.astMemberExpressionUnroll(ast.expressions[1]);\r\n }\r\n }\r\n\r\n // Failure, unknown expression\r\n throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast);\r\n }\r\n\r\n /**\r\n * @desc Parses the class function JS, and returns its Abstract Syntax Tree object.\r\n * This is used internally to convert to shader code\r\n *\r\n * @param {Object} [inParser] - Parser to use, assumes in scope 'parser' if null or undefined\r\n *\r\n * @returns {Object} The function AST Object, note that result is cached under this.ast;\r\n */\r\n getJsAST(inParser) {\r\n if (this.ast) {\r\n return this.ast;\r\n }\r\n if (typeof this.source === 'object') {\r\n this.traceFunctionAST(this.source);\r\n return this.ast = this.source;\r\n }\r\n\r\n const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : parse\r\n if (inParser === null) {\r\n throw new Error('Missing JS to AST parser');\r\n }\r\n\r\n const ast = Object.freeze(parser(`const parser_${ this.name } = ${ this.source };`, {\r\n locations: true\r\n }));\r\n // take out the function object, outside the var declarations\r\n const functionAST = ast.body[0].declarations[0].init;\r\n this.traceFunctionAST(functionAST);\r\n\r\n if (!ast) {\r\n throw new Error('Failed to parse JS code');\r\n }\r\n\r\n return this.ast = functionAST;\r\n }\r\n\r\n traceFunctionAST(ast) {\r\n const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast);\r\n this.contexts = contexts;\r\n this.identifiers = identifiers;\r\n this.functionCalls = functionCalls;\r\n this.declarations = [];\r\n this.functions = functions;\r\n for (let i = 0; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n const { ast, context, name, origin, forceInteger, assignable } = declaration;\r\n const { init } = ast;\r\n const dependencies = this.getDependencies(init);\r\n let valueType = null;\r\n\r\n if (forceInteger) {\r\n valueType = 'Integer';\r\n } else {\r\n if (init) {\r\n const realType = this.getType(init);\r\n switch (realType) {\r\n case 'Integer':\r\n case 'Float':\r\n case 'Number':\r\n if (init.type === 'MemberExpression') {\r\n valueType = realType;\r\n } else {\r\n valueType = 'Number';\r\n }\r\n break;\r\n case 'LiteralInteger':\r\n valueType = 'Number';\r\n break;\r\n default:\r\n valueType = realType;\r\n }\r\n }\r\n }\r\n this.declarations.push({\r\n valueType,\r\n dependencies,\r\n isSafe: this.isSafeDependencies(dependencies),\r\n ast,\r\n name,\r\n context,\r\n origin,\r\n assignable,\r\n });\r\n }\r\n\r\n for (let i = 0; i < functions.length; i++) {\r\n this.onNestedFunction(functions[i]);\r\n }\r\n }\r\n\r\n getDeclaration(ast) {\r\n for (let i = 0; i < this.identifiers.length; i++) {\r\n const identifier = this.identifiers[i];\r\n if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) {\r\n for (let j = 0; j < this.declarations.length; j++) {\r\n const declaration = this.declarations[j];\r\n if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) {\r\n return declaration;\r\n }\r\n }\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @desc Return the type of parameter sent to subKernel/Kernel.\r\n * @param {Object} ast - Identifier\r\n * @returns {String} Type of the parameter\r\n */\r\n getVariableType(ast) {\r\n if (ast.type !== 'Identifier') {\r\n throw new Error(`ast of ${ast.type} not \"Identifier\"`);\r\n }\r\n let type = null;\r\n const argumentIndex = this.argumentNames.indexOf(ast.name);\r\n if (argumentIndex === -1) {\r\n const declaration = this.getDeclaration(ast);\r\n if (declaration) {\r\n return declaration.valueType;\r\n }\r\n } else {\r\n const argumentType = this.argumentTypes[argumentIndex];\r\n if (argumentType) {\r\n type = argumentType;\r\n }\r\n }\r\n if (!type && this.strictTypingChecking) {\r\n throw new Error(`Declaration of ${name} not found`);\r\n }\r\n return type;\r\n }\r\n\r\n /**\r\n * Generally used to lookup the value type returned from a member expressions\r\n * @param {String} type\r\n * @return {String}\r\n */\r\n getLookupType(type) {\r\n if (!typeLookupMap.hasOwnProperty(type)) {\r\n throw new Error(`unknown typeLookupMap ${ type }`);\r\n }\r\n return typeLookupMap[type];\r\n }\r\n\r\n getConstantType(constantName) {\r\n if (this.constantTypes[constantName]) {\r\n const type = this.constantTypes[constantName];\r\n if (type === 'Float') {\r\n return 'Number';\r\n } else {\r\n return type;\r\n }\r\n }\r\n throw new Error(`Type for constant \"${ constantName }\" not declared`);\r\n }\r\n\r\n toString() {\r\n if (this._string) return this._string;\r\n return this._string = this.astGeneric(this.getJsAST(), []).join('').trim();\r\n }\r\n\r\n toJSON() {\r\n const settings = {\r\n source: this.source,\r\n name: this.name,\r\n constants: this.constants,\r\n constantTypes: this.constantTypes,\r\n isRootKernel: this.isRootKernel,\r\n isSubKernel: this.isSubKernel,\r\n debug: this.debug,\r\n output: this.output,\r\n loopMaxIterations: this.loopMaxIterations,\r\n argumentNames: this.argumentNames,\r\n argumentTypes: this.argumentTypes,\r\n argumentSizes: this.argumentSizes,\r\n returnType: this.returnType,\r\n leadingReturnStatement: this.leadingReturnStatement,\r\n followingReturnStatement: this.followingReturnStatement,\r\n };\r\n\r\n return {\r\n ast: this.ast,\r\n settings\r\n };\r\n }\r\n\r\n /**\r\n * Recursively looks up type for ast expression until it's found\r\n * @param ast\r\n * @returns {String|null}\r\n */\r\n getType(ast) {\r\n if (Array.isArray(ast)) {\r\n return this.getType(ast[ast.length - 1]);\r\n }\r\n switch (ast.type) {\r\n case 'BlockStatement':\r\n return this.getType(ast.body);\r\n case 'ArrayExpression':\r\n return `Array(${ ast.elements.length })`;\r\n case 'Literal':\r\n const literalKey = `${ast.start},${ast.end}`;\r\n if (this.literalTypes[literalKey]) {\r\n return this.literalTypes[literalKey];\r\n }\r\n if (Number.isInteger(ast.value)) {\r\n return 'LiteralInteger';\r\n } else if (ast.value === true || ast.value === false) {\r\n return 'Boolean';\r\n } else {\r\n return 'Number';\r\n }\r\n case 'AssignmentExpression':\r\n return this.getType(ast.left);\r\n case 'CallExpression':\r\n if (this.isAstMathFunction(ast)) {\r\n return 'Number';\r\n }\r\n if (!ast.callee || !ast.callee.name) {\r\n if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) {\r\n const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name;\r\n this.inferArgumentTypesIfNeeded(functionName, ast.arguments);\r\n return this.lookupReturnType(functionName, ast, this);\r\n }\r\n throw this.astErrorOutput('Unknown call expression', ast);\r\n }\r\n if (ast.callee && ast.callee.name) {\r\n const functionName = ast.callee.name;\r\n this.inferArgumentTypesIfNeeded(functionName, ast.arguments);\r\n return this.lookupReturnType(functionName, ast, this);\r\n }\r\n throw this.astErrorOutput(`Unhandled getType Type \"${ ast.type }\"`, ast);\r\n case 'BinaryExpression':\r\n // modulos is Number\r\n switch (ast.operator) {\r\n case '%':\r\n case '/':\r\n if (this.fixIntegerDivisionAccuracy) {\r\n return 'Number';\r\n } else {\r\n break;\r\n }\r\n case '>':\r\n case '<':\r\n return 'Boolean';\r\n case '&':\r\n case '|':\r\n case '^':\r\n case '<<':\r\n case '>>':\r\n case '>>>':\r\n return 'Integer';\r\n }\r\n const type = this.getType(ast.left);\r\n if (this.isState('skip-literal-correction')) return type;\r\n if (type === 'LiteralInteger') {\r\n const rightType = this.getType(ast.right);\r\n if (rightType === 'LiteralInteger') {\r\n if (ast.left.value % 1 === 0) {\r\n return 'Integer';\r\n } else {\r\n return 'Float';\r\n }\r\n }\r\n return rightType;\r\n }\r\n return typeLookupMap[type] || type;\r\n case 'UpdateExpression':\r\n return this.getType(ast.argument);\r\n case 'UnaryExpression':\r\n if (ast.operator === '~') {\r\n return 'Integer';\r\n }\r\n return this.getType(ast.argument);\r\n case 'VariableDeclaration': {\r\n const declarations = ast.declarations;\r\n let lastType;\r\n for (let i = 0; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n lastType = this.getType(declaration);\r\n }\r\n if (!lastType) {\r\n throw this.astErrorOutput(`Unable to find type for declaration`, ast);\r\n }\r\n return lastType;\r\n }\r\n case 'VariableDeclarator':\r\n const declaration = this.getDeclaration(ast.id);\r\n if (!declaration) {\r\n throw this.astErrorOutput(`Unable to find declarator`, ast);\r\n }\r\n\r\n if (!declaration.valueType) {\r\n throw this.astErrorOutput(`Unable to find declarator valueType`, ast);\r\n }\r\n\r\n return declaration.valueType;\r\n case 'Identifier':\r\n if (ast.name === 'Infinity') {\r\n return 'Number';\r\n }\r\n if (this.isAstVariable(ast)) {\r\n const signature = this.getVariableSignature(ast);\r\n if (signature === 'value') {\r\n const type = this.getVariableType(ast);\r\n if (!type) {\r\n throw this.astErrorOutput(`Unable to find identifier valueType`, ast);\r\n }\r\n return type;\r\n }\r\n }\r\n const origin = this.findIdentifierOrigin(ast);\r\n if (origin && origin.init) {\r\n return this.getType(origin.init);\r\n }\r\n return null;\r\n case 'ReturnStatement':\r\n return this.getType(ast.argument);\r\n case 'MemberExpression':\r\n if (this.isAstMathFunction(ast)) {\r\n switch (ast.property.name) {\r\n case 'ceil':\r\n return 'Integer';\r\n case 'floor':\r\n return 'Integer';\r\n case 'round':\r\n return 'Integer';\r\n }\r\n return 'Number';\r\n }\r\n if (this.isAstVariable(ast)) {\r\n const variableSignature = this.getVariableSignature(ast);\r\n switch (variableSignature) {\r\n case 'value[]':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'value[][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object));\r\n case 'value[][][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object.object));\r\n case 'value[][][][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object.object.object));\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n return 'Integer';\r\n case 'this.output.value':\r\n return this.dynamicOutput ? 'Integer' : 'LiteralInteger';\r\n case 'this.constants.value':\r\n return this.getConstantType(ast.property.name);\r\n case 'this.constants.value[]':\r\n return this.getLookupType(this.getConstantType(ast.object.property.name));\r\n case 'this.constants.value[][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.property.name));\r\n case 'this.constants.value[][][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.object.property.name));\r\n case 'this.constants.value[][][][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name));\r\n case 'fn()[]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'fn()[][]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'fn()[][][]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'value.value':\r\n if (this.isAstMathVariable(ast)) {\r\n return 'Number';\r\n }\r\n switch (ast.property.name) {\r\n case 'r':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'g':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'b':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'a':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n }\r\n case '[][]':\r\n return 'Number';\r\n }\r\n throw this.astErrorOutput('Unhandled getType MemberExpression', ast);\r\n }\r\n throw this.astErrorOutput('Unhandled getType MemberExpression', ast);\r\n case 'ConditionalExpression':\r\n return this.getType(ast.consequent);\r\n case 'FunctionDeclaration':\r\n case 'FunctionExpression':\r\n const lastReturn = this.findLastReturn(ast.body);\r\n if (lastReturn) {\r\n return this.getType(lastReturn);\r\n }\r\n return null;\r\n case 'IfStatement':\r\n return this.getType(ast.consequent);\r\n default:\r\n throw this.astErrorOutput(`Unhandled getType Type \"${ ast.type }\"`, ast);\r\n }\r\n }\r\n\r\n inferArgumentTypesIfNeeded(functionName, args) {\r\n // ensure arguments are filled in, so when we lookup return type, we already can infer it\r\n for (let i = 0; i < args.length; i++) {\r\n if (!this.needsArgumentType(functionName, i)) continue;\r\n const type = this.getType(args[i]);\r\n if (!type) {\r\n throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]);\r\n }\r\n this.assignArgumentType(functionName, i, type);\r\n }\r\n }\r\n\r\n isAstMathVariable(ast) {\r\n const mathProperties = [\r\n 'E',\r\n 'PI',\r\n 'SQRT2',\r\n 'SQRT1_2',\r\n 'LN2',\r\n 'LN10',\r\n 'LOG2E',\r\n 'LOG10E',\r\n ];\r\n return ast.type === 'MemberExpression' &&\r\n ast.object && ast.object.type === 'Identifier' &&\r\n ast.object.name === 'Math' &&\r\n ast.property &&\r\n ast.property.type === 'Identifier' &&\r\n mathProperties.indexOf(ast.property.name) > -1;\r\n }\r\n\r\n isAstMathFunction(ast) {\r\n const mathFunctions = [\r\n 'abs',\r\n 'acos',\r\n 'asin',\r\n 'atan',\r\n 'atan2',\r\n 'ceil',\r\n 'cos',\r\n 'exp',\r\n 'floor',\r\n 'log',\r\n 'log2',\r\n 'max',\r\n 'min',\r\n 'pow',\r\n 'random',\r\n 'round',\r\n 'sign',\r\n 'sin',\r\n 'sqrt',\r\n 'tan',\r\n ];\r\n return ast.type === 'CallExpression' &&\r\n ast.callee &&\r\n ast.callee.type === 'MemberExpression' &&\r\n ast.callee.object &&\r\n ast.callee.object.type === 'Identifier' &&\r\n ast.callee.object.name === 'Math' &&\r\n ast.callee.property &&\r\n ast.callee.property.type === 'Identifier' &&\r\n mathFunctions.indexOf(ast.callee.property.name) > -1;\r\n }\r\n\r\n isAstVariable(ast) {\r\n return ast.type === 'Identifier' || ast.type === 'MemberExpression';\r\n }\r\n\r\n isSafe(ast) {\r\n return this.isSafeDependencies(this.getDependencies(ast));\r\n }\r\n\r\n isSafeDependencies(dependencies) {\r\n return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true;\r\n }\r\n\r\n /**\r\n *\r\n * @param ast\r\n * @param dependencies\r\n * @param isNotSafe\r\n * @return {Array}\r\n */\r\n getDependencies(ast, dependencies, isNotSafe) {\r\n if (!dependencies) {\r\n dependencies = [];\r\n }\r\n if (!ast) return null;\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.getDependencies(ast[i], dependencies, isNotSafe);\r\n }\r\n return dependencies;\r\n }\r\n switch (ast.type) {\r\n case 'AssignmentExpression':\r\n this.getDependencies(ast.left, dependencies, isNotSafe);\r\n this.getDependencies(ast.right, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'ConditionalExpression':\r\n this.getDependencies(ast.test, dependencies, isNotSafe);\r\n this.getDependencies(ast.alternate, dependencies, isNotSafe);\r\n this.getDependencies(ast.consequent, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'Literal':\r\n dependencies.push({\r\n origin: 'literal',\r\n value: ast.value,\r\n isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value)\r\n });\r\n break;\r\n case 'VariableDeclarator':\r\n return this.getDependencies(ast.init, dependencies, isNotSafe);\r\n case 'Identifier':\r\n const declaration = this.getDeclaration(ast);\r\n if (declaration) {\r\n dependencies.push({\r\n name: ast.name,\r\n origin: 'declaration',\r\n isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies),\r\n });\r\n } else if (this.argumentNames.indexOf(ast.name) > -1) {\r\n dependencies.push({\r\n name: ast.name,\r\n origin: 'argument',\r\n isSafe: false,\r\n });\r\n } else if (this.strictTypingChecking) {\r\n throw new Error(`Cannot find identifier origin \"${ast.name}\"`);\r\n }\r\n break;\r\n case 'FunctionDeclaration':\r\n return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe);\r\n case 'ReturnStatement':\r\n return this.getDependencies(ast.argument, dependencies);\r\n case 'BinaryExpression':\r\n isNotSafe = (ast.operator === '/' || ast.operator === '*');\r\n this.getDependencies(ast.left, dependencies, isNotSafe);\r\n this.getDependencies(ast.right, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'UnaryExpression':\r\n case 'UpdateExpression':\r\n return this.getDependencies(ast.argument, dependencies, isNotSafe);\r\n case 'VariableDeclaration':\r\n return this.getDependencies(ast.declarations, dependencies, isNotSafe);\r\n case 'ArrayExpression':\r\n dependencies.push({\r\n origin: 'declaration',\r\n isSafe: true,\r\n });\r\n return dependencies;\r\n case 'CallExpression':\r\n dependencies.push({\r\n origin: 'function',\r\n isSafe: true,\r\n });\r\n return dependencies;\r\n case 'MemberExpression':\r\n const details = this.getMemberExpressionDetails(ast);\r\n switch (details.signature) {\r\n case 'value[]':\r\n this.getDependencies(ast.object, dependencies, isNotSafe);\r\n break;\r\n case 'value[][]':\r\n this.getDependencies(ast.object.object, dependencies, isNotSafe);\r\n break;\r\n case 'value[][][]':\r\n this.getDependencies(ast.object.object.object, dependencies, isNotSafe);\r\n break;\r\n case 'this.output.value':\r\n if (this.dynamicOutput) {\r\n dependencies.push({\r\n name: details.name,\r\n origin: 'output',\r\n isSafe: false,\r\n });\r\n }\r\n break;\r\n }\r\n if (details) {\r\n if (details.property) {\r\n this.getDependencies(details.property, dependencies, isNotSafe);\r\n }\r\n if (details.xProperty) {\r\n this.getDependencies(details.xProperty, dependencies, isNotSafe);\r\n }\r\n if (details.yProperty) {\r\n this.getDependencies(details.yProperty, dependencies, isNotSafe);\r\n }\r\n if (details.zProperty) {\r\n this.getDependencies(details.zProperty, dependencies, isNotSafe);\r\n }\r\n return dependencies;\r\n }\r\n default:\r\n throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast);\r\n }\r\n return dependencies;\r\n }\r\n\r\n getVariableSignature(ast) {\r\n if (!this.isAstVariable(ast)) {\r\n throw new Error(`ast of type \"${ ast.type }\" is not a variable signature`);\r\n }\r\n if (ast.type === 'Identifier') {\r\n return 'value';\r\n }\r\n const signature = [];\r\n while (true) {\r\n if (!ast) break;\r\n if (ast.computed) {\r\n signature.push('[]');\r\n } else if (ast.type === 'ThisExpression') {\r\n signature.unshift('this');\r\n } else if (ast.property && ast.property.name) {\r\n if (\r\n ast.property.name === 'x' ||\r\n ast.property.name === 'y' ||\r\n ast.property.name === 'z'\r\n ) {\r\n signature.unshift('.value');\r\n } else if (\r\n ast.property.name === 'constants' ||\r\n ast.property.name === 'thread' ||\r\n ast.property.name === 'output'\r\n ) {\r\n signature.unshift('.' + ast.property.name);\r\n } else {\r\n signature.unshift('.value');\r\n }\r\n } else if (ast.name) {\r\n signature.unshift('value');\r\n } else if (ast.callee && ast.callee.name) {\r\n signature.unshift('fn()');\r\n } else if (ast.elements) {\r\n signature.unshift('[]');\r\n } else {\r\n signature.unshift('unknown');\r\n }\r\n ast = ast.object;\r\n }\r\n\r\n const signatureString = signature.join('');\r\n const allowedExpressions = [\r\n 'value',\r\n 'value[]',\r\n 'value[][]',\r\n 'value[][][]',\r\n 'value[][][][]',\r\n 'value.value',\r\n 'value.thread.value',\r\n 'this.thread.value',\r\n 'this.output.value',\r\n 'this.constants.value',\r\n 'this.constants.value[]',\r\n 'this.constants.value[][]',\r\n 'this.constants.value[][][]',\r\n 'this.constants.value[][][][]',\r\n 'fn()[]',\r\n 'fn()[][]',\r\n 'fn()[][][]',\r\n '[][]',\r\n ];\r\n if (allowedExpressions.indexOf(signatureString) > -1) {\r\n return signatureString;\r\n }\r\n return null;\r\n }\r\n\r\n build() {\r\n return this.toString().length > 0;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for generically to its respective function\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed string array\r\n */\r\n astGeneric(ast, retArr) {\r\n if (ast === null) {\r\n throw this.astErrorOutput('NULL ast', ast);\r\n } else {\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.astGeneric(ast[i], retArr);\r\n }\r\n return retArr;\r\n }\r\n\r\n switch (ast.type) {\r\n case 'FunctionDeclaration':\r\n return this.astFunctionDeclaration(ast, retArr);\r\n case 'FunctionExpression':\r\n return this.astFunctionExpression(ast, retArr);\r\n case 'ReturnStatement':\r\n return this.astReturnStatement(ast, retArr);\r\n case 'Literal':\r\n return this.astLiteral(ast, retArr);\r\n case 'BinaryExpression':\r\n return this.astBinaryExpression(ast, retArr);\r\n case 'Identifier':\r\n return this.astIdentifierExpression(ast, retArr);\r\n case 'AssignmentExpression':\r\n return this.astAssignmentExpression(ast, retArr);\r\n case 'ExpressionStatement':\r\n return this.astExpressionStatement(ast, retArr);\r\n case 'EmptyStatement':\r\n return this.astEmptyStatement(ast, retArr);\r\n case 'BlockStatement':\r\n return this.astBlockStatement(ast, retArr);\r\n case 'IfStatement':\r\n return this.astIfStatement(ast, retArr);\r\n case 'SwitchStatement':\r\n return this.astSwitchStatement(ast, retArr);\r\n case 'BreakStatement':\r\n return this.astBreakStatement(ast, retArr);\r\n case 'ContinueStatement':\r\n return this.astContinueStatement(ast, retArr);\r\n case 'ForStatement':\r\n return this.astForStatement(ast, retArr);\r\n case 'WhileStatement':\r\n return this.astWhileStatement(ast, retArr);\r\n case 'DoWhileStatement':\r\n return this.astDoWhileStatement(ast, retArr);\r\n case 'VariableDeclaration':\r\n return this.astVariableDeclaration(ast, retArr);\r\n case 'VariableDeclarator':\r\n return this.astVariableDeclarator(ast, retArr);\r\n case 'ThisExpression':\r\n return this.astThisExpression(ast, retArr);\r\n case 'SequenceExpression':\r\n return this.astSequenceExpression(ast, retArr);\r\n case 'UnaryExpression':\r\n return this.astUnaryExpression(ast, retArr);\r\n case 'UpdateExpression':\r\n return this.astUpdateExpression(ast, retArr);\r\n case 'LogicalExpression':\r\n return this.astLogicalExpression(ast, retArr);\r\n case 'MemberExpression':\r\n return this.astMemberExpression(ast, retArr);\r\n case 'CallExpression':\r\n return this.astCallExpression(ast, retArr);\r\n case 'ArrayExpression':\r\n return this.astArrayExpression(ast, retArr);\r\n case 'DebuggerStatement':\r\n return this.astDebuggerStatement(ast, retArr);\r\n case 'ConditionalExpression':\r\n return this.astConditionalExpression(ast, retArr);\r\n }\r\n\r\n throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast);\r\n }\r\n }\r\n /**\r\n * @desc To throw the AST error, with its location.\r\n * @param {string} error - the error message output\r\n * @param {Object} ast - the AST object where the error is\r\n */\r\n astErrorOutput(error, ast) {\r\n if (typeof this.source !== 'string') {\r\n return new Error(error);\r\n }\r\n\r\n const debugString = getAstString(this.source, ast);\r\n const leadingSource = this.source.substr(ast.start);\r\n const splitLines = leadingSource.split(/\\n/);\r\n const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0;\r\n return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\\n ${ debugString }`);\r\n }\r\n\r\n astDebuggerStatement(arrNode, retArr) {\r\n return retArr;\r\n }\r\n\r\n astConditionalExpression(ast, retArr) {\r\n if (ast.type !== 'ConditionalExpression') {\r\n throw this.astErrorOutput('Not a conditional expression', ast);\r\n }\r\n retArr.push('(');\r\n this.astGeneric(ast.test, retArr);\r\n retArr.push('?');\r\n this.astGeneric(ast.consequent, retArr);\r\n retArr.push(':');\r\n this.astGeneric(ast.alternate, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @param {Object} ast\r\n * @param {String[]} retArr\r\n * @returns {String[]}\r\n */\r\n astFunction(ast, retArr) {\r\n throw new Error(`\"astFunction\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function declaration*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunctionDeclaration(ast, retArr) {\r\n if (this.isChildFunction(ast)) {\r\n return retArr;\r\n }\r\n return this.astFunction(ast, retArr);\r\n }\r\n astFunctionExpression(ast, retArr) {\r\n if (this.isChildFunction(ast)) {\r\n return retArr;\r\n }\r\n return this.astFunction(ast, retArr);\r\n }\r\n isChildFunction(ast) {\r\n for (let i = 0; i < this.functions.length; i++) {\r\n if (this.functions[i] === ast) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n astReturnStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astLiteral(ast, retArr) {\r\n this.literalTypes[`${ast.start},${ast.end}`] = 'Number';\r\n return retArr;\r\n }\r\n astBinaryExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astIdentifierExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astAssignmentExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *generic expression* statement\r\n * @param {Object} esNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astExpressionStatement(esNode, retArr) {\r\n this.astGeneric(esNode.expression, retArr);\r\n retArr.push(';');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for an *Empty* Statement\r\n * @param {Object} eNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astEmptyStatement(eNode, retArr) {\r\n return retArr;\r\n }\r\n astBlockStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astIfStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astSwitchStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Break* Statement\r\n * @param {Object} brNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBreakStatement(brNode, retArr) {\r\n retArr.push('break;');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Continue* Statement\r\n * @param {Object} crNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astContinueStatement(crNode, retArr) {\r\n retArr.push('continue;\\n');\r\n return retArr;\r\n }\r\n astForStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astWhileStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astDoWhileStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declaration*\r\n * @param {Object} varDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclaration(varDecNode, retArr) {\r\n const declarations = varDecNode.declarations;\r\n if (!declarations || !declarations[0] || !declarations[0].init) {\r\n throw this.astErrorOutput('Unexpected expression', varDecNode);\r\n }\r\n const result = [];\r\n const firstDeclaration = declarations[0];\r\n const init = firstDeclaration.init;\r\n let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init);\r\n if (type === 'LiteralInteger') {\r\n // We had the choice to go either float or int, choosing float\r\n type = 'Number';\r\n }\r\n const markupType = typeMap[type];\r\n if (!markupType) {\r\n throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode);\r\n }\r\n let dependencies = this.getDependencies(firstDeclaration.init);\r\n throw new Error('remove me');\r\n this.declarations[firstDeclaration.id.name] = Object.freeze({\r\n type,\r\n dependencies,\r\n isSafe: dependencies.every(dependency => dependency.isSafe)\r\n });\r\n const initResult = [`${type} user_${firstDeclaration.id.name}=`];\r\n this.astGeneric(init, initResult);\r\n result.push(initResult.join(''));\r\n\r\n // first declaration is done, now any added ones setup\r\n for (let i = 1; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n dependencies = this.getDependencies(declaration);\r\n throw new Error('Remove me');\r\n this.declarations[declaration.id.name] = Object.freeze({\r\n type,\r\n dependencies,\r\n isSafe: false\r\n });\r\n this.astGeneric(declaration, result);\r\n }\r\n\r\n retArr.push(retArr, result.join(','));\r\n retArr.push(';');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declarator*\r\n * @param {Object} iVarDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclarator(iVarDecNode, retArr) {\r\n this.astGeneric(iVarDecNode.id, retArr);\r\n if (iVarDecNode.init !== null) {\r\n retArr.push('=');\r\n this.astGeneric(iVarDecNode.init, retArr);\r\n }\r\n return retArr;\r\n }\r\n astThisExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astSequenceExpression(sNode, retArr) {\r\n for (let i = 0; i < sNode.expressions.length; i++) {\r\n if (i > 0) {\r\n retArr.push(',');\r\n }\r\n this.astGeneric(sNode.expressions, retArr);\r\n }\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Unary* Expression\r\n * @param {Object} uNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astUnaryExpression(uNode, retArr) {\r\n const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr);\r\n if (unaryResult) {\r\n return retArr;\r\n }\r\n\r\n if (uNode.prefix) {\r\n retArr.push(uNode.operator);\r\n this.astGeneric(uNode.argument, retArr);\r\n } else {\r\n this.astGeneric(uNode.argument, retArr);\r\n retArr.push(uNode.operator);\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseUnary(uNode, retArr) {}\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Update* Expression\r\n * @param {Object} uNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astUpdateExpression(uNode, retArr) {\r\n if (uNode.prefix) {\r\n retArr.push(uNode.operator);\r\n this.astGeneric(uNode.argument, retArr);\r\n } else {\r\n this.astGeneric(uNode.argument, retArr);\r\n retArr.push(uNode.operator);\r\n }\r\n\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Logical* Expression\r\n * @param {Object} logNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astLogicalExpression(logNode, retArr) {\r\n retArr.push('(');\r\n this.astGeneric(logNode.left, retArr);\r\n retArr.push(logNode.operator);\r\n this.astGeneric(logNode.right, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n astMemberExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astCallExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astArrayExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param ast\r\n * @return {IFunctionNodeMemberExpressionDetails}\r\n */\r\n getMemberExpressionDetails(ast) {\r\n if (ast.type !== 'MemberExpression') {\r\n throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast);\r\n }\r\n let name = null;\r\n let type = null;\r\n const variableSignature = this.getVariableSignature(ast);\r\n switch (variableSignature) {\r\n case 'value':\r\n return null;\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n case 'this.output.value':\r\n return {\r\n signature: variableSignature,\r\n type: 'Integer',\r\n name: ast.property.name\r\n };\r\n case 'value[]':\r\n if (typeof ast.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object),\r\n xProperty: ast.property\r\n };\r\n case 'value[][]':\r\n if (typeof ast.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object),\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value[][][]':\r\n if (typeof ast.object.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object.object),\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value[][][][]':\r\n if (typeof ast.object.object.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object.object.object),\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value.value':\r\n if (typeof ast.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n if (this.isAstMathVariable(ast)) {\r\n name = ast.property.name;\r\n return {\r\n name,\r\n origin: 'Math',\r\n type: 'Number',\r\n signature: variableSignature,\r\n };\r\n }\r\n switch (ast.property.name) {\r\n case 'r':\r\n case 'g':\r\n case 'b':\r\n case 'a':\r\n name = ast.object.name;\r\n return {\r\n name,\r\n property: ast.property.name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: 'Number'\r\n };\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n case 'this.constants.value':\r\n if (typeof ast.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n };\r\n case 'this.constants.value[]':\r\n if (typeof ast.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n xProperty: ast.property,\r\n };\r\n case 'this.constants.value[][]': {\r\n if (typeof ast.object.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n }\r\n case 'this.constants.value[][][]': {\r\n if (typeof ast.object.object.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n }\r\n case 'fn()[]':\r\n case '[][]':\r\n return {\r\n signature: variableSignature,\r\n property: ast.property,\r\n };\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n }\r\n\r\n findIdentifierOrigin(astToFind) {\r\n const stack = [this.ast];\r\n\r\n while (stack.length > 0) {\r\n const atNode = stack[0];\r\n if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) {\r\n return atNode;\r\n }\r\n stack.shift();\r\n if (atNode.argument) {\r\n stack.push(atNode.argument);\r\n } else if (atNode.body) {\r\n stack.push(atNode.body);\r\n } else if (atNode.declarations) {\r\n stack.push(atNode.declarations);\r\n } else if (Array.isArray(atNode)) {\r\n for (let i = 0; i < atNode.length; i++) {\r\n stack.push(atNode[i]);\r\n }\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n findLastReturn(ast) {\r\n const stack = [ast || this.ast];\r\n\r\n while (stack.length > 0) {\r\n const atNode = stack.pop();\r\n if (atNode.type === 'ReturnStatement') {\r\n return atNode;\r\n }\r\n if (atNode.type === 'FunctionDeclaration') {\r\n continue;\r\n }\r\n if (atNode.argument) {\r\n stack.push(atNode.argument);\r\n } else if (atNode.body) {\r\n stack.push(atNode.body);\r\n } else if (atNode.declarations) {\r\n stack.push(atNode.declarations);\r\n } else if (Array.isArray(atNode)) {\r\n for (let i = 0; i < atNode.length; i++) {\r\n stack.push(atNode[i]);\r\n }\r\n } else if (atNode.consequent) {\r\n stack.push(atNode.consequent);\r\n } else if (atNode.cases) {\r\n stack.push(atNode.cases);\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n getInternalVariableName(name) {\r\n if (!this._internalVariableNames.hasOwnProperty(name)) {\r\n this._internalVariableNames[name] = 0;\r\n }\r\n this._internalVariableNames[name]++;\r\n if (this._internalVariableNames[name] === 1) {\r\n return name;\r\n }\r\n return name + this._internalVariableNames[name];\r\n }\r\n\r\n varWarn() {\r\n console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let');\r\n }\r\n}\r\n\r\nconst typeLookupMap = {\r\n 'Number': 'Number',\r\n 'Float': 'Float',\r\n 'Integer': 'Integer',\r\n 'Array': 'Number',\r\n 'Array(2)': 'Number',\r\n 'Array(3)': 'Number',\r\n 'Array(4)': 'Number',\r\n 'Array2D': 'Number',\r\n 'Array3D': 'Number',\r\n 'Input': 'Number',\r\n 'HTMLImage': 'Array(4)',\r\n 'HTMLVideo': 'Array(4)',\r\n 'HTMLImageArray': 'Array(4)',\r\n 'NumberTexture': 'Number',\r\n 'MemoryOptimizedNumberTexture': 'Number',\r\n 'Array1D(2)': 'Array(2)',\r\n 'Array1D(3)': 'Array(3)',\r\n 'Array1D(4)': 'Array(4)',\r\n 'Array2D(2)': 'Array(2)',\r\n 'Array2D(3)': 'Array(3)',\r\n 'Array2D(4)': 'Array(4)',\r\n 'Array3D(2)': 'Array(2)',\r\n 'Array3D(3)': 'Array(3)',\r\n 'Array3D(4)': 'Array(4)',\r\n 'ArrayTexture(1)': 'Number',\r\n 'ArrayTexture(2)': 'Array(2)',\r\n 'ArrayTexture(3)': 'Array(3)',\r\n 'ArrayTexture(4)': 'Array(4)',\r\n};\r\n","import { FunctionNode } from '../function-node';\r\n\r\n/**\r\n * @desc [INTERNAL] Represents a single function, inside JS\r\n *\r\n *

This handles all the raw state, converted state, etc. Of a single function.

\r\n */\r\nexport class CPUFunctionNode extends FunctionNode {\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunction(ast, retArr) {\r\n\r\n // Setup function return type and name\r\n if (!this.isRootKernel) {\r\n retArr.push('function');\r\n retArr.push(' ');\r\n retArr.push(this.name);\r\n retArr.push('(');\r\n\r\n // Arguments handling\r\n for (let i = 0; i < this.argumentNames.length; ++i) {\r\n const argumentName = this.argumentNames[i];\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n retArr.push('user_');\r\n retArr.push(argumentName);\r\n }\r\n\r\n // Function opening\r\n retArr.push(') {\\n');\r\n }\r\n\r\n // Body statement iteration\r\n for (let i = 0; i < ast.body.body.length; ++i) {\r\n this.astGeneric(ast.body.body[i], retArr);\r\n retArr.push('\\n');\r\n }\r\n\r\n if (!this.isRootKernel) {\r\n // Function closing\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to *return* statement\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astReturnStatement(ast, retArr) {\r\n const type = this.returnType || this.getType(ast.argument);\r\n\r\n if (!this.returnType) {\r\n this.returnType = type;\r\n }\r\n\r\n if (this.isRootKernel) {\r\n retArr.push(this.leadingReturnStatement);\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';\\n');\r\n retArr.push(this.followingReturnStatement);\r\n retArr.push('continue;\\n');\r\n } else if (this.isSubKernel) {\r\n retArr.push(`subKernelResult_${ this.name } = `);\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';');\r\n retArr.push(`return subKernelResult_${ this.name };`);\r\n } else {\r\n retArr.push('return ');\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *literal value*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astLiteral(ast, retArr) {\r\n\r\n // Reject non numeric literals\r\n if (isNaN(ast.value)) {\r\n throw this.astErrorOutput(\r\n 'Non-numeric literal not supported : ' + ast.value,\r\n ast\r\n );\r\n }\r\n\r\n retArr.push(ast.value);\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *binary* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBinaryExpression(ast, retArr) {\r\n retArr.push('(');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput(\r\n 'IdentifierExpression - not an Identifier',\r\n idtNode\r\n );\r\n }\r\n\r\n switch (idtNode.name) {\r\n case 'Infinity':\r\n retArr.push('Infinity');\r\n break;\r\n default:\r\n if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {\r\n retArr.push('constants_' + idtNode.name);\r\n } else {\r\n retArr.push('user_' + idtNode.name);\r\n }\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *for-loop* expression\r\n * @param {Object} forNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astForStatement(forNode, retArr) {\r\n if (forNode.type !== 'ForStatement') {\r\n throw this.astErrorOutput('Invalid for statement', forNode);\r\n }\r\n\r\n const initArr = [];\r\n const testArr = [];\r\n const updateArr = [];\r\n const bodyArr = [];\r\n let isSafe = null;\r\n\r\n if (forNode.init) {\r\n this.pushState('in-for-loop-init');\r\n this.astGeneric(forNode.init, initArr);\r\n for (let i = 0; i < initArr.length; i++) {\r\n if (initArr[i].includes && initArr[i].includes(',')) {\r\n isSafe = false;\r\n }\r\n }\r\n this.popState('in-for-loop-init');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.test) {\r\n this.astGeneric(forNode.test, testArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.update) {\r\n this.astGeneric(forNode.update, updateArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.body) {\r\n this.pushState('loop-body');\r\n this.astGeneric(forNode.body, bodyArr);\r\n this.popState('loop-body');\r\n }\r\n\r\n // have all parts, now make them safe\r\n if (isSafe === null) {\r\n isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);\r\n }\r\n\r\n if (isSafe) {\r\n retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\\n`);\r\n retArr.push(bodyArr.join(''));\r\n retArr.push('}\\n');\r\n } else {\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n if (initArr.length > 0) {\r\n retArr.push(initArr.join(''), ';\\n');\r\n }\r\n retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) {\r\n retArr.push(`if (!${testArr.join('')}) break;\\n`);\r\n }\r\n retArr.push(bodyArr.join(''));\r\n retArr.push(`\\n${updateArr.join('')};`);\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *while* loop\r\n * @param {Object} whileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed javascript string\r\n */\r\n astWhileStatement(whileNode, retArr) {\r\n if (whileNode.type !== 'WhileStatement') {\r\n throw this.astErrorOutput(\r\n 'Invalid while statement',\r\n whileNode\r\n );\r\n }\r\n\r\n retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');\r\n retArr.push('if (');\r\n this.astGeneric(whileNode.test, retArr);\r\n retArr.push(') {\\n');\r\n this.astGeneric(whileNode.body, retArr);\r\n retArr.push('} else {\\n');\r\n retArr.push('break;\\n');\r\n retArr.push('}\\n');\r\n retArr.push('}\\n');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *do while* loop\r\n * @param {Object} doWhileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astDoWhileStatement(doWhileNode, retArr) {\r\n if (doWhileNode.type !== 'DoWhileStatement') {\r\n throw this.astErrorOutput(\r\n 'Invalid while statement',\r\n doWhileNode\r\n );\r\n }\r\n\r\n retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');\r\n this.astGeneric(doWhileNode.body, retArr);\r\n retArr.push('if (!');\r\n this.astGeneric(doWhileNode.test, retArr);\r\n retArr.push(') {\\n');\r\n retArr.push('break;\\n');\r\n retArr.push('}\\n');\r\n retArr.push('}\\n');\r\n\r\n return retArr;\r\n\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Assignment* Expression\r\n * @param {Object} assNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astAssignmentExpression(assNode, retArr) {\r\n const declaration = this.getDeclaration(assNode.left);\r\n if (declaration && !declaration.assignable) {\r\n throw new this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode);\r\n }\r\n this.astGeneric(assNode.left, retArr);\r\n retArr.push(assNode.operator);\r\n this.astGeneric(assNode.right, retArr);\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Block* statement\r\n * @param {Object} bNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBlockStatement(bNode, retArr) {\r\n if (this.isState('loop-body')) {\r\n this.pushState('block-body'); // this prevents recursive removal of braces\r\n for (let i = 0; i < bNode.body.length; i++) {\r\n this.astGeneric(bNode.body[i], retArr);\r\n }\r\n this.popState('block-body');\r\n } else {\r\n retArr.push('{\\n');\r\n for (let i = 0; i < bNode.body.length; i++) {\r\n this.astGeneric(bNode.body[i], retArr);\r\n }\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declaration*\r\n * @param {Object} varDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclaration(varDecNode, retArr) {\r\n if (varDecNode.kind === 'var' && this.warnVarUsage) {\r\n this.varWarn();\r\n }\r\n retArr.push(`${varDecNode.kind} `);\r\n const { declarations } = varDecNode;\r\n for (let i = 0; i < declarations.length; i++) {\r\n if (i > 0) {\r\n retArr.push(',');\r\n }\r\n this.astGeneric(declarations[i], retArr);\r\n }\r\n if (!this.isState('in-for-loop-init')) {\r\n retArr.push(';');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *If* Statement\r\n * @param {Object} ifNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIfStatement(ifNode, retArr) {\r\n retArr.push('if (');\r\n this.astGeneric(ifNode.test, retArr);\r\n retArr.push(')');\r\n if (ifNode.consequent.type === 'BlockStatement') {\r\n this.astGeneric(ifNode.consequent, retArr);\r\n } else {\r\n retArr.push(' {\\n');\r\n this.astGeneric(ifNode.consequent, retArr);\r\n retArr.push('\\n}\\n');\r\n }\r\n\r\n if (ifNode.alternate) {\r\n retArr.push('else ');\r\n if (ifNode.alternate.type === 'BlockStatement') {\r\n this.astGeneric(ifNode.alternate, retArr);\r\n } else {\r\n retArr.push(' {\\n');\r\n this.astGeneric(ifNode.alternate, retArr);\r\n retArr.push('\\n}\\n');\r\n }\r\n }\r\n return retArr;\r\n\r\n }\r\n\r\n astSwitchStatement(ast, retArr) {\r\n const { discriminant, cases } = ast;\r\n retArr.push('switch (');\r\n this.astGeneric(discriminant, retArr);\r\n retArr.push(') {\\n');\r\n for (let i = 0; i < cases.length; i++) {\r\n if (cases[i].test === null) {\r\n retArr.push('default:\\n');\r\n this.astGeneric(cases[i].consequent, retArr);\r\n if (cases[i].consequent && cases[i].consequent.length > 0) {\r\n retArr.push('break;\\n');\r\n }\r\n continue;\r\n }\r\n retArr.push('case ');\r\n this.astGeneric(cases[i].test, retArr);\r\n retArr.push(':\\n');\r\n if (cases[i].consequent && cases[i].consequent.length > 0) {\r\n this.astGeneric(cases[i].consequent, retArr);\r\n retArr.push('break;\\n');\r\n }\r\n }\r\n retArr.push('\\n}');\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *This* expression\r\n * @param {Object} tNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astThisExpression(tNode, retArr) {\r\n retArr.push('_this');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Member* Expression\r\n * @param {Object} mNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astMemberExpression(mNode, retArr) {\r\n const {\r\n signature,\r\n type,\r\n property,\r\n xProperty,\r\n yProperty,\r\n zProperty,\r\n name,\r\n origin\r\n } = this.getMemberExpressionDetails(mNode);\r\n switch (signature) {\r\n case 'this.thread.value':\r\n retArr.push(`_this.thread.${ name }`);\r\n return retArr;\r\n case 'this.output.value':\r\n switch (name) {\r\n case 'x':\r\n retArr.push('outputX');\r\n break;\r\n case 'y':\r\n retArr.push('outputY');\r\n break;\r\n case 'z':\r\n retArr.push('outputZ');\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n return retArr;\r\n case 'value':\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n case 'value[]':\r\n case 'value[][]':\r\n case 'value[][][]':\r\n case 'value.value':\r\n if (origin === 'Math') {\r\n retArr.push(Math[name]);\r\n return retArr;\r\n }\r\n switch (property) {\r\n case 'r':\r\n retArr.push(`user_${ name }[0]`);\r\n return retArr;\r\n case 'g':\r\n retArr.push(`user_${ name }[1]`);\r\n return retArr;\r\n case 'b':\r\n retArr.push(`user_${ name }[2]`);\r\n return retArr;\r\n case 'a':\r\n retArr.push(`user_${ name }[3]`);\r\n return retArr;\r\n }\r\n break;\r\n case 'this.constants.value':\r\n case 'this.constants.value[]':\r\n case 'this.constants.value[][]':\r\n case 'this.constants.value[][][]':\r\n break;\r\n case 'fn()[]':\r\n this.astGeneric(mNode.object, retArr);\r\n retArr.push('[');\r\n this.astGeneric(mNode.property, retArr);\r\n retArr.push(']');\r\n return retArr;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n\r\n if (!mNode.computed) {\r\n // handle simple types\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n retArr.push(`${origin}_${name}`);\r\n return retArr;\r\n }\r\n }\r\n\r\n // handle more complex types\r\n // argument may have come from a parent\r\n const markupName = `${origin}_${name}`;\r\n\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n case 'HTMLImageArray':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'HTMLImage':\r\n default:\r\n let size;\r\n let isInput;\r\n if (origin === 'constants') {\r\n const constant = this.constants[name];\r\n isInput = this.constantTypes[name] === 'Input';\r\n size = isInput ? constant.size : null;\r\n } else {\r\n isInput = this.isInput(name);\r\n size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null;\r\n }\r\n retArr.push(`${ markupName }`);\r\n if (zProperty && yProperty) {\r\n if (isInput) {\r\n retArr.push('[(');\r\n this.astGeneric(zProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`);\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n } else {\r\n retArr.push('[');\r\n this.astGeneric(zProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n } else if (yProperty) {\r\n if (isInput) {\r\n retArr.push('[(');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n } else {\r\n retArr.push('[');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n } else if (typeof xProperty !== 'undefined') {\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *call* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astCallExpression(ast, retArr) {\r\n if (ast.type !== 'CallExpression') {\r\n // Failure, unknown expression\r\n throw this.astErrorOutput('Unknown CallExpression', ast);\r\n }\r\n // Get the full function call, unrolled\r\n let functionName = this.astMemberExpressionUnroll(ast.callee);\r\n\r\n // Register the function into the called registry\r\n if (this.calledFunctions.indexOf(functionName) < 0) {\r\n this.calledFunctions.push(functionName);\r\n }\r\n\r\n const isMathFunction = this.isAstMathFunction(ast);\r\n\r\n // track the function was called\r\n if (this.onFunctionCall) {\r\n this.onFunctionCall(this.name, functionName, ast.arguments);\r\n }\r\n\r\n // Call the function\r\n retArr.push(functionName);\r\n\r\n // Open arguments space\r\n retArr.push('(');\r\n const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];\r\n // Add the arguments\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n\r\n // in order to track return type, even though this is CPU\r\n let argumentType = this.getType(argument);\r\n if (!targetTypes[i]) {\r\n this.triggerImplyArgumentType(functionName, i, argumentType, this);\r\n }\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n this.astGeneric(argument, retArr);\r\n }\r\n // Close arguments space\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Array* Expression\r\n * @param {Object} arrNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astArrayExpression(arrNode, retArr) {\r\n const arrLen = arrNode.elements.length;\r\n\r\n retArr.push('new Float32Array([');\r\n for (let i = 0; i < arrLen; ++i) {\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const subNode = arrNode.elements[i];\r\n this.astGeneric(subNode, retArr)\r\n }\r\n retArr.push('])');\r\n\r\n return retArr;\r\n }\r\n\r\n astDebuggerStatement(arrNode, retArr) {\r\n retArr.push('debugger;');\r\n return retArr;\r\n }\r\n}\r\n","import { utils } from '../../utils'\r\n\r\nfunction constantsToString(constants, types) {\r\n const results = [];\r\n for (const name in types) {\r\n if (!types.hasOwnProperty(name)) continue;\r\n const type = types[name];\r\n const constant = constants[name];\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n results.push(`${name}:${constant}`);\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`);\r\n break;\r\n }\r\n }\r\n return `{ ${ results.join() } }`;\r\n}\r\n\r\nexport function cpuKernelString(cpuKernel, name) {\r\n const header = [];\r\n const thisProperties = [];\r\n const beforeReturn = [];\r\n\r\n const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString());\r\n\r\n header.push(\r\n ' const { context, canvas, constants: incomingConstants } = settings;',\r\n ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`,\r\n ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`,\r\n ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`,\r\n );\r\n\r\n thisProperties.push(\r\n ' constants: _constants,',\r\n ' context,',\r\n ' output,',\r\n ' thread: {x: 0, y: 0, z: 0},',\r\n );\r\n\r\n if (cpuKernel.graphical) {\r\n header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`);\r\n header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`);\r\n\r\n const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), {\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case '_colorData':\r\n return '_colorData';\r\n case '_imageData':\r\n return '_imageData';\r\n case 'output':\r\n return 'output';\r\n case 'thread':\r\n return 'this.thread';\r\n }\r\n return JSON.stringify(cpuKernel[propertyName]);\r\n },\r\n findDependency: (object, name) => {\r\n return null;\r\n }\r\n });\r\n\r\n const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), {\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case '_colorData':\r\n return '_colorData';\r\n case '_imageData':\r\n return '_imageData';\r\n case 'output':\r\n return 'output';\r\n case 'thread':\r\n return 'this.thread';\r\n }\r\n return JSON.stringify(cpuKernel[propertyName]);\r\n },\r\n findDependency: () => {\r\n return null;\r\n }\r\n });\r\n\r\n thisProperties.push(\r\n ' _imageData,',\r\n ' _colorData,',\r\n ` color: ${colorFn},`,\r\n );\r\n\r\n beforeReturn.push(\r\n ` kernel.getPixels = ${getPixelsFn};`\r\n );\r\n }\r\n\r\n const constantTypes = [];\r\n const constantKeys = Object.keys(cpuKernel.constantTypes);\r\n for (let i = 0; i < constantKeys.length; i++) {\r\n constantTypes.push(cpuKernel.constantTypes[constantKeys]);\r\n }\r\n if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) {\r\n const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), {\r\n doNotDefine: ['canvas'],\r\n findDependency: (object, name) => {\r\n if (object === 'this') {\r\n return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString();\r\n }\r\n return null;\r\n },\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case 'canvas':\r\n return;\r\n case 'context':\r\n return 'context';\r\n }\r\n }\r\n });\r\n beforeReturn.push(flattenedImageTo3DArray);\r\n thisProperties.push(` _mediaTo2DArray,`);\r\n thisProperties.push(` _imageTo3DArray,`);\r\n } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) {\r\n const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), {\r\n findDependency: (object, name) => {\r\n return null;\r\n },\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case 'canvas':\r\n return 'settings.canvas';\r\n case 'context':\r\n return 'settings.context';\r\n }\r\n throw new Error('unhandled thisLookup');\r\n }\r\n });\r\n beforeReturn.push(flattenedImageTo2DArray);\r\n thisProperties.push(` _mediaTo2DArray,`);\r\n }\r\n\r\n return `function(settings) {\r\n${ header.join('\\n') }\r\n for (const p in _constantTypes) {\r\n if (!_constantTypes.hasOwnProperty(p)) continue;\r\n const type = _constantTypes[p];\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n if (incomingConstants.hasOwnProperty(p)) {\r\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\r\n }\r\n continue;\r\n }\r\n if (!incomingConstants.hasOwnProperty(p)) {\r\n throw new Error('constant ' + p + ' not found');\r\n }\r\n _constants[p] = incomingConstants[p];\r\n }\r\n const kernel = (function() {\r\n${cpuKernel._kernelString}\r\n })\r\n .apply({ ${thisProperties.join('\\n')} });\r\n ${ beforeReturn.join('\\n') }\r\n return kernel;\r\n}`;\r\n}\r\n","import { Kernel } from '../kernel';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { CPUFunctionNode } from './function-node';\r\nimport { utils } from '../../utils';\r\nimport { cpuKernelString } from './kernel-string';\r\n\r\n/**\r\n * @desc Kernel Implementation for CPU.\r\n *

Instantiates properties to the CPU Kernel.

\r\n */\r\nexport class CPUKernel extends Kernel {\r\n static getFeatures() {\r\n return this.features;\r\n }\r\n static get features() {\r\n return Object.freeze({\r\n kernelMap: true,\r\n isIntegerDivisionAccurate: true\r\n });\r\n }\r\n static get isSupported() {\r\n return true;\r\n }\r\n static isContextMatch(context) {\r\n return false;\r\n }\r\n /**\r\n * @desc The current mode in which gpu.js is executing.\r\n */\r\n static get mode() {\r\n return 'cpu';\r\n }\r\n\r\n static nativeFunctionArguments() {\r\n return null;\r\n }\r\n\r\n static nativeFunctionReturnType() {\r\n return null;\r\n }\r\n\r\n static combineKernels(combinedKernel) {\r\n return combinedKernel;\r\n }\r\n\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.mergeSettings(source.settings || settings);\r\n\r\n this._imageData = null;\r\n this._colorData = null;\r\n this._kernelString = null;\r\n this.thread = {\r\n x: 0,\r\n y: 0,\r\n z: 0\r\n };\r\n this.translatedSources = null;\r\n }\r\n\r\n initCanvas() {\r\n if (typeof document !== 'undefined') {\r\n return document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n return new OffscreenCanvas(0, 0);\r\n }\r\n }\r\n\r\n initContext() {\r\n if (!this.canvas) return null;\r\n return this.canvas.getContext('2d');\r\n }\r\n\r\n initPlugins(settings) {\r\n return [];\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n if (argType === 'Array') {\r\n this.output = utils.getDimensions(argType);\r\n } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {\r\n this.output = args[0].output;\r\n } else {\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n }\r\n\r\n this.checkOutput();\r\n }\r\n\r\n translateSource() {\r\n this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = ';\r\n if (this.subKernels) {\r\n const followingReturnStatement = []\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const {\r\n name\r\n } = this.subKernels[i];\r\n followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\\n` : `result_${ name }[x] = subKernelResult_${ name };\\n`);\r\n }\r\n this.followingReturnStatement = followingReturnStatement.join('');\r\n }\r\n const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode);\r\n this.translatedSources = functionBuilder.getPrototypes('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n }\r\n\r\n /**\r\n * @desc Builds the Kernel, by generating the kernel\r\n * string using thread dimensions, and arguments\r\n * supplied to the kernel.\r\n *\r\n *

If the graphical flag is enabled, canvas is used.

\r\n */\r\n build() {\r\n this.setupConstants();\r\n this.setupArguments(arguments);\r\n this.validateSettings(arguments);\r\n this.translateSource();\r\n\r\n if (this.graphical) {\r\n const {\r\n canvas,\r\n output\r\n } = this;\r\n if (!canvas) {\r\n throw new Error('no canvas available for using graphical output');\r\n }\r\n const width = output[0];\r\n const height = output[1] || 1;\r\n canvas.width = width;\r\n canvas.height = height;\r\n this._imageData = this.context.createImageData(width, height);\r\n this._colorData = new Uint8ClampedArray(width * height * 4);\r\n }\r\n\r\n const kernelString = this.getKernelString();\r\n this.kernelString = kernelString;\r\n\r\n if (this.debug) {\r\n console.log('Function output:');\r\n console.log(kernelString);\r\n }\r\n\r\n try {\r\n this.run = new Function([], kernelString).bind(this)();\r\n } catch (e) {\r\n console.error('An error occurred compiling the javascript: ', e);\r\n }\r\n }\r\n\r\n color(r, g, b, a) {\r\n if (typeof a === 'undefined') {\r\n a = 1;\r\n }\r\n\r\n r = Math.floor(r * 255);\r\n g = Math.floor(g * 255);\r\n b = Math.floor(b * 255);\r\n a = Math.floor(a * 255);\r\n\r\n const width = this.output[0];\r\n const height = this.output[1];\r\n\r\n const x = this.thread.x;\r\n const y = height - this.thread.y - 1;\r\n\r\n const index = x + y * width;\r\n\r\n this._colorData[index * 4 + 0] = r;\r\n this._colorData[index * 4 + 1] = g;\r\n this._colorData[index * 4 + 2] = b;\r\n this._colorData[index * 4 + 3] = a;\r\n }\r\n\r\n /**\r\n * @desc Generates kernel string for this kernel program.\r\n *\r\n *

If sub-kernels are supplied, they are also factored in.\r\n * This string can be saved by calling the `toString` method\r\n * and then can be reused later.

\r\n *\r\n * @returns {String} result\r\n *\r\n */\r\n getKernelString() {\r\n if (this._kernelString !== null) return this._kernelString;\r\n\r\n let kernelThreadString = null;\r\n let {\r\n translatedSources\r\n } = this;\r\n if (translatedSources.length > 1) {\r\n translatedSources = translatedSources.filter(fn => {\r\n if (/^function/.test(fn)) return fn;\r\n kernelThreadString = fn;\r\n return false;\r\n })\r\n } else {\r\n kernelThreadString = translatedSources.shift();\r\n }\r\n return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() };\r\n ${ this.injectedNative || '' }\r\n const _this = this;\r\n ${ this._processConstants() }\r\n return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => {\r\n ${ this._processArguments() }\r\n ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) }\r\n ${ translatedSources.length > 0 ? translatedSources.join('\\n') : '' }\r\n };`;\r\n }\r\n\r\n /**\r\n * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.\r\n */\r\n toString() {\r\n return cpuKernelString(this);\r\n }\r\n\r\n /**\r\n * @desc Get the maximum loop size String.\r\n * @returns {String} result\r\n */\r\n _getLoopMaxString() {\r\n return (\r\n this.loopMaxIterations ?\r\n ` ${ parseInt(this.loopMaxIterations) };` :\r\n ' 1000;'\r\n );\r\n }\r\n\r\n _processConstants() {\r\n if (!this.constants) return '';\r\n\r\n const result = [];\r\n for (let p in this.constants) {\r\n const type = this.constantTypes[p];\r\n switch (type) {\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\\n`);\r\n break;\r\n case 'HTMLImageArray':\r\n result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\\n`);\r\n break;\r\n case 'Input':\r\n result.push(` const constants_${p} = this.constants.${p}.value;\\n`);\r\n break;\r\n default:\r\n result.push(` const constants_${p} = this.constants.${p};\\n`);\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n _processArguments() {\r\n const result = [];\r\n for (let i = 0; i < this.argumentTypes.length; i++) {\r\n const variableName = `user_${this.argumentNames[i]}`;\r\n switch (this.argumentTypes[i]) {\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\\n`);\r\n break;\r\n case 'HTMLImageArray':\r\n result.push(` ${variableName} = this._imageTo3DArray(${variableName});\\n`);\r\n break;\r\n case 'Input':\r\n result.push(` ${variableName} = ${variableName}.value;\\n`);\r\n break;\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'NumberTexture':\r\n case 'MemoryOptimizedNumberTexture':\r\n result.push(`\r\n if (${variableName}.toArray) {\r\n if (!_this.textureCache) {\r\n _this.textureCache = [];\r\n _this.arrayCache = [];\r\n }\r\n const textureIndex = _this.textureCache.indexOf(${variableName});\r\n if (textureIndex !== -1) {\r\n ${variableName} = _this.arrayCache[textureIndex];\r\n } else {\r\n _this.textureCache.push(${variableName});\r\n ${variableName} = ${variableName}.toArray();\r\n _this.arrayCache.push(${variableName});\r\n }\r\n }`);\r\n break;\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n _mediaTo2DArray(media) {\r\n const canvas = this.canvas;\r\n const width = media.width > 0 ? media.width : media.videoWidth;\r\n const height = media.height > 0 ? media.height : media.videoHeight;\r\n if (canvas.width < width) {\r\n canvas.width = width;\r\n }\r\n if (canvas.height < height) {\r\n canvas.height = height;\r\n }\r\n const ctx = this.context;\r\n ctx.drawImage(media, 0, 0, width, height);\r\n const pixelsData = ctx.getImageData(0, 0, width, height).data;\r\n const imageArray = new Array(height);\r\n let index = 0;\r\n for (let y = height - 1; y >= 0; y--) {\r\n const row = imageArray[y] = new Array(width);\r\n for (let x = 0; x < width; x++) {\r\n const pixel = new Float32Array(4);\r\n pixel[0] = pixelsData[index++] / 255; // r\r\n pixel[1] = pixelsData[index++] / 255; // g\r\n pixel[2] = pixelsData[index++] / 255; // b\r\n pixel[3] = pixelsData[index++] / 255; // a\r\n row[x] = pixel;\r\n }\r\n }\r\n return imageArray;\r\n }\r\n\r\n getPixels(flip) {\r\n const [width, height] = this.output;\r\n // cpu is not flipped by default\r\n return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0);\r\n }\r\n\r\n _imageTo3DArray(images) {\r\n const imagesArray = new Array(images.length);\r\n for (let i = 0; i < images.length; i++) {\r\n imagesArray[i] = this._mediaTo2DArray(images[i]);\r\n }\r\n return imagesArray;\r\n }\r\n\r\n _resultKernelBody(kernelString) {\r\n switch (this.output.length) {\r\n case 1:\r\n return this._resultKernel1DLoop(kernelString) + this._kernelOutput();\r\n case 2:\r\n return this._resultKernel2DLoop(kernelString) + this._kernelOutput();\r\n case 3:\r\n return this._resultKernel3DLoop(kernelString) + this._kernelOutput();\r\n default:\r\n throw new Error('unsupported size kernel');\r\n }\r\n }\r\n\r\n _graphicalKernelBody(kernelThreadString) {\r\n switch (this.output.length) {\r\n case 2:\r\n return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput();\r\n default:\r\n throw new Error('unsupported size kernel');\r\n }\r\n }\r\n\r\n _graphicalOutput() {\r\n return `\r\n this._imageData.data.set(this._colorData);\r\n this.context.putImageData(this._imageData, 0, 0);\r\n return;`\r\n }\r\n\r\n _getKernelResultTypeConstructorString() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return 'Float32Array';\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return 'Array';\r\n default:\r\n if (this.graphical) {\r\n return 'Float32Array';\r\n }\r\n throw new Error(`unhandled returnType ${ this.returnType }`);\r\n }\r\n }\r\n\r\n _resultKernel1DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const result = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n this.thread.y = 0;\r\n this.thread.z = 0;\r\n ${ kernelString }\r\n }`;\r\n }\r\n\r\n _resultKernel2DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n const result = new Array(outputY);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.z = 0;\r\n this.thread.y = y;\r\n const resultX = result[y] = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join('') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }`;\r\n }\r\n\r\n _graphicalKernel2DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.z = 0;\r\n this.thread.y = y;\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join('') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }`;\r\n }\r\n\r\n _resultKernel3DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n const outputZ = _this.output[2];\r\n const result = new Array(outputZ);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let z = 0; z < outputZ; z++) {\r\n this.thread.z = z;\r\n const resultY = result[z] = new Array(outputY);\r\n ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.y = y;\r\n const resultX = resultY[y] = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join(' ') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }\r\n }`;\r\n }\r\n\r\n _kernelOutput() {\r\n if (!this.subKernels) {\r\n return '\\n return result;';\r\n }\r\n return `\\n return {\r\n result: result,\r\n ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\\n ') }\r\n };`;\r\n }\r\n\r\n _mapSubKernels(fn) {\r\n return this.subKernels === null ? [''] :\r\n this.subKernels.map(fn);\r\n }\r\n\r\n\r\n\r\n destroy(removeCanvasReference) {\r\n if (removeCanvasReference) {\r\n delete this.canvas;\r\n }\r\n }\r\n\r\n static destroyContext(context) {}\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON();\r\n return json;\r\n }\r\n\r\n setOutput(output) {\r\n super.setOutput(output);\r\n const [width, height] = this.output;\r\n if (this.graphical) {\r\n this._imageData = this.context.createImageData(width, height);\r\n this._colorData = new Uint8ClampedArray(width * height * 4);\r\n }\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { Texture } from '../../../texture';\r\n\r\nexport class GLTextureFloat extends Texture {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n renderRawOutput() {\r\n const { context: gl } = this;\r\n const framebuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\r\n gl.framebufferTexture2D(\r\n gl.FRAMEBUFFER,\r\n gl.COLOR_ATTACHMENT0,\r\n gl.TEXTURE_2D,\r\n this.texture,\r\n 0\r\n );\r\n const result = new Float32Array(this.size[0] * this.size[1] * 4);\r\n gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n renderValues() {\r\n return this.renderRawOutput();\r\n }\r\n toArray() {\r\n return utils.erectFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erectArray3(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erectArray4(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureFloat2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n toArray() {\r\n return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureFloat3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n toArray() {\r\n return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { Texture } from '../../../texture';\r\n\r\nexport class GLTextureUnsigned extends Texture {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n renderRawOutput() {\r\n const { context: gl } = this;\r\n const framebuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\r\n gl.framebufferTexture2D(\r\n gl.FRAMEBUFFER,\r\n gl.COLOR_ATTACHMENT0,\r\n gl.TEXTURE_2D,\r\n this.texture,\r\n 0\r\n );\r\n const result = new Uint8Array(this.size[0] * this.size[1] * 4);\r\n gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result);\r\n return result;\r\n }\r\n renderValues() {\r\n return new Float32Array(this.renderRawOutput().buffer);\r\n }\r\n toArray() {\r\n return utils.erectPackedFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureUnsigned2D extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n toArray() {\r\n return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureUnsigned3D extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n toArray() {\r\n return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureGraphical extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return this.renderValues();\r\n }\r\n}\r\n","import { Kernel } from '../kernel';\r\nimport { utils } from '../../utils';\r\nimport { GLTextureArray2Float } from './texture/array-2-float';\r\nimport { GLTextureArray2Float2D } from './texture/array-2-float-2d';\r\nimport { GLTextureArray2Float3D } from './texture/array-2-float-3d';\r\nimport { GLTextureArray3Float } from './texture/array-3-float';\r\nimport { GLTextureArray3Float2D } from './texture/array-3-float-2d';\r\nimport { GLTextureArray3Float3D } from './texture/array-3-float-3d';\r\nimport { GLTextureArray4Float } from './texture/array-4-float';\r\nimport { GLTextureArray4Float2D } from './texture/array-4-float-2d';\r\nimport { GLTextureArray4Float3D } from './texture/array-4-float-3d';\r\nimport { GLTextureFloat } from './texture/float';\r\nimport { GLTextureFloat2D } from './texture/float-2d';\r\nimport { GLTextureFloat3D } from './texture/float-3d';\r\nimport { GLTextureMemoryOptimized } from './texture/memory-optimized';\r\nimport { GLTextureMemoryOptimized2D } from './texture/memory-optimized-2d';\r\nimport { GLTextureMemoryOptimized3D } from './texture/memory-optimized-3d';\r\nimport { GLTextureUnsigned } from './texture/unsigned';\r\nimport { GLTextureUnsigned2D } from './texture/unsigned-2d';\r\nimport { GLTextureUnsigned3D } from './texture/unsigned-3d';\r\nimport { GLTextureGraphical } from './texture/graphical';\r\n\r\n/**\r\n * @abstract\r\n * @extends Kernel\r\n */\r\nexport class GLKernel extends Kernel {\r\n static get mode() {\r\n return 'gpu';\r\n }\r\n\r\n static getIsFloatRead() {\r\n const kernelString = `function kernelFunction() {\r\n return 1;\r\n }`;\r\n const kernel = new this(kernelString, {\r\n context: this.testContext,\r\n canvas: this.testCanvas,\r\n validate: false,\r\n output: [1],\r\n precision: 'single',\r\n returnType: 'Number',\r\n tactic: 'speed',\r\n });\r\n kernel.build();\r\n kernel.run();\r\n const result = kernel.renderOutput();\r\n kernel.destroy(true);\r\n return result[0] === 1;\r\n }\r\n\r\n static getIsIntegerDivisionAccurate() {\r\n function kernelFunction(v1, v2) {\r\n return v1[this.thread.x] / v2[this.thread.x];\r\n }\r\n const kernel = new this(kernelFunction.toString(), {\r\n context: this.testContext,\r\n canvas: this.testCanvas,\r\n validate: false,\r\n output: [2],\r\n returnType: 'Number',\r\n precision: 'unsigned',\r\n tactic: 'speed',\r\n });\r\n const args = [\r\n [6, 6030401],\r\n [3, 3991]\r\n ];\r\n kernel.build.apply(kernel, args);\r\n kernel.run.apply(kernel, args);\r\n const result = kernel.renderOutput();\r\n kernel.destroy(true);\r\n // have we not got whole numbers for 6/3 or 6030401/3991\r\n // add more here if others see this problem\r\n return result[0] === 2 && result[1] === 1511;\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static get testCanvas() {\r\n throw new Error(`\"testCanvas\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static get testContext() {\r\n throw new Error(`\"testContext\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {IKernelFeatures}\r\n */\r\n static get features() {\r\n throw new Error(`\"features\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static setupFeatureChecks() {\r\n throw new Error(`\"setupFeatureChecks\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @desc Fix division by factor of 3 FP accuracy bug\r\n * @param {Boolean} fix - should fix\r\n */\r\n setFixIntegerDivisionAccuracy(fix) {\r\n this.fixIntegerDivisionAccuracy = fix;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle output mode\r\n * @param {String} flag - 'single' or 'unsigned'\r\n */\r\n setPrecision(flag) {\r\n this.precision = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle texture output mode\r\n * @param {Boolean} flag - true to enable floatTextures\r\n * @deprecated\r\n */\r\n setFloatTextures(flag) {\r\n utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory');\r\n this.floatTextures = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * A highly readable very forgiving micro-parser for a glsl function that gets argument types\r\n * @param {String} source\r\n * @returns {{argumentTypes: String[], argumentNames: String[]}}\r\n */\r\n static nativeFunctionArguments(source) {\r\n const argumentTypes = [];\r\n const argumentNames = [];\r\n const states = [];\r\n const isStartingVariableName = /^[a-zA-Z_]/;\r\n const isVariableChar = /[a-zA-Z_0-9]/;\r\n let i = 0;\r\n let argumentName = null;\r\n let argumentType = null;\r\n while (i < source.length) {\r\n const char = source[i];\r\n const nextChar = source[i + 1];\r\n const state = states.length > 0 ? states[states.length - 1] : null;\r\n\r\n // begin MULTI_LINE_COMMENT handling\r\n if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') {\r\n states.push('MULTI_LINE_COMMENT');\r\n i += 2;\r\n continue;\r\n } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') {\r\n states.pop();\r\n i += 2;\r\n continue;\r\n }\r\n // end MULTI_LINE_COMMENT handling\r\n\r\n // begin COMMENT handling\r\n else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') {\r\n states.push('COMMENT');\r\n i += 2;\r\n continue;\r\n } else if (state === 'COMMENT' && char === '\\n') {\r\n states.pop();\r\n i++;\r\n continue;\r\n }\r\n // end COMMENT handling\r\n\r\n // being FUNCTION_ARGUMENTS handling\r\n else if (state === null && char === '(') {\r\n states.push('FUNCTION_ARGUMENTS');\r\n i++;\r\n continue;\r\n } else if (state === 'FUNCTION_ARGUMENTS') {\r\n if (char === ')') {\r\n states.pop();\r\n break;\r\n }\r\n if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'float';\r\n argumentName = '';\r\n i += 6;\r\n continue;\r\n } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'int';\r\n argumentName = '';\r\n i += 4;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec2';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec3';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec4';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n }\r\n }\r\n // end FUNCTION_ARGUMENTS handling\r\n\r\n // begin DECLARE_VARIABLE handling\r\n else if (state === 'DECLARE_VARIABLE') {\r\n if (argumentName === '') {\r\n if (char === ' ') {\r\n i++;\r\n continue;\r\n }\r\n if (!isStartingVariableName.test(char)) {\r\n throw new Error('variable name is not expected string');\r\n }\r\n }\r\n argumentName += char;\r\n if (!isVariableChar.test(nextChar)) {\r\n states.pop();\r\n argumentNames.push(argumentName);\r\n argumentTypes.push(typeMap[argumentType]);\r\n }\r\n }\r\n // end DECLARE_VARIABLE handling\r\n\r\n // Progress to next character\r\n i++;\r\n }\r\n if (states.length > 0) {\r\n throw new Error('GLSL function was not parsable');\r\n }\r\n return {\r\n argumentNames,\r\n argumentTypes,\r\n };\r\n }\r\n\r\n static nativeFunctionReturnType(source) {\r\n return typeMap[source.match(/int|float|vec[2-4]/)[0]];\r\n }\r\n\r\n static combineKernels(combinedKernel, lastKernel) {\r\n combinedKernel.apply(null, arguments);\r\n const {\r\n texSize,\r\n context,\r\n threadDim\r\n } = lastKernel.texSize;\r\n let result;\r\n if (lastKernel.precision === 'single') {\r\n const w = texSize[0];\r\n const h = Math.ceil(texSize[1] / 4);\r\n result = new Float32Array(w * h * 4 * 4);\r\n context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result);\r\n } else {\r\n const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);\r\n context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes);\r\n result = new Float32Array(bytes.buffer);\r\n }\r\n\r\n result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);\r\n\r\n if (lastKernel.output.length === 1) {\r\n return result;\r\n } else if (lastKernel.output.length === 2) {\r\n return utils.splitArray(result, lastKernel.output[0]);\r\n } else if (lastKernel.output.length === 3) {\r\n const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);\r\n return cube.map(function(x) {\r\n return utils.splitArray(x, lastKernel.output[0]);\r\n });\r\n }\r\n }\r\n\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.transferValues = null;\r\n this.formatValues = null;\r\n this.TextureConstructor = null;\r\n this.renderOutput = null;\r\n this.renderRawOutput = null;\r\n this.texSize = null;\r\n this.translatedSource = null;\r\n this.renderStrategy = null;\r\n this.compiledFragmentShader = null;\r\n this.compiledVertexShader = null;\r\n }\r\n\r\n checkTextureSize() {\r\n const { features } = this.constructor;\r\n if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) {\r\n throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`);\r\n }\r\n }\r\n\r\n translateSource() {\r\n throw new Error(`\"translateSource\" not defined on ${this.constructor.name}`);\r\n }\r\n\r\n /**\r\n * Picks a render strategy for the now finally parsed kernel\r\n * @param args\r\n * @return {null|KernelOutput}\r\n */\r\n pickRenderStrategy(args) {\r\n if (this.graphical) {\r\n this.renderRawOutput = this.readPackedPixelsToUint8Array;\r\n this.transferValues = (pixels) => pixels;\r\n this.TextureConstructor = GLTextureGraphical;\r\n return null;\r\n }\r\n if (this.precision === 'unsigned') {\r\n this.renderRawOutput = this.readPackedPixelsToUint8Array;\r\n this.transferValues = this.readPackedPixelsToFloat32Array;\r\n if (this.pipeline) {\r\n this.renderOutput = this.renderTexture;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToTextures;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned3D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned2D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureUnsigned;\r\n this.renderStrategy = renderStrategy.PackedPixelToFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return this.requestFallback(args);\r\n }\r\n } else {\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToArrays;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n this.renderOutput = this.renderValues;\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned3D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo3DFloat;\r\n this.formatValues = utils.erect3DPackedFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned2D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo2DFloat;\r\n this.formatValues = utils.erect2DPackedFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureUnsigned;\r\n this.renderStrategy = renderStrategy.PackedPixelToFloat;\r\n this.formatValues = utils.erectPackedFloat;\r\n return null;\r\n }\r\n\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return this.requestFallback(args);\r\n }\r\n }\r\n } else if (this.precision === 'single') {\r\n this.renderRawOutput = this.readFloatPixelsToFloat32Array;\r\n this.transferValues = this.readFloatPixelsToFloat32Array;\r\n if (this.pipeline) {\r\n this.renderStrategy = renderStrategy.FloatTexture;\r\n this.renderOutput = this.renderTexture;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToTextures;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureMemoryOptimized;\r\n return null;\r\n }\r\n } else {\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureFloat3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureFloat2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureFloat;\r\n return null;\r\n }\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n return null;\r\n }\r\n }\r\n }\r\n this.renderOutput = this.renderValues;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToArrays;\r\n }\r\n if (this.optimizeFloatMemory) {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized3D;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat;\r\n this.formatValues = utils.erectMemoryOptimized3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized2D;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat;\r\n this.formatValues = utils.erectMemoryOptimized2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureMemoryOptimized;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat;\r\n this.formatValues = utils.erectMemoryOptimizedFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray2;\r\n this.formatValues = utils.erect3DArray2;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray2;\r\n this.formatValues = utils.erect2DArray2;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray2;\r\n this.formatValues = utils.erectArray2;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray3;\r\n this.formatValues = utils.erect3DArray3;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray3;\r\n this.formatValues = utils.erect2DArray3;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray3;\r\n this.formatValues = utils.erectArray3;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray4;\r\n this.formatValues = utils.erect3DArray4;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray4;\r\n this.formatValues = utils.erect2DArray4;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray4;\r\n this.formatValues = utils.erectArray4;\r\n return null;\r\n }\r\n }\r\n } else {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureFloat3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DFloat;\r\n this.formatValues = utils.erect3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureFloat2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DFloat;\r\n this.formatValues = utils.erect2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureFloat;\r\n this.renderStrategy = renderStrategy.FloatPixelToFloat;\r\n this.formatValues = utils.erectFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray2;\r\n this.formatValues = utils.erect3DArray2;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray2;\r\n this.formatValues = utils.erect2DArray2;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray2;\r\n this.formatValues = utils.erectArray2;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray3;\r\n this.formatValues = utils.erect3DArray3;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray3;\r\n this.formatValues = utils.erect2DArray3;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray3;\r\n this.formatValues = utils.erectArray3;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray4;\r\n this.formatValues = utils.erect3DArray4;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray4;\r\n this.formatValues = utils.erect2DArray4;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray4;\r\n this.formatValues = utils.erectArray4;\r\n return null;\r\n }\r\n }\r\n }\r\n } else {\r\n throw new Error(`unhandled precision of \"${this.precision}\"`);\r\n }\r\n\r\n throw new Error(`unhandled return type \"${this.returnType}\"`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @returns String\r\n */\r\n getKernelString() {\r\n throw new Error(`abstract method call`);\r\n }\r\n\r\n getMainResultTexture() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Integer':\r\n case 'Number':\r\n return this.getMainResultNumberTexture();\r\n case 'Array(2)':\r\n return this.getMainResultArray2Texture();\r\n case 'Array(3)':\r\n return this.getMainResultArray3Texture();\r\n case 'Array(4)':\r\n return this.getMainResultArray4Texture();\r\n default:\r\n throw new Error(`unhandled returnType type ${ this.returnType }`);\r\n }\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelNumberTexture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelNumberTexture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray2Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray2Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray3Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray3Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray4Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray4Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultGraphical() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultMemoryOptimizedFloats() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultPackedPixels() {\r\n throw new Error(`abstract method call`);\r\n }\r\n\r\n getMainResultString() {\r\n if (this.graphical) {\r\n return this.getMainResultGraphical();\r\n } else if (this.precision === 'single') {\r\n if (this.optimizeFloatMemory) {\r\n return this.getMainResultMemoryOptimizedFloats();\r\n }\r\n return this.getMainResultTexture();\r\n } else {\r\n return this.getMainResultPackedPixels();\r\n }\r\n }\r\n\r\n getMainResultNumberTexture() {\r\n return utils.linesToString(this.getMainResultKernelNumberTexture()) +\r\n utils.linesToString(this.getMainResultSubKernelNumberTexture());\r\n }\r\n\r\n getMainResultArray2Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray2Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray2Texture());\r\n }\r\n\r\n getMainResultArray3Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray3Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray3Texture());\r\n }\r\n\r\n getMainResultArray4Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray4Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray4Texture());\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getFloatTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp float;\\n';\r\n case 'performance':\r\n return 'precision highp float;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump float;\\n';\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getIntTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp int;\\n';\r\n case 'performance':\r\n return 'precision highp int;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump int;\\n';\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getSampler2DTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp sampler2D;\\n';\r\n case 'performance':\r\n return 'precision highp sampler2D;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump sampler2D;\\n';\r\n }\r\n }\r\n\r\n getSampler2DArrayTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp sampler2DArray;\\n';\r\n case 'performance':\r\n return 'precision highp sampler2DArray;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump sampler2DArray;\\n';\r\n }\r\n }\r\n\r\n renderTexture() {\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n readPackedPixelsToUint8Array() {\r\n if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be \"unsigned\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const result = new Uint8Array(texSize[0] * texSize[1] * 4);\r\n gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result);\r\n return result;\r\n }\r\n\r\n readPackedPixelsToFloat32Array() {\r\n return new Float32Array(this.readPackedPixelsToUint8Array().buffer);\r\n }\r\n\r\n readFloatPixelsToFloat32Array() {\r\n if (this.precision !== 'single') throw new Error('Requires this.precision to be \"single\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const w = texSize[0];\r\n const h = texSize[1];\r\n const result = new Float32Array(w * h * 4);\r\n gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n\r\n readMemoryOptimizedFloatPixelsToFloat32Array() {\r\n if (this.precision !== 'single') throw new Error('Requires this.precision to be \"single\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const w = texSize[0];\r\n const h = texSize[1];\r\n const result = new Float32Array(w * h * 4);\r\n gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Boolean} [flip]\r\n * @return {Uint8Array}\r\n */\r\n getPixels(flip) {\r\n const {\r\n context: gl,\r\n output\r\n } = this;\r\n const [width, height] = output;\r\n const pixels = new Uint8Array(width * height * 4);\r\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\r\n // flipped by default, so invert\r\n return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer);\r\n }\r\n\r\n renderKernelsToArrays() {\r\n const result = {\r\n result: this.renderOutput(),\r\n };\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n result[this.subKernels[i].property] = new this.TextureConstructor({\r\n texture: this.subKernelOutputTextures[i],\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n }).toArray();\r\n }\r\n return result;\r\n }\r\n\r\n renderKernelsToTextures() {\r\n const result = {\r\n result: this.renderOutput(),\r\n };\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n result[this.subKernels[i].property] = new this.TextureConstructor({\r\n texture: this.subKernelOutputTextures[i],\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n return result;\r\n }\r\n\r\n setOutput(output) {\r\n super.setOutput(output);\r\n if (this.program) {\r\n this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1];\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n const { context: gl } = this;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n this.updateMaxTexSize();\r\n this.framebuffer.width = this.texSize[0];\r\n this.framebuffer.height = this.texSize[1];\r\n this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n this.canvas.width = this.maxTexSize[0];\r\n this.canvas.height = this.maxTexSize[1];\r\n this._setupOutputTexture();\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n this._setupSubOutputTextures();\r\n }\r\n }\r\n return this;\r\n }\r\n renderValues() {\r\n return this.formatValues(\r\n this.transferValues(),\r\n this.output[0],\r\n this.output[1],\r\n this.output[2]\r\n );\r\n }\r\n}\r\n\r\nexport const renderStrategy = Object.freeze({\r\n PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'),\r\n PackedPixelToFloat: Symbol('PackedPixelToFloat'),\r\n PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'),\r\n PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'),\r\n PackedTexture: Symbol('PackedTexture'),\r\n FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'),\r\n FloatPixelToFloat: Symbol('FloatPixelToFloat'),\r\n FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'),\r\n FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'),\r\n FloatPixelToArray2: Symbol('FloatPixelToArray2'),\r\n FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'),\r\n FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'),\r\n FloatPixelToArray3: Symbol('FloatPixelToArray3'),\r\n FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'),\r\n FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'),\r\n FloatPixelToArray4: Symbol('FloatPixelToArray4'),\r\n FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'),\r\n FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'),\r\n FloatTexture: Symbol('FloatTexture'),\r\n MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'),\r\n MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'),\r\n MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'),\r\n});\r\n\r\nconst typeMap = {\r\n int: 'Integer',\r\n float: 'Number',\r\n vec2: 'Array(2)',\r\n vec3: 'Array(3)',\r\n vec4: 'Array(4)',\r\n};\r\n","import { utils } from '../../utils';\r\nimport { FunctionNode } from '../function-node';\r\n// Closure capture for the ast function, prevent collision with existing AST functions\r\n// The prefixes to use\r\nconst jsMathPrefix = 'Math.';\r\nconst localPrefix = 'this.';\r\n\r\n/**\r\n * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code\r\n * @extends FunctionNode\r\n * @returns the converted WebGL function string\r\n */\r\nexport class WebGLFunctionNode extends FunctionNode {\r\n constructor(source, settings) {\r\n super(source, settings);\r\n if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) {\r\n this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy;\r\n }\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunction(ast, retArr) {\r\n // Setup function return type and name\r\n if (this.isRootKernel) {\r\n retArr.push('void');\r\n } else {\r\n // looking up return type, this is a little expensive, and can be avoided if returnType is set\r\n let lastReturn = null;\r\n if (!this.returnType) {\r\n const lastReturn = this.findLastReturn();\r\n if (lastReturn) {\r\n this.returnType = this.getType(ast.body);\r\n if (this.returnType === 'LiteralInteger') {\r\n this.returnType = 'Number';\r\n }\r\n }\r\n }\r\n\r\n const { returnType } = this;\r\n if (!returnType) {\r\n retArr.push('void');\r\n } else {\r\n const type = typeMap[returnType];\r\n if (!type) {\r\n throw new Error(`unknown type ${returnType}`);\r\n }\r\n retArr.push(type);\r\n }\r\n }\r\n retArr.push(' ');\r\n retArr.push(this.name);\r\n retArr.push('(');\r\n\r\n if (!this.isRootKernel) {\r\n // Arguments handling\r\n for (let i = 0; i < this.argumentNames.length; ++i) {\r\n const argumentName = this.argumentNames[i];\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)];\r\n // The type is too loose ended, here we descide to solidify a type, lets go with float\r\n if (!argumentType) {\r\n throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast);\r\n }\r\n if (argumentType === 'LiteralInteger') {\r\n this.argumentTypes[i] = argumentType = 'Number';\r\n }\r\n const type = typeMap[argumentType];\r\n if (!type) {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n retArr.push(type);\r\n retArr.push(' ');\r\n retArr.push('user_');\r\n retArr.push(argumentName);\r\n }\r\n }\r\n\r\n // Function opening\r\n retArr.push(') {\\n');\r\n\r\n // Body statement iteration\r\n for (let i = 0; i < ast.body.body.length; ++i) {\r\n this.astGeneric(ast.body.body[i], retArr);\r\n retArr.push('\\n');\r\n }\r\n\r\n // Function closing\r\n retArr.push('}\\n');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to *return* statement\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astReturnStatement(ast, retArr) {\r\n if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast);\r\n this.pushState('skip-literal-correction');\r\n const type = this.getType(ast.argument);\r\n this.popState('skip-literal-correction');\r\n\r\n const result = [];\r\n\r\n if (!this.returnType) {\r\n if (type === 'LiteralInteger' || type === 'Integer') {\r\n this.returnType = 'Number';\r\n } else {\r\n this.returnType = type;\r\n }\r\n }\r\n\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Float':\r\n switch (type) {\r\n case 'Integer':\r\n result.push('float(');\r\n this.astGeneric(ast.argument, result);\r\n result.push(')');\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.argument, result);\r\n\r\n // Running astGeneric forces the LiteralInteger to pick a type, and here, if we are returning a float, yet\r\n // the LiteralInteger has picked to be an integer because of constraints on it we cast it to float.\r\n if (this.getType(ast) === 'Integer') {\r\n result.unshift('float(');\r\n result.push(')');\r\n }\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, result);\r\n }\r\n break;\r\n case 'Integer':\r\n switch (type) {\r\n case 'Float':\r\n case 'Number':\r\n this.castValueToInteger(ast.argument, result);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.argument, result);\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, result);\r\n }\r\n break;\r\n case 'Array(4)':\r\n case 'Array(3)':\r\n case 'Array(2)':\r\n case 'Input':\r\n this.astGeneric(ast.argument, result);\r\n break;\r\n default:\r\n throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast);\r\n }\r\n\r\n if (this.isRootKernel) {\r\n retArr.push(`kernelResult = ${ result.join('') };`);\r\n retArr.push('return;');\r\n } else if (this.isSubKernel) {\r\n retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`);\r\n retArr.push(`return subKernelResult_${ this.name };`);\r\n } else {\r\n retArr.push(`return ${ result.join('') };`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *literal value*\r\n *\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n *\r\n * @returns {Array} the append retArr\r\n */\r\n astLiteral(ast, retArr) {\r\n // Reject non numeric literals\r\n if (isNaN(ast.value)) {\r\n throw this.astErrorOutput(\r\n 'Non-numeric literal not supported : ' + ast.value,\r\n ast\r\n );\r\n }\r\n\r\n const key = `${ast.start},${ast.end}`;\r\n if (Number.isInteger(ast.value)) {\r\n if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.literalTypes[key] = 'Integer';\r\n retArr.push(`${ast.value}`);\r\n } else if (this.isState('casting-to-float') || this.isState('building-float')) {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}.0`);\r\n } else {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}.0`);\r\n }\r\n } else if (this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.literalTypes[key] = 'Integer';\r\n retArr.push(Math.round(ast.value));\r\n } else {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *binary* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBinaryExpression(ast, retArr) {\r\n if (this.checkAndUpconvertOperator(ast, retArr)) {\r\n return retArr;\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy && ast.operator === '/') {\r\n retArr.push('div_with_int_check(');\r\n this.pushState('building-float');\r\n switch (this.getType(ast.left)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(', ');\r\n switch (this.getType(ast.right)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n this.popState('building-float');\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n retArr.push('(');\r\n const leftType = this.getType(ast.left) || 'Number';\r\n const rightType = this.getType(ast.right) || 'Number';\r\n if (!leftType || !rightType) {\r\n throw this.astErrorOutput(`Unhandled binary expression`, ast);\r\n }\r\n const key = leftType + ' & ' + rightType;\r\n switch (key) {\r\n case 'Integer & Integer':\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n case 'Number & Float':\r\n case 'Float & Number':\r\n case 'Float & Float':\r\n case 'Number & Number':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n case 'LiteralInteger & LiteralInteger':\r\n if (this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.castLiteralToFloat(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n }\r\n break;\r\n\r\n case 'Integer & Float':\r\n case 'Integer & Number':\r\n if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') {\r\n // if right value is actually a float, don't loose that information, cast left to right rather than the usual right to left\r\n if (!Number.isInteger(ast.right.value)) {\r\n this.pushState('building-float');\r\n this.castValueToFloat(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n }\r\n }\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.pushState('casting-to-integer');\r\n if (ast.right.type === 'Literal') {\r\n const literalResult = [];\r\n this.astGeneric(ast.right, literalResult);\r\n const literalType = this.getType(ast.right);\r\n if (literalType === 'Integer') {\r\n retArr.push(literalResult.join(''));\r\n } else {\r\n throw this.astErrorOutput(`Unhandled binary expression with literal`, ast);\r\n }\r\n } else {\r\n retArr.push('int(');\r\n this.astGeneric(ast.right, retArr);\r\n retArr.push(')');\r\n }\r\n this.popState('casting-to-integer');\r\n this.popState('building-integer');\r\n break;\r\n case 'Integer & LiteralInteger':\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n\r\n case 'Number & Integer':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n case 'Float & LiteralInteger':\r\n case 'Number & LiteralInteger':\r\n if (this.isState('in-for-loop-test')) {\r\n this.pushState('building-integer');\r\n retArr.push('int(');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(')');\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n }\r\n break;\r\n case 'LiteralInteger & Float':\r\n case 'LiteralInteger & Number':\r\n if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) {\r\n this.pushState('building-integer');\r\n this.castLiteralToInteger(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.pushState('casting-to-float');\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('casting-to-float');\r\n this.popState('building-float');\r\n }\r\n break;\r\n case 'LiteralInteger & Integer':\r\n this.pushState('building-integer');\r\n this.castLiteralToInteger(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n\r\n case 'Boolean & Boolean':\r\n this.pushState('building-boolean');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-boolean');\r\n break;\r\n\r\n case 'Float & Integer':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n\r\n default:\r\n throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast);\r\n }\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertOperator(ast, retArr) {\r\n const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr);\r\n if (bitwiseResult) {\r\n return bitwiseResult;\r\n }\r\n const upconvertableOperators = {\r\n '%': 'mod',\r\n '**': 'pow',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n switch (this.getType(ast.left)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(',');\r\n switch (this.getType(ast.right)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseOperators(ast, retArr) {\r\n const upconvertableOperators = {\r\n '&': 'bitwiseAnd',\r\n '|': 'bitwiseOr',\r\n '^': 'bitwiseXOR',\r\n '<<': 'bitwiseZeroFillLeftShift',\r\n '>>': 'bitwiseSignedRightShift',\r\n '>>>': 'bitwiseZeroFillRightShift',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n const leftType = this.getType(ast.left);\r\n switch (leftType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(',');\r\n const rightType = this.getType(ast.right);\r\n switch (rightType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseUnary(ast, retArr) {\r\n const upconvertableOperators = {\r\n '~': 'bitwiseNot',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n switch (this.getType(ast.argument)) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.argument, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.argument, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castLiteralToInteger(ast, retArr) {\r\n this.pushState('casting-to-integer');\r\n this.astGeneric(ast, retArr);\r\n this.popState('casting-to-integer');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castLiteralToFloat(ast, retArr) {\r\n this.pushState('casting-to-float');\r\n this.astGeneric(ast, retArr);\r\n this.popState('casting-to-float');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castValueToInteger(ast, retArr) {\r\n this.pushState('casting-to-integer');\r\n retArr.push('int(');\r\n this.astGeneric(ast, retArr);\r\n retArr.push(')');\r\n this.popState('casting-to-integer');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castValueToFloat(ast, retArr) {\r\n this.pushState('casting-to-float');\r\n retArr.push('float(');\r\n this.astGeneric(ast, retArr);\r\n retArr.push(')');\r\n this.popState('casting-to-float');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode);\r\n }\r\n\r\n const type = this.getType(idtNode);\r\n\r\n if (idtNode.name === 'Infinity') {\r\n // https://stackoverflow.com/a/47543127/1324039\r\n retArr.push('3.402823466e+38');\r\n } else if (type === 'Boolean') {\r\n if (this.argumentNames.indexOf(idtNode.name) > -1) {\r\n retArr.push(`bool(user_${idtNode.name})`);\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *for-loop* expression\r\n * @param {Object} forNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astForStatement(forNode, retArr) {\r\n if (forNode.type !== 'ForStatement') {\r\n throw this.astErrorOutput('Invalid for statement', forNode);\r\n }\r\n\r\n const initArr = [];\r\n const testArr = [];\r\n const updateArr = [];\r\n const bodyArr = [];\r\n let isSafe = null;\r\n\r\n if (forNode.init) {\r\n this.pushState('in-for-loop-init');\r\n this.astGeneric(forNode.init, initArr);\r\n const { declarations } = forNode.init;\r\n for (let i = 0; i < declarations.length; i++) {\r\n if (declarations[i].init && declarations[i].init.type !== 'Literal') {\r\n isSafe = false;\r\n }\r\n }\r\n if (isSafe) {\r\n for (let i = 0; i < initArr.length; i++) {\r\n if (initArr[i].includes && initArr[i].includes(',')) {\r\n isSafe = false;\r\n }\r\n }\r\n }\r\n this.popState('in-for-loop-init');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.test) {\r\n this.pushState('in-for-loop-test');\r\n this.astGeneric(forNode.test, testArr);\r\n this.popState('in-for-loop-test');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.update) {\r\n this.astGeneric(forNode.update, updateArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.body) {\r\n this.pushState('loop-body');\r\n this.astGeneric(forNode.body, bodyArr);\r\n this.popState('loop-body');\r\n }\r\n\r\n // have all parts, now make them safe\r\n if (isSafe === null) {\r\n isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);\r\n }\r\n\r\n if (isSafe) {\r\n retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\\n`);\r\n retArr.push(bodyArr.join(''));\r\n retArr.push('}\\n');\r\n } else {\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n if (initArr.length > 0) {\r\n retArr.push(initArr.join(''), ';\\n');\r\n }\r\n retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) {\r\n retArr.push(`if (!${testArr.join('')}) break;\\n`);\r\n }\r\n retArr.push(bodyArr.join(''));\r\n retArr.push(`\\n${updateArr.join('')};`);\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *while* loop\r\n * @param {Object} whileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astWhileStatement(whileNode, retArr) {\r\n if (whileNode.type !== 'WhileStatement') {\r\n throw this.astErrorOutput('Invalid while statement', whileNode);\r\n }\r\n\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n retArr.push(`for (int ${iVariableName}=0;${iVariableName} i + 1) {\r\n movingDefaultToEnd = true;\r\n this.astGeneric(cases[i].consequent, defaultResult);\r\n continue;\r\n } else {\r\n retArr.push(' else {\\n');\r\n }\r\n } else {\r\n // all others\r\n if (i === 0 || !pastFirstIf) {\r\n pastFirstIf = true;\r\n retArr.push(`if (${varName} == `);\r\n } else {\r\n if (fallingThrough) {\r\n retArr.push(`${varName} == `);\r\n fallingThrough = false;\r\n } else {\r\n retArr.push(` else if (${varName} == `);\r\n }\r\n }\r\n if (type === 'Integer') {\r\n const testType = this.getType(cases[i].test);\r\n switch (testType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(cases[i].test, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(cases[i].test, retArr);\r\n break;\r\n }\r\n } else if (type === 'Float') {\r\n const testType = this.getType(cases[i].test);\r\n switch (testType) {\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(cases[i].test, retArr);\r\n break;\r\n case 'Integer':\r\n this.castValueToFloat(cases[i].test, retArr);\r\n break;\r\n }\r\n } else {\r\n throw new Error('unhanlded');\r\n }\r\n if (!cases[i].consequent || cases[i].consequent.length === 0) {\r\n fallingThrough = true;\r\n retArr.push(' || ');\r\n continue;\r\n }\r\n retArr.push(`) {\\n`);\r\n }\r\n this.astGeneric(cases[i].consequent, retArr);\r\n retArr.push('\\n}');\r\n }\r\n if (movingDefaultToEnd) {\r\n retArr.push(' else {');\r\n retArr.push(defaultResult.join(''));\r\n retArr.push('}');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *This* expression\r\n * @param {Object} tNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astThisExpression(tNode, retArr) {\r\n retArr.push('this');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Member* Expression\r\n * @param {Object} mNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astMemberExpression(mNode, retArr) {\r\n const {\r\n property,\r\n name,\r\n signature,\r\n origin,\r\n type,\r\n xProperty,\r\n yProperty,\r\n zProperty\r\n } = this.getMemberExpressionDetails(mNode);\r\n switch (signature) {\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n if (name !== 'x' && name !== 'y' && name !== 'z') {\r\n throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode);\r\n }\r\n retArr.push(`threadId.${name}`);\r\n return retArr;\r\n case 'this.output.value':\r\n if (this.dynamicOutput) {\r\n switch (name) {\r\n case 'x':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.x)');\r\n } else {\r\n retArr.push('uOutputDim.x');\r\n }\r\n break;\r\n case 'y':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.y)');\r\n } else {\r\n retArr.push('uOutputDim.y');\r\n }\r\n break;\r\n case 'z':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.z)');\r\n } else {\r\n retArr.push('uOutputDim.z');\r\n }\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n } else {\r\n switch (name) {\r\n case 'x':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[0]);\r\n } else {\r\n retArr.push(this.output[0], '.0');\r\n }\r\n break;\r\n case 'y':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[1]);\r\n } else {\r\n retArr.push(this.output[1], '.0');\r\n }\r\n break;\r\n case 'z':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[2]);\r\n } else {\r\n retArr.push(this.output[2], '.0');\r\n }\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n }\r\n return retArr;\r\n case 'value':\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n case 'value[]':\r\n case 'value[][]':\r\n case 'value[][][]':\r\n case 'value[][][][]':\r\n case 'value.value':\r\n if (origin === 'Math') {\r\n retArr.push(Math[name]);\r\n return retArr;\r\n }\r\n switch (property) {\r\n case 'r':\r\n retArr.push(`user_${ name }.r`);\r\n return retArr;\r\n case 'g':\r\n retArr.push(`user_${ name }.g`);\r\n return retArr;\r\n case 'b':\r\n retArr.push(`user_${ name }.b`);\r\n return retArr;\r\n case 'a':\r\n retArr.push(`user_${ name }.a`);\r\n return retArr;\r\n }\r\n break;\r\n case 'this.constants.value':\r\n if (typeof xProperty === 'undefined') {\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n retArr.push(`constants_${ name }`);\r\n return retArr;\r\n }\r\n }\r\n case 'this.constants.value[]':\r\n case 'this.constants.value[][]':\r\n case 'this.constants.value[][][]':\r\n case 'this.constants.value[][][][]':\r\n break;\r\n case 'fn()[]':\r\n this.astCallExpression(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(property));\r\n retArr.push(']');\r\n return retArr;\r\n case '[][]':\r\n this.astArrayExpression(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(property));\r\n retArr.push(']');\r\n return retArr;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n\r\n if (mNode.computed === false) {\r\n // handle simple types\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n retArr.push(`${origin}_${name}`);\r\n return retArr;\r\n }\r\n }\r\n\r\n // handle more complex types\r\n // argument may have come from a parent\r\n const markupName = `${origin}_${name}`;\r\n\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n // Get from local vec4\r\n this.astGeneric(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(xProperty));\r\n retArr.push(']');\r\n break;\r\n case 'HTMLImageArray':\r\n retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(1)':\r\n retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(2)':\r\n case 'Array2D(2)':\r\n case 'Array3D(2)':\r\n retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(2)':\r\n retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(3)':\r\n case 'Array2D(3)':\r\n case 'Array3D(3)':\r\n retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(3)':\r\n retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(4)':\r\n case 'Array2D(4)':\r\n case 'Array3D(4)':\r\n retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(4)':\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'NumberTexture':\r\n case 'Array':\r\n case 'Array2D':\r\n case 'Array3D':\r\n case 'Array4D':\r\n case 'Input':\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.precision === 'single') {\r\n // bitRatio is always 4 here, javascript doesn't yet have 8 or 16 bit support\r\n // TODO: make 8 or 16 bit work anyway!\r\n retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n } else {\r\n const bitRatio = (origin === 'user' ?\r\n this.lookupFunctionArgumentBitRatio(this.name, name) :\r\n this.constantBitRatios[name]\r\n );\r\n switch (bitRatio) {\r\n case 1:\r\n retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n case 2:\r\n retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n case 4:\r\n case 0:\r\n retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n default:\r\n throw new Error(`unhandled bit ratio of ${bitRatio}`);\r\n }\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n }\r\n break;\r\n case 'MemoryOptimizedNumberTexture':\r\n retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n default:\r\n throw new Error(`unhandled member expression \"${ type }\"`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *call* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astCallExpression(ast, retArr) {\r\n if (!ast.callee) {\r\n throw this.astErrorOutput('Unknown CallExpression', ast);\r\n }\r\n\r\n let functionName = null;\r\n const isMathFunction = this.isAstMathFunction(ast);\r\n\r\n // Its a math operator or this.something(), remove the prefix\r\n if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) {\r\n functionName = ast.callee.property.name;\r\n }\r\n // Issue #212, BABEL!\r\n else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) {\r\n functionName = ast.callee.expressions[1].property.name;\r\n } else {\r\n functionName = ast.callee.name;\r\n }\r\n\r\n if (!functionName) {\r\n throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast);\r\n }\r\n\r\n // if this if grows to more than one, lets use a switch\r\n if (functionName === 'atan2') {\r\n functionName = 'atan';\r\n }\r\n\r\n // Register the function into the called registry\r\n if (this.calledFunctions.indexOf(functionName) < 0) {\r\n this.calledFunctions.push(functionName);\r\n }\r\n\r\n if (functionName === 'random' && this.plugins && this.plugins.length > 0) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) {\r\n retArr.push(plugin.functionReplace);\r\n return retArr;\r\n }\r\n }\r\n }\r\n\r\n // track the function was called\r\n if (this.onFunctionCall) {\r\n this.onFunctionCall(this.name, functionName, ast.arguments);\r\n }\r\n\r\n // Call the function\r\n retArr.push(functionName);\r\n\r\n // Open arguments space\r\n retArr.push('(');\r\n\r\n // Add the arguments\r\n if (isMathFunction) {\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n const argumentType = this.getType(argument);\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n\r\n switch (argumentType) {\r\n case 'Integer':\r\n this.castValueToFloat(argument, retArr);\r\n break;\r\n default:\r\n this.astGeneric(argument, retArr);\r\n break;\r\n }\r\n }\r\n } else {\r\n const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n let targetType = targetTypes[i];\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const argumentType = this.getType(argument);\r\n if (!targetType) {\r\n this.triggerImplyArgumentType(functionName, i, argumentType, this);\r\n targetType = argumentType;\r\n }\r\n switch (argumentType) {\r\n case 'Number':\r\n case 'Float':\r\n if (targetType === 'Integer') {\r\n retArr.push('int(');\r\n this.astGeneric(argument, retArr);\r\n retArr.push(')');\r\n continue;\r\n } else if (targetType === 'Number' || targetType === 'Float') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n } else if (targetType === 'LiteralInteger') {\r\n this.castLiteralToFloat(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'Integer':\r\n if (targetType === 'Number' || targetType === 'Float') {\r\n retArr.push('float(');\r\n this.astGeneric(argument, retArr);\r\n retArr.push(')');\r\n continue;\r\n } else if (targetType === 'Integer') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'LiteralInteger':\r\n if (targetType === 'Integer') {\r\n this.castLiteralToInteger(argument, retArr);\r\n continue;\r\n } else if (targetType === 'Number' || targetType === 'Float') {\r\n this.castLiteralToFloat(argument, retArr);\r\n continue;\r\n } else if (targetType === 'LiteralInteger') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n if (targetType === argumentType) {\r\n if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);\r\n this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);\r\n retArr.push(`user_${argument.name}`);\r\n continue;\r\n }\r\n break;\r\n case 'HTMLImage':\r\n case 'HTMLImageArray':\r\n case 'HTMLVideo':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'Array':\r\n case 'Input':\r\n if (targetType === argumentType) {\r\n if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);\r\n this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);\r\n retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`);\r\n continue;\r\n }\r\n break;\r\n }\r\n throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named \"${ argument.name }\"`, ast);\r\n }\r\n }\r\n // Close arguments space\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Array* Expression\r\n * @param {Object} arrNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astArrayExpression(arrNode, retArr) {\r\n const arrLen = arrNode.elements.length;\r\n\r\n retArr.push('vec' + arrLen + '(');\r\n for (let i = 0; i < arrLen; ++i) {\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const subNode = arrNode.elements[i];\r\n this.astGeneric(subNode, retArr)\r\n }\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n memberExpressionXYZ(x, y, z, retArr) {\r\n if (z) {\r\n retArr.push(this.memberExpressionPropertyMarkup(z), ', ');\r\n } else {\r\n retArr.push('0, ');\r\n }\r\n if (y) {\r\n retArr.push(this.memberExpressionPropertyMarkup(y), ', ');\r\n } else {\r\n retArr.push('0, ');\r\n }\r\n retArr.push(this.memberExpressionPropertyMarkup(x));\r\n return retArr;\r\n }\r\n\r\n memberExpressionPropertyMarkup(property) {\r\n if (!property) {\r\n throw new Error('Property not set');\r\n }\r\n const type = this.getType(property);\r\n const result = [];\r\n switch (type) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(property, result);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(property, result);\r\n break;\r\n default:\r\n this.astGeneric(property, result);\r\n }\r\n return result.join('');\r\n }\r\n}\r\n\r\nconst typeMap = {\r\n 'Array': 'sampler2D',\r\n 'Array(2)': 'vec2',\r\n 'Array(3)': 'vec3',\r\n 'Array(4)': 'vec4',\r\n 'Array2D': 'sampler2D',\r\n 'Array3D': 'sampler2D',\r\n 'Boolean': 'bool',\r\n 'Float': 'float',\r\n 'Input': 'sampler2D',\r\n 'Integer': 'int',\r\n 'Number': 'float',\r\n 'LiteralInteger': 'float',\r\n 'NumberTexture': 'sampler2D',\r\n 'MemoryOptimizedNumberTexture': 'sampler2D',\r\n 'ArrayTexture(1)': 'sampler2D',\r\n 'ArrayTexture(2)': 'sampler2D',\r\n 'ArrayTexture(3)': 'sampler2D',\r\n 'ArrayTexture(4)': 'sampler2D',\r\n 'HTMLVideo': 'sampler2D',\r\n 'HTMLImage': 'sampler2D',\r\n 'HTMLImageArray': 'sampler2DArray',\r\n};\r\n\r\nconst operatorMap = {\r\n '===': '==',\r\n '!==': '!='\r\n};\r\n","const source = `\r\n\r\nuniform highp float triangle_noise_seed;\r\nhighp float triangle_noise_shift = 0.000001;\r\n\r\n//https://www.shadertoy.com/view/4t2SDh\r\n//note: uniformly distributed, normalized rand, [0;1[\r\nfloat nrand( vec2 n )\r\n{\r\n return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);\r\n}\r\n//note: remaps v to [0;1] in interval [a;b]\r\nfloat remap( float a, float b, float v )\r\n{\r\n return clamp( (v-a) / (b-a), 0.0, 1.0 );\r\n}\r\n\r\nfloat n4rand( vec2 n )\r\n{\r\n float t = fract( triangle_noise_seed + triangle_noise_shift );\r\n float nrnd0 = nrand( n + 0.07*t );\r\n float nrnd1 = nrand( n + 0.11*t );\r\n float nrnd2 = nrand( n + 0.13*t );\r\n float nrnd3 = nrand( n + 0.17*t );\r\n float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0;\r\n triangle_noise_shift = result + 0.000001;\r\n return result;\r\n}`;\r\n\r\nconst name = 'triangle-noise-noise';\r\n\r\nconst functionMatch = 'Math.random()';\r\n\r\nconst functionReplace = 'n4rand(vTexCoord)';\r\n\r\nconst functionReturnType = 'Number';\r\n\r\nconst onBeforeRun = (kernel) => {\r\n kernel.setUniform1f('triangle_noise_seed', Math.random());\r\n};\r\n\r\n/**\r\n * @type IPlugin\r\n */\r\nexport default {\r\n name,\r\n onBeforeRun,\r\n functionMatch,\r\n functionReplace,\r\n functionReturnType,\r\n source\r\n};\r\n","// language=GLSL\r\nexport const fragmentShader = `__HEADER__;\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nconst int LOOP_MAX = __LOOP_MAX__;\r\n\r\n__PLUGINS__;\r\n__CONSTANTS__;\r\n\r\nvarying vec2 vTexCoord;\r\n\r\nvec4 round(vec4 x) {\r\n return floor(x + 0.5);\r\n}\r\n\r\nfloat round(float x) {\r\n return floor(x + 0.5);\r\n}\r\n\r\nconst int BIT_COUNT = 32;\r\nint modi(int x, int y) {\r\n return x - y * (x / y);\r\n}\r\n\r\nint bitwiseOr(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseXOR(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseAnd(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 && b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseNot(int a) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (modi(a, 2) == 0) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n n = n * 2;\r\n }\r\n return result;\r\n}\r\nint bitwiseZeroFillLeftShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n *= 2;\r\n }\r\n\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nint bitwiseSignedRightShift(int num, int shifts) {\r\n return int(floor(float(num) / pow(2.0, float(shifts))));\r\n}\r\n\r\nint bitwiseZeroFillRightShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n /= 2;\r\n }\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nvec2 integerMod(vec2 x, float y) {\r\n vec2 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec3 integerMod(vec3 x, float y) {\r\n vec3 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec4 integerMod(vec4 x, vec4 y) {\r\n vec4 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nfloat integerMod(float x, float y) {\r\n float res = floor(mod(x, y));\r\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\r\n}\r\n\r\nint integerMod(int x, int y) {\r\n return x - (y * int(x / y));\r\n}\r\n\r\n__DIVIDE_WITH_INTEGER_CHECK__;\r\n\r\n// Here be dragons!\r\n// DO NOT OPTIMIZE THIS CODE\r\n// YOU WILL BREAK SOMETHING ON SOMEBODY\\'S MACHINE\r\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\r\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\r\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\r\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\r\nfloat decode32(vec4 texel) {\r\n __DECODE32_ENDIANNESS__;\r\n texel *= 255.0;\r\n vec2 gte128;\r\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\r\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\r\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\r\n float res = exp2(round(exponent));\r\n texel.b = texel.b - 128.0 * gte128.x;\r\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\r\n res *= gte128.y * -2.0 + 1.0;\r\n return res;\r\n}\r\n\r\nfloat decode16(vec4 texel, int index) {\r\n int channel = integerMod(index, 2);\r\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\r\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\r\n return 0.0;\r\n}\r\n\r\nfloat decode8(vec4 texel, int index) {\r\n int channel = integerMod(index, 4);\r\n if (channel == 0) return texel.r * 255.0;\r\n if (channel == 1) return texel.g * 255.0;\r\n if (channel == 2) return texel.b * 255.0;\r\n if (channel == 3) return texel.a * 255.0;\r\n return 0.0;\r\n}\r\n\r\nvec4 legacyEncode32(float f) {\r\n float F = abs(f);\r\n float sign = f < 0.0 ? 1.0 : 0.0;\r\n float exponent = floor(log2(F));\r\n float mantissa = (exp2(-exponent) * F);\r\n // exponent += floor(log2(mantissa));\r\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\r\n texel.rg = integerMod(texel.rg, 256.0);\r\n texel.b = integerMod(texel.b, 128.0);\r\n texel.a = exponent*0.5 + 63.5;\r\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\r\n texel = floor(texel);\r\n texel *= 0.003921569; // 1/255\r\n __ENCODE32_ENDIANNESS__;\r\n return texel;\r\n}\r\n\r\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\r\nvec4 encode32(float value) {\r\n if (value == 0.0) return vec4(0, 0, 0, 0);\r\n\r\n float exponent;\r\n float mantissa;\r\n vec4 result;\r\n float sgn;\r\n\r\n sgn = step(0.0, -value);\r\n value = abs(value);\r\n\r\n exponent = floor(log2(value));\r\n\r\n mantissa = value*pow(2.0, -exponent)-1.0;\r\n exponent = exponent+127.0;\r\n result = vec4(0,0,0,0);\r\n\r\n result.a = floor(exponent/2.0);\r\n exponent = exponent - result.a*2.0;\r\n result.a = result.a + 128.0*sgn;\r\n\r\n result.b = floor(mantissa * 128.0);\r\n mantissa = mantissa - result.b / 128.0;\r\n result.b = result.b + exponent*128.0;\r\n\r\n result.g = floor(mantissa*32768.0);\r\n mantissa = mantissa - result.g/32768.0;\r\n\r\n result.r = floor(mantissa*8388608.0);\r\n return result/255.0;\r\n}\r\n// Dragons end here\r\n\r\nint index;\r\nivec3 threadId;\r\n\r\nivec3 indexTo3D(int idx, ivec3 texDim) {\r\n int z = int(idx / (texDim.x * texDim.y));\r\n idx -= z * int(texDim.x * texDim.y);\r\n int y = int(idx / texDim.x);\r\n int x = int(integerMod(idx, texDim.x));\r\n return ivec3(x, y, z);\r\n}\r\n\r\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n return decode32(texel);\r\n}\r\n\r\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x * 2;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\r\n return decode16(texel, index);\r\n}\r\n\r\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x * 4;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\r\n return decode8(texel, index);\r\n}\r\n\r\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 4);\r\n index = index / 4;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n if (channel == 0) return texel.r;\r\n if (channel == 1) return texel.g;\r\n if (channel == 2) return texel.b;\r\n if (channel == 3) return texel.a;\r\n return 0.0;\r\n}\r\n\r\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture2D(tex, st / vec2(texSize));\r\n}\r\n\r\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return result[0];\r\n}\r\n\r\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec2(result[0], result[1]);\r\n}\r\n\r\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int channel = integerMod(index, 2);\r\n index = index / 2;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n if (channel == 0) return vec2(texel.r, texel.g);\r\n if (channel == 1) return vec2(texel.b, texel.a);\r\n return vec2(0.0, 0.0);\r\n}\r\n\r\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec3(result[0], result[1], result[2]);\r\n}\r\n\r\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\r\n int vectorIndex = fieldIndex / 4;\r\n int vectorOffset = fieldIndex - vectorIndex * 4;\r\n int readY = vectorIndex / texSize.x;\r\n int readX = vectorIndex - readY * texSize.x;\r\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\r\n\r\n if (vectorOffset == 0) {\r\n return tex1.xyz;\r\n } else if (vectorOffset == 1) {\r\n return tex1.yzw;\r\n } else {\r\n readX++;\r\n if (readX >= texSize.x) {\r\n readX = 0;\r\n readY++;\r\n }\r\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\r\n if (vectorOffset == 2) {\r\n return vec3(tex1.z, tex1.w, tex2.x);\r\n } else {\r\n return vec3(tex1.w, tex2.x, tex2.y);\r\n }\r\n }\r\n}\r\n\r\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n return getImage2D(tex, texSize, texDim, z, y, x);\r\n}\r\n\r\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n return vec4(texel.r, texel.g, texel.b, texel.a);\r\n}\r\n\r\nvec4 actualColor;\r\nvoid color(float r, float g, float b, float a) {\r\n actualColor = vec4(r,g,b,a);\r\n}\r\n\r\nvoid color(float r, float g, float b) {\r\n color(r,g,b,1.0);\r\n}\r\n\r\nvoid color(sampler2D image) {\r\n actualColor = texture2D(image, vTexCoord);\r\n}\r\n\r\n__INJECTED_NATIVE__;\r\n__MAIN_CONSTANTS__;\r\n__MAIN_ARGUMENTS__;\r\n__KERNEL__;\r\n\r\nvoid main(void) {\r\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\r\n __MAIN_RESULT__;\r\n}`;\r\n","// language=GLSL\r\nexport const vertexShader = `__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nattribute vec2 aPos;\r\nattribute vec2 aTexCoord;\r\n\r\nvarying vec2 vTexCoord;\r\nuniform vec2 ratio;\r\n\r\nvoid main(void) {\r\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\r\n vTexCoord = aTexCoord;\r\n}`;\r\n","/**\n *\n * @param {WebGLRenderingContext} gl\n * @param {IGLWiretapOptions} [options]\n * @returns {GLWiretapProxy}\n */\nfunction glWiretap(gl, options = {}) {\n const {\n contextName = 'gl',\n throwGetError,\n useTrackablePrimitives,\n readPixelsFile,\n recording = [],\n variables = {},\n onReadPixels,\n onUnrecognizedArgumentLookup,\n } = options;\n const proxy = new Proxy(gl, { get: listen });\n const contextVariables = [];\n const entityNames = {};\n let imageCount = 0;\n let indent = '';\n let readPixelsVariableName;\n return proxy;\n function listen(obj, property) {\n switch (property) {\n case 'addComment': return addComment;\n case 'checkThrowError': return checkThrowError;\n case 'getReadPixelsVariableName': return readPixelsVariableName;\n case 'insertVariable': return insertVariable;\n case 'reset': return reset;\n case 'setIndent': return setIndent;\n case 'toString': return toString;\n case 'getContextVariableName': return getContextVariableName;\n }\n if (typeof gl[property] === 'function') {\n return function() { // need arguments from this, fyi\n switch (property) {\n case 'getError':\n if (throwGetError) {\n recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`);\n } else {\n recording.push(`${indent}${contextName}.getError();`); // flush out errors\n }\n return gl.getError();\n case 'getExtension': {\n const variableName = `${contextName}Variables${contextVariables.length}`;\n recording.push(`${indent}const ${variableName} = ${contextName}.getExtension('${arguments[0]}');`);\n const extension = gl.getExtension(arguments[0]);\n if (extension && typeof extension === 'object') {\n const tappedExtension = glExtensionWiretap(extension, {\n getEntity,\n useTrackablePrimitives,\n recording,\n contextName: variableName,\n contextVariables,\n variables,\n indent,\n onUnrecognizedArgumentLookup,\n });\n contextVariables.push(tappedExtension);\n return tappedExtension;\n } else {\n contextVariables.push(null);\n }\n return extension;\n }\n case 'readPixels':\n const i = contextVariables.indexOf(arguments[6]);\n let targetVariableName;\n if (i === -1) {\n const variableName = getVariableName(arguments[6]);\n if (variableName) {\n targetVariableName = variableName;\n recording.push(`${indent}${variableName}`);\n } else {\n targetVariableName = `${contextName}Variable${contextVariables.length}`;\n contextVariables.push(arguments[6]);\n recording.push(`${indent}const ${targetVariableName} = new ${arguments[6].constructor.name}(${arguments[6].length});`);\n }\n } else {\n targetVariableName = `${contextName}Variable${i}`;\n }\n readPixelsVariableName = targetVariableName;\n const argumentAsStrings = [\n arguments[0],\n arguments[1],\n arguments[2],\n arguments[3],\n getEntity(arguments[4]),\n getEntity(arguments[5]),\n targetVariableName\n ];\n recording.push(`${indent}${contextName}.readPixels(${argumentAsStrings.join(', ')});`);\n if (readPixelsFile) {\n writePPM(arguments[2], arguments[3]);\n }\n if (onReadPixels) {\n onReadPixels(targetVariableName, argumentAsStrings);\n }\n return gl.readPixels.apply(gl, arguments);\n case 'drawBuffers':\n recording.push(`${indent}${contextName}.drawBuffers([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup } )}]);`);\n return gl.drawBuffers(arguments[0]);\n }\n let result = gl[property].apply(gl, arguments);\n switch (typeof result) {\n case 'undefined':\n recording.push(`${indent}${methodCallToString(property, arguments)};`);\n return;\n case 'number':\n case 'boolean':\n if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result = trackablePrimitive(result));\n break;\n }\n default:\n if (result === null) {\n recording.push(`${methodCallToString(property, arguments)};`);\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n }\n\n contextVariables.push(result);\n }\n return result;\n }\n }\n entityNames[gl[property]] = property;\n return gl[property];\n }\n function toString() {\n return recording.join('\\n');\n }\n function reset() {\n while (recording.length > 0) {\n recording.pop();\n }\n }\n function insertVariable(name, value) {\n variables[name] = value;\n }\n function getEntity(value) {\n const name = entityNames[value];\n if (name) {\n return contextName + '.' + name;\n }\n return value;\n }\n function setIndent(spaces) {\n indent = ' '.repeat(spaces);\n }\n function addVariable(value, source) {\n const variableName = `${contextName}Variable${contextVariables.length}`;\n recording.push(`${indent}const ${variableName} = ${source};`);\n contextVariables.push(value);\n return variableName;\n }\n function writePPM(width, height) {\n const sourceVariable = `${contextName}Variable${contextVariables.length}`;\n const imageVariable = `imageDatum${imageCount}`;\n recording.push(`${indent}let ${imageVariable} = [\"P3\\\\n# ${readPixelsFile}.ppm\\\\n\", ${width}, ' ', ${height}, \"\\\\n255\\\\n\"].join(\"\");`);\n recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`);\n recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`);\n recording.push(`${indent}}`);\n recording.push(`${indent}if (typeof require !== \"undefined\") {`);\n recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`);\n recording.push(`${indent}}`);\n imageCount++;\n }\n function addComment(value) {\n recording.push(`${indent}// ${value}`);\n }\n function checkThrowError() {\n recording.push(`${indent}(() => {\n${indent}const error = ${contextName}.getError();\n${indent}if (error !== ${contextName}.NONE) {\n${indent} const names = Object.getOwnPropertyNames(gl);\n${indent} for (let i = 0; i < names.length; i++) {\n${indent} const name = names[i];\n${indent} if (${contextName}[name] === error) {\n${indent} throw new Error('${contextName} threw ' + name);\n${indent} }\n${indent} }\n${indent}}\n${indent}})();`);\n }\n function methodCallToString(method, args) {\n return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;\n }\n\n function getVariableName(value) {\n if (variables) {\n for (const name in variables) {\n if (variables[name] === value) {\n return name;\n }\n }\n }\n return null;\n }\n\n function getContextVariableName(value) {\n const i = contextVariables.indexOf(value);\n if (i !== -1) {\n return `${contextName}Variable${i}`;\n }\n return null;\n }\n}\n\n/**\n *\n * @param extension\n * @param {IGLExtensionWiretapOptions} options\n * @returns {*}\n */\nfunction glExtensionWiretap(extension, options) {\n const proxy = new Proxy(extension, { get: listen });\n const extensionEntityNames = {};\n const {\n contextName,\n contextVariables,\n getEntity,\n useTrackablePrimitives,\n recording,\n variables,\n indent,\n onUnrecognizedArgumentLookup,\n } = options;\n return proxy;\n function listen(obj, property) {\n if (typeof obj[property] === 'function') {\n return function() {\n switch (property) {\n case 'drawBuffersWEBGL':\n recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`);\n return extension.drawBuffersWEBGL(arguments[0]);\n }\n let result = extension[property].apply(extension, arguments);\n switch (typeof result) {\n case 'undefined':\n recording.push(`${indent}${methodCallToString(property, arguments)};`);\n return;\n case 'number':\n case 'boolean':\n if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result = trackablePrimitive(result));\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result);\n }\n break;\n default:\n if (result === null) {\n recording.push(`${methodCallToString(property, arguments)};`);\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n }\n contextVariables.push(result);\n }\n return result;\n };\n }\n extensionEntityNames[extension[property]] = property;\n return extension[property];\n }\n\n function getExtensionEntity(value) {\n if (extensionEntityNames.hasOwnProperty(value)) {\n return `${contextName}.${extensionEntityNames[value]}`;\n }\n return getEntity(value);\n }\n\n function methodCallToString(method, args) {\n return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;\n }\n\n function addVariable(value, source) {\n const variableName = `${contextName}Variable${contextVariables.length}`;\n contextVariables.push(value);\n recording.push(`${indent}const ${variableName} = ${source};`);\n return variableName;\n }\n}\n\nfunction argumentsToString(args, options) {\n const { variables, onUnrecognizedArgumentLookup } = options;\n return (Array.from(args).map((arg) => {\n const variableName = getVariableName(arg);\n if (variableName) {\n return variableName;\n }\n return argumentToString(arg, options);\n }).join(', '));\n\n function getVariableName(value) {\n if (variables) {\n for (const name in variables) {\n if (!variables.hasOwnProperty(name)) continue;\n if (variables[name] === value) {\n return name;\n }\n }\n }\n if (onUnrecognizedArgumentLookup) {\n return onUnrecognizedArgumentLookup(value);\n }\n return null;\n }\n}\n\nfunction argumentToString(arg, options) {\n const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options;\n if (typeof arg === 'undefined') {\n return 'undefined';\n }\n if (arg === null) {\n return 'null';\n }\n const i = contextVariables.indexOf(arg);\n if (i > -1) {\n return `${contextName}Variable${i}`;\n }\n switch (arg.constructor.name) {\n case 'String':\n const hasLines = /\\n/.test(arg);\n const hasSingleQuotes = /'/.test(arg);\n const hasDoubleQuotes = /\"/.test(arg);\n if (hasLines) {\n return '`' + arg + '`';\n } else if (hasSingleQuotes && !hasDoubleQuotes) {\n return '\"' + arg + '\"';\n } else if (!hasSingleQuotes && hasDoubleQuotes) {\n return \"'\" + arg + \"'\";\n } else {\n return '\\'' + arg + '\\'';\n }\n case 'Number': return getEntity(arg);\n case 'Boolean': return getEntity(arg);\n case 'Array':\n return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`);\n case 'Float32Array':\n case 'Uint8Array':\n case 'Uint16Array':\n case 'Int32Array':\n return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`);\n default:\n if (onUnrecognizedArgumentLookup) {\n const instantiationString = onUnrecognizedArgumentLookup(arg);\n if (instantiationString) {\n return instantiationString;\n }\n }\n throw new Error(`unrecognized argument type ${arg.constructor.name}`);\n }\n}\n\nfunction trackablePrimitive(value) {\n // wrapped in object, so track-able\n return new value.constructor(value);\n}\n\nif (typeof module !== 'undefined') {\n module.exports = { glWiretap, glExtensionWiretap };\n}\n\nif (typeof window !== 'undefined') {\n glWiretap.glExtensionWiretap = glExtensionWiretap;\n window.glWiretap = glWiretap;\n}\n","import { glWiretap } from 'gl-wiretap';\r\nimport { utils } from '../../utils';\r\n\r\nfunction toStringWithoutUtils(fn) {\r\n return fn.toString()\r\n .replace('=>', '')\r\n .replace(/^function /, '')\r\n .replace(/utils[.]/g, '/*utils.*/');\r\n}\r\n\r\n/**\r\n *\r\n * @param {Kernel} Kernel\r\n * @param {KernelVariable[]} args\r\n * @param {Kernel} originKernel\r\n * @param {string} [setupContextString]\r\n * @param {string} [destroyContextString]\r\n * @returns {string}\r\n */\r\nexport function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) {\r\n args = args ? Array.from(args).map(arg => {\r\n switch (typeof arg) {\r\n case 'boolean':\r\n return new Boolean(arg);\r\n case 'number':\r\n return new Number(arg);\r\n default:\r\n return arg;\r\n }\r\n }) : null;\r\n const uploadedValues = [];\r\n const postResult = [];\r\n const context = glWiretap(originKernel.context, {\r\n useTrackablePrimitives: true,\r\n onReadPixels: (targetName) => {\r\n if (kernel.subKernels) {\r\n if (!subKernelsResultVariableSetup) {\r\n postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`);\r\n subKernelsResultVariableSetup = true;\r\n } else {\r\n const property = kernel.subKernels[subKernelsResultIndex++].property;\r\n postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`);\r\n }\r\n if (subKernelsResultIndex === kernel.subKernels.length) {\r\n postResult.push(' return result;');\r\n }\r\n return;\r\n }\r\n if (targetName) {\r\n postResult.push(` return ${getRenderString(targetName, kernel)};`);\r\n } else {\r\n postResult.push(` return null;`);\r\n }\r\n },\r\n onUnrecognizedArgumentLookup: (argument) => {\r\n const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues);\r\n if (argumentName) {\r\n return argumentName;\r\n }\r\n const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues);\r\n if (constantName) {\r\n return constantName;\r\n }\r\n return null;\r\n }\r\n });\r\n let subKernelsResultVariableSetup = false;\r\n let subKernelsResultIndex = 0;\r\n const {\r\n source,\r\n canvas,\r\n output,\r\n pipeline,\r\n graphical,\r\n loopMaxIterations,\r\n constants,\r\n optimizeFloatMemory,\r\n precision,\r\n fixIntegerDivisionAccuracy,\r\n functions,\r\n nativeFunctions,\r\n subKernels,\r\n immutable,\r\n argumentTypes,\r\n constantTypes,\r\n kernelArguments,\r\n kernelConstants,\r\n } = originKernel;\r\n const kernel = new Kernel(source, {\r\n canvas,\r\n context,\r\n checkContext: false,\r\n output,\r\n pipeline,\r\n graphical,\r\n loopMaxIterations,\r\n constants,\r\n optimizeFloatMemory,\r\n precision,\r\n fixIntegerDivisionAccuracy,\r\n functions,\r\n nativeFunctions,\r\n subKernels,\r\n immutable,\r\n argumentTypes,\r\n constantTypes,\r\n });\r\n let result = [];\r\n context.setIndent(2);\r\n kernel.build.apply(kernel, args);\r\n result.push(context.toString());\r\n context.reset();\r\n\r\n kernel.kernelArguments.forEach((kernelArgument, i) => {\r\n switch (kernelArgument.type) {\r\n // primitives\r\n case 'Integer':\r\n case 'Boolean':\r\n case 'Number':\r\n case 'Float':\r\n // non-primitives\r\n case 'Array':\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);\r\n break;\r\n case 'HTMLImageArray':\r\n for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) {\r\n const arg = args[i];\r\n context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]);\r\n }\r\n break;\r\n case 'Input':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);\r\n break;\r\n case 'MemoryOptimizedNumberTexture':\r\n case 'NumberTexture':\r\n case 'Array1D(2)':\r\n case 'Array1D(3)':\r\n case 'Array1D(4)':\r\n case 'Array2D(2)':\r\n case 'Array2D(3)':\r\n case 'Array2D(4)':\r\n case 'Array3D(2)':\r\n case 'Array3D(3)':\r\n case 'Array3D(4)':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture);\r\n break;\r\n default:\r\n throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`);\r\n }\r\n });\r\n result.push('/** start of injected functions **/');\r\n result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.isArray)}`);\r\n if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) {\r\n result.push(\r\n ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};`\r\n );\r\n }\r\n result.push('/** end of injected functions **/');\r\n result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`);\r\n context.setIndent(4);\r\n kernel.run.apply(kernel, args);\r\n if (kernel.renderKernels) {\r\n kernel.renderKernels();\r\n } else if (kernel.renderOutput) {\r\n kernel.renderOutput();\r\n }\r\n result.push(' /** start setup uploads for kernel values **/');\r\n kernel.kernelArguments.forEach(kernelArgument => {\r\n result.push(' ' + kernelArgument.getStringValueHandler().split('\\n').join('\\n '));\r\n });\r\n result.push(' /** end setup uploads for kernel values **/');\r\n result.push(context.toString());\r\n if (kernel.renderOutput === kernel.renderTexture) {\r\n context.reset();\r\n const results = kernel.renderKernels();\r\n const textureName = context.getContextVariableName(kernel.outputTexture);\r\n result.push(` return {\r\n result: {\r\n texture: ${ textureName },\r\n type: '${ results.result.type }',\r\n toArray: ${ getToArrayString(results.result, textureName) }\r\n },`);\r\n const { subKernels, subKernelOutputTextures } = kernel;\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const texture = subKernelOutputTextures[i];\r\n const subKernel = subKernels[i];\r\n const subKernelResult = results[subKernel.property];\r\n const subKernelTextureName = context.getContextVariableName(texture);\r\n result.push(`\r\n ${subKernel.property}: {\r\n texture: ${ subKernelTextureName },\r\n type: '${ subKernelResult.type }',\r\n toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) }\r\n },`);\r\n }\r\n result.push(` };`);\r\n }\r\n result.push(` ${destroyContextString ? '\\n' + destroyContextString + ' ': ''}`);\r\n result.push(postResult.join('\\n'));\r\n result.push(' };');\r\n if (kernel.graphical) {\r\n result.push(getGetPixelsString(kernel));\r\n result.push(` innerKernel.getPixels = getPixels;`);\r\n }\r\n result.push(' return innerKernel;');\r\n\r\n let constantsUpload = [];\r\n kernelConstants.forEach((kernelConstant) => {\r\n constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`);\r\n });\r\n return `function kernel(settings) {\r\n const { context, constants } = settings;\r\n ${constantsUpload.join('')}\r\n ${setupContextString ? setupContextString : ''}\r\n${result.join('\\n')}\r\n}`;\r\n}\r\n\r\nfunction getRenderString(targetName, kernel) {\r\n const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`;\r\n if (kernel.output[2]) {\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`;\r\n }\r\n if (kernel.output[1]) {\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`;\r\n }\r\n\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]})`;\r\n}\r\n\r\nfunction getGetPixelsString(kernel) {\r\n const getPixels = kernel.getPixels.toString();\r\n const useFunctionKeyword = !/^function/.test(getPixels);\r\n return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, {\r\n findDependency: (object, name) => {\r\n if (object === 'utils') {\r\n return `const ${name} = ${utils[name].toString()};`;\r\n }\r\n return null;\r\n },\r\n thisLookup: (property) => {\r\n if (property === 'context') {\r\n return null;\r\n }\r\n if (kernel.hasOwnProperty(property)) {\r\n return JSON.stringify(kernel[property]);\r\n }\r\n throw new Error(`unhandled thisLookup ${ property }`);\r\n }\r\n });\r\n}\r\n\r\nfunction getToArrayString(kernelResult, textureName) {\r\n const toArray = kernelResult.toArray.toString();\r\n const useFunctionKeyword = !/^function/.test(toArray);\r\n const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, {\r\n findDependency: (object, name) => {\r\n if (object === 'utils') {\r\n return `const ${name} = ${utils[name].toString()};`;\r\n } else if (object === 'this') {\r\n return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`;\r\n } else {\r\n throw new Error('unhandled fromObject');\r\n }\r\n },\r\n thisLookup: (property) => {\r\n if (property === 'texture') {\r\n return textureName;\r\n }\r\n if (kernelResult.hasOwnProperty(property)) {\r\n return JSON.stringify(kernelResult[property]);\r\n }\r\n throw new Error(`unhandled thisLookup ${ property }`);\r\n }\r\n });\r\n return `() => {\r\n ${flattenedFunctions}\r\n return toArray();\r\n }`;\r\n}\r\n\r\n/**\r\n *\r\n * @param {KernelVariable} argument\r\n * @param {KernelValue[]} kernelValues\r\n * @param {KernelVariable[]} values\r\n * @param context\r\n * @param {KernelVariable[]} uploadedValues\r\n * @return {string|null}\r\n */\r\nfunction findKernelValue(argument, kernelValues, values, context, uploadedValues) {\r\n if (argument === null) return null;\r\n switch (typeof argument) {\r\n case 'boolean':\r\n case 'number':\r\n return null;\r\n }\r\n if (\r\n typeof HTMLImageElement !== 'undefined' &&\r\n argument instanceof HTMLImageElement\r\n ) {\r\n for (let i = 0; i < kernelValues.length; i++) {\r\n const kernelValue = kernelValues[i];\r\n if (kernelValue.type !== 'HTMLImageArray') continue;\r\n if (kernelValue.uploadValue !== argument) continue;\r\n // TODO: if we send two of the same image, the parser could get confused, and short circuit to the first, handle that here\r\n const variableIndex = values[i].indexOf(argument);\r\n if (variableIndex === -1) continue;\r\n const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`;\r\n context.insertVariable(variableName, argument);\r\n return variableName;\r\n }\r\n return null;\r\n }\r\n\r\n for (let i = 0; i < kernelValues.length; i++) {\r\n const kernelValue = kernelValues[i];\r\n if (argument !== kernelValue.uploadValue) continue;\r\n const variable = `uploadValue_${kernelValue.name}`;\r\n context.insertVariable(variable, kernelValue);\r\n return variable;\r\n }\r\n return null;\r\n}\r\n","/**\r\n * @class KernelValue\r\n */\r\nexport class KernelValue {\r\n /**\r\n *\r\n * @param {KernelVariable} value\r\n * @param {IKernelValueSettings} settings\r\n */\r\n constructor(value, settings) {\r\n const {\r\n name,\r\n kernel,\r\n context,\r\n checkContext,\r\n onRequestContextHandle,\r\n onUpdateValueMismatch,\r\n origin,\r\n strictIntegers,\r\n type,\r\n tactic,\r\n } = settings;\r\n if (!name) {\r\n throw new Error('name not set');\r\n }\r\n if (!type) {\r\n throw new Error('type not set');\r\n }\r\n if (!origin) {\r\n throw new Error('origin not set');\r\n }\r\n if (!tactic) {\r\n throw new Error('tactic not set');\r\n }\r\n if (origin !== 'user' && origin !== 'constants') {\r\n throw new Error(`origin must be \"user\" or \"constants\" value is \"${ origin }\"`);\r\n }\r\n if (!onRequestContextHandle) {\r\n throw new Error('onRequestContextHandle is not set');\r\n }\r\n this.name = name;\r\n this.origin = origin;\r\n this.tactic = tactic;\r\n this.id = `${this.origin}_${name}`;\r\n this.varName = origin === 'constants' ? `constants.${name}` : name;\r\n this.kernel = kernel;\r\n this.strictIntegers = strictIntegers;\r\n // handle textures\r\n this.type = value.type || type;\r\n this.size = value.size || null;\r\n this.index = null;\r\n this.context = context;\r\n this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true;\r\n this.contextHandle = null;\r\n this.onRequestContextHandle = onRequestContextHandle;\r\n this.onUpdateValueMismatch = onUpdateValueMismatch;\r\n this.forceUploadEachRun = null;\r\n }\r\n\r\n getSource() {\r\n throw new Error(`\"getSource\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n updateValue(value) {\r\n throw new Error(`\"updateValue\" not defined on ${ this.constructor.name }`);\r\n }\r\n}\r\n","import { Input } from '../../../input';\r\nimport { KernelValue } from '../../kernel-value';\r\nimport { utils } from '../../../utils';\r\n\r\nexport class WebGLKernelValue extends KernelValue {\r\n /**\r\n * @param {KernelVariable} value\r\n * @param {IWebGLKernelValueSettings} settings\r\n */\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.dimensionsId = null;\r\n this.sizeId = null;\r\n this.initialValueConstructor = value.constructor;\r\n this.onRequestTexture = settings.onRequestTexture;\r\n this.onRequestIndex = settings.onRequestIndex;\r\n this.uploadValue = null;\r\n this.textureSize = null;\r\n this.bitRatio = null;\r\n }\r\n\r\n /**\r\n *\r\n * @param {number} width\r\n * @param {number} height\r\n */\r\n checkSize(width, height) {\r\n if (!this.kernel.validate) return;\r\n const { maxTextureSize } = this.kernel.constructor.features;\r\n if (width > maxTextureSize || height > maxTextureSize) {\r\n if (width > height) {\r\n throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`);\r\n } else {\r\n throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);\r\n }\r\n }\r\n }\r\n\r\n requestTexture() {\r\n this.texture = this.onRequestTexture();\r\n this.setupTexture();\r\n }\r\n\r\n setupTexture() {\r\n this.contextHandle = this.onRequestContextHandle();\r\n this.index = this.onRequestIndex();\r\n this.dimensionsId = this.id + 'Dim';\r\n this.sizeId = this.id + 'Size';\r\n }\r\n\r\n getTransferArrayType(value) {\r\n if (Array.isArray(value[0])) {\r\n return this.getTransferArrayType(value[0]);\r\n }\r\n switch (value.constructor) {\r\n case Array:\r\n case Int32Array:\r\n case Int16Array:\r\n case Int8Array:\r\n return Float32Array;\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Uint16Array:\r\n case Uint32Array:\r\n case Float32Array:\r\n case Float64Array:\r\n return value.constructor;\r\n }\r\n console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros');\r\n return value.constructor;\r\n }\r\n /**\r\n * @desc Adds kernel parameters to the Value Texture,\r\n * binding it to the context, etc.\r\n *\r\n * @param {Array|Float32Array|Uint16Array} value - The actual Value supplied to the kernel\r\n * @param {Number} length - the expected total length of the output array\r\n * @param {Object} [Type]\r\n * @returns {Float32Array|Uint16Array|Uint8Array} flattened array to transfer\r\n */\r\n formatArrayTransfer(value, length, Type) {\r\n if (utils.isArray(value[0]) || this.optimizeFloatMemory) {\r\n // not already flat\r\n const valuesFlat = new Float32Array(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n } else {\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n case Uint16Array:\r\n case Int16Array:\r\n case Float32Array:\r\n case Int32Array: {\r\n const valuesFlat = new(Type || value.constructor)(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n }\r\n default: {\r\n const valuesFlat = new Float32Array(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4\r\n * @param value\r\n * @returns {number}\r\n */\r\n getBitRatio(value) {\r\n if (Array.isArray(value[0])) {\r\n return this.getBitRatio(value[0]);\r\n } else if (value.constructor === Input) {\r\n return this.getBitRatio(value.value);\r\n }\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n return 1;\r\n case Uint16Array:\r\n case Int16Array:\r\n return 2;\r\n case Float32Array:\r\n case Int32Array:\r\n default:\r\n return 4;\r\n }\r\n }\r\n\r\n /**\r\n * Used for when we want a string output of our kernel, so we can still input values to the kernel\r\n */\r\n getStringValueHandler() {\r\n throw new Error(`\"getStringValueHandler\" not implemented on ${this.constructor.name}`);\r\n }\r\n\r\n getVariablePrecisionString() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'lowp';\r\n case 'performance':\r\n return 'highp';\r\n case 'balanced':\r\n default:\r\n return 'mediump';\r\n }\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueBoolean extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const bool ${this.id} = ${value};\\n`;\r\n }\r\n return `uniform bool ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueFloat extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n if (Number.isInteger(value)) {\r\n return `const float ${this.id} = ${value}.0;\\n`;\r\n }\r\n return `const float ${this.id} = ${value};\\n`;\r\n }\r\n return `uniform float ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1f(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueInteger extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const int ${this.id} = ${ parseInt(value) };\\n`;\r\n }\r\n return `uniform int ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueHTMLImage extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const { width, height } = value;\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, 1];\r\n this.requestTexture();\r\n this.textureSize = [width, height];\r\n this.uploadValue = value;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputImage) {\r\n if (inputImage.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n const { width, height } = value;\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, 1];\r\n this.textureSize = [width, height];\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {}\r\n","import { WebGLKernelValueDynamicHTMLImage } from './dynamic-html-image';\r\n\r\nexport class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleInput extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}.value, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n if (input.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleInput } from './single-input';\r\n\r\nexport class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueUnsignedInput extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = this.getBitRatio(value);\r\n const [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n this.TranserArrayType = this.getTransferArrayType(value.value);\r\n this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,\r\n `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,\r\n `flattenTo(${this.varName}.value, preUploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n if (input.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.preUploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedInput } from './unsigned-input';\r\n\r\nexport class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n const Type = this.getTransferArrayType(value.value);\r\n this.preUploadValue = new Type(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const [width, height] = value.size;\r\n this.checkSize(width, height);\r\n this.setupTexture();\r\n this.dimensions = value.dimensions;\r\n this.textureSize = value.size;\r\n this.uploadValue = value.texture;\r\n this.forceUploadEachRun = true;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName}.texture;\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n if (inputTexture.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n if (this.checkContext && inputTexture.context !== this.context) {\r\n throw new Error(`Value ${this.name} (${this.type }) must be from same context`);\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from './memory-optimized-number-texture';\r\n\r\nexport class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n this.checkSize(inputTexture.size[0], inputTexture.size[1]);\r\n this.dimensions = inputTexture.dimensions;\r\n this.textureSize = inputTexture.size;\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(inputTexture);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueNumberTexture extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const [width, height] = value.size;\r\n this.checkSize(width, height);\r\n this.setupTexture();\r\n const { size: textureSize, dimensions } = value;\r\n this.bitRatio = this.getBitRatio(value);\r\n this.dimensions = dimensions;\r\n this.textureSize = textureSize;\r\n this.uploadValue = value.texture;\r\n this.forceUploadEachRun = true;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName}.texture;\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n if (inputTexture.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n if (this.checkContext && inputTexture.context !== this.context) {\r\n throw new Error(`Value ${this.name} (${this.type}) must be from same context`);\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueNumberTexture } from './number-texture';\r\n\r\nexport class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = value.dimensions;\r\n this.checkSize(value.size[0], value.size[1]);\r\n this.textureSize = value.size;\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray } from './single-array';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray1DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], 1, 1]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten2dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray1DI } from './single-array1d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray2DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten3dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray2DI } from './single-array2d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray3DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten4dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray3DI } from './single-array3d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray2 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\\n`;\r\n }\r\n return `uniform vec2 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(2)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform2fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray3 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\\n`;\r\n }\r\n return `uniform vec3 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(3)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform3fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray4 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\\n`;\r\n }\r\n return `uniform vec4 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(4)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform4fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueUnsignedArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = this.getBitRatio(value);\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n this.TranserArrayType = this.getTransferArrayType(value);\r\n this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,\r\n `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,\r\n `flattenTo(${this.varName}, preUploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.preUploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedArray } from './unsigned-array';\r\n\r\nexport class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n const Type = this.getTransferArrayType(value);\r\n this.preUploadValue = new Type(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueBoolean } from './kernel-value/boolean';\r\nimport { WebGLKernelValueFloat } from './kernel-value/float';\r\nimport { WebGLKernelValueInteger } from './kernel-value/integer';\r\n\r\nimport { WebGLKernelValueHTMLImage } from './kernel-value/html-image';\r\nimport { WebGLKernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image';\r\n\r\nimport { WebGLKernelValueHTMLVideo } from './kernel-value/html-video';\r\nimport { WebGLKernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video';\r\n\r\nimport { WebGLKernelValueSingleInput } from './kernel-value/single-input';\r\nimport { WebGLKernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input';\r\n\r\nimport { WebGLKernelValueUnsignedInput } from './kernel-value/unsigned-input';\r\nimport { WebGLKernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input';\r\n\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture';\r\nimport { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nimport { WebGLKernelValueNumberTexture } from './kernel-value/number-texture';\r\nimport { WebGLKernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture';\r\n\r\nimport { WebGLKernelValueSingleArray } from './kernel-value/single-array';\r\nimport { WebGLKernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array';\r\n\r\nimport { WebGLKernelValueSingleArray1DI } from './kernel-value/single-array1d-i';\r\nimport { WebGLKernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i';\r\n\r\nimport { WebGLKernelValueSingleArray2DI } from './kernel-value/single-array2d-i';\r\nimport { WebGLKernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i';\r\n\r\nimport { WebGLKernelValueSingleArray3DI } from './kernel-value/single-array3d-i';\r\nimport { WebGLKernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i';\r\n\r\nimport { WebGLKernelValueSingleArray2 } from './kernel-value/single-array2';\r\nimport { WebGLKernelValueSingleArray3 } from './kernel-value/single-array3';\r\nimport { WebGLKernelValueSingleArray4 } from './kernel-value/single-array4';\r\n\r\nimport { WebGLKernelValueUnsignedArray } from './kernel-value/unsigned-array';\r\nimport { WebGLKernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array';\r\n\r\nexport const kernelValueMaps = {\r\n unsigned: {\r\n dynamic: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Array': WebGLKernelValueDynamicUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGLKernelValueDynamicUnsignedInput,\r\n 'NumberTexture': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Array': WebGLKernelValueUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGLKernelValueUnsignedInput,\r\n 'NumberTexture': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueHTMLVideo,\r\n }\r\n },\r\n single: {\r\n dynamic: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Array': WebGLKernelValueDynamicSingleArray,\r\n 'Array(2)': WebGLKernelValueSingleArray2,\r\n 'Array(3)': WebGLKernelValueSingleArray3,\r\n 'Array(4)': WebGLKernelValueSingleArray4,\r\n 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Input': WebGLKernelValueDynamicSingleInput,\r\n 'NumberTexture': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Array': WebGLKernelValueSingleArray,\r\n 'Array(2)': WebGLKernelValueSingleArray2,\r\n 'Array(3)': WebGLKernelValueSingleArray3,\r\n 'Array(4)': WebGLKernelValueSingleArray4,\r\n 'Array1D(2)': WebGLKernelValueSingleArray1DI,\r\n 'Array1D(3)': WebGLKernelValueSingleArray1DI,\r\n 'Array1D(4)': WebGLKernelValueSingleArray1DI,\r\n 'Array2D(2)': WebGLKernelValueSingleArray2DI,\r\n 'Array2D(3)': WebGLKernelValueSingleArray2DI,\r\n 'Array2D(4)': WebGLKernelValueSingleArray2DI,\r\n 'Array3D(2)': WebGLKernelValueSingleArray3DI,\r\n 'Array3D(3)': WebGLKernelValueSingleArray3DI,\r\n 'Array3D(4)': WebGLKernelValueSingleArray3DI,\r\n 'Input': WebGLKernelValueSingleInput,\r\n 'NumberTexture': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueHTMLVideo,\r\n }\r\n },\r\n};\r\n\r\nexport function lookupKernelValueType(type, dynamic, precision, value) {\r\n if (!type) {\r\n throw new Error('type missing');\r\n }\r\n if (!dynamic) {\r\n throw new Error('dynamic missing');\r\n }\r\n if (!precision) {\r\n throw new Error('precision missing');\r\n }\r\n if (value.type) {\r\n type = value.type;\r\n }\r\n const types = kernelValueMaps[precision][dynamic];\r\n if (types[type] === false) {\r\n return null;\r\n } else if (types[type] === undefined) {\r\n throw new Error(`Could not find a KernelValue for ${ type }`);\r\n }\r\n return types[type];\r\n}\r\n","import { GLKernel } from '../gl/kernel';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { WebGLFunctionNode } from './function-node';\r\nimport { utils } from '../../utils';\r\nimport triangleNoise from '../../plugins/triangle-noise';\r\nimport { fragmentShader } from './fragment-shader';\r\nimport { vertexShader } from './vertex-shader';\r\nimport { glKernelString } from '../gl/kernel-string';\r\nimport { lookupKernelValueType } from './kernel-value-maps';\r\n\r\nlet isSupported = null;\r\nlet testCanvas = null;\r\nlet testContext = null;\r\nlet testExtensions = null;\r\nlet features = null;\r\n\r\nconst plugins = [triangleNoise];\r\nconst canvases = [];\r\nconst maxTexSizes = {};\r\n\r\n/**\r\n * @desc Kernel Implementation for WebGL.\r\n *\r\n * This builds the shaders and runs them on the GPU, then outputs the result\r\n * back as float (enabled by default) and Texture.\r\n *\r\n * @prop {Object} textureCache - webGl Texture cache\r\n * @prop {Object} programUniformLocationCache - Location of program variables in memory\r\n * @prop {Object} framebuffer - Webgl frameBuffer\r\n * @prop {Object} buffer - WebGL buffer\r\n * @prop {Object} program - The webGl Program\r\n * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel\r\n * @prop {Boolean} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float\r\n * @prop {String} endianness - Endian information like Little-endian, Big-endian.\r\n * @prop {Array} argumentTypes - Types of parameters sent to the Kernel\r\n * @prop {String} compiledFragmentShader - Compiled fragment shader string\r\n * @prop {String} compiledVertexShader - Compiled Vertical shader string\r\n * @extends GLKernel\r\n */\r\nexport class WebGLKernel extends GLKernel {\r\n static get isSupported() {\r\n if (isSupported !== null) {\r\n return isSupported;\r\n }\r\n this.setupFeatureChecks();\r\n isSupported = this.isContextMatch(testContext);\r\n return isSupported;\r\n }\r\n\r\n static setupFeatureChecks() {\r\n if (typeof document !== 'undefined') {\r\n testCanvas = document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n testCanvas = new OffscreenCanvas(0, 0);\r\n }\r\n if (!testCanvas) return;\r\n testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl');\r\n if (!testContext || !testContext.getExtension) return;\r\n testExtensions = {\r\n OES_texture_float: testContext.getExtension('OES_texture_float'),\r\n OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),\r\n OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),\r\n WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),\r\n };\r\n features = this.getFeatures();\r\n }\r\n\r\n static isContextMatch(context) {\r\n if (typeof WebGLRenderingContext !== 'undefined') {\r\n return context instanceof WebGLRenderingContext;\r\n }\r\n return false;\r\n }\r\n\r\n static getFeatures() {\r\n const isDrawBuffers = this.getIsDrawBuffers();\r\n return Object.freeze({\r\n isFloatRead: this.getIsFloatRead(),\r\n isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),\r\n isTextureFloat: this.getIsTextureFloat(),\r\n isDrawBuffers,\r\n kernelMap: isDrawBuffers,\r\n channelCount: this.getChannelCount(),\r\n });\r\n }\r\n\r\n static getIsTextureFloat() {\r\n return Boolean(testExtensions.OES_texture_float);\r\n }\r\n\r\n static getIsDrawBuffers() {\r\n return Boolean(testExtensions.WEBGL_draw_buffers);\r\n }\r\n\r\n static getChannelCount() {\r\n return testExtensions.WEBGL_draw_buffers ?\r\n testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :\r\n 1;\r\n }\r\n\r\n static lookupKernelValueType(type, dynamic, precision, value) {\r\n return lookupKernelValueType(type, dynamic, precision, value);\r\n }\r\n\r\n static get testCanvas() {\r\n return testCanvas;\r\n }\r\n\r\n static get testContext() {\r\n return testContext;\r\n }\r\n\r\n static get features() {\r\n return features;\r\n }\r\n\r\n static get fragmentShader() {\r\n return fragmentShader;\r\n }\r\n\r\n static get vertexShader() {\r\n return vertexShader;\r\n }\r\n\r\n /**\r\n *\r\n * @param {String} source\r\n * @param {IKernelSettings} settings\r\n */\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.program = null;\r\n this.pipeline = settings.pipeline;\r\n this.endianness = utils.systemEndianness();\r\n this.extensions = {};\r\n this.subKernelOutputTextures = null;\r\n this.kernelArguments = null;\r\n this.argumentTextureCount = 0;\r\n this.constantTextureCount = 0;\r\n this.compiledFragmentShader = null;\r\n this.compiledVertexShader = null;\r\n this.fragShader = null;\r\n this.vertShader = null;\r\n this.drawBuffersMap = null;\r\n this.outputTexture = null;\r\n\r\n /**\r\n *\r\n * @type {Int32Array|null}\r\n */\r\n this.maxTexSize = null;\r\n this.switchingKernels = false;\r\n this.onRequestSwitchKernel = null;\r\n\r\n this.mergeSettings(source.settings || settings);\r\n\r\n /**\r\n * The thread dimensions, x, y and z\r\n * @type {Array|null}\r\n */\r\n this.threadDim = null;\r\n this.framebuffer = null;\r\n this.buffer = null;\r\n this.textureCache = {};\r\n this.programUniformLocationCache = {};\r\n this.uniform1fCache = {};\r\n this.uniform1iCache = {};\r\n this.uniform2fCache = {};\r\n this.uniform2fvCache = {};\r\n this.uniform2ivCache = {};\r\n this.uniform3fvCache = {};\r\n this.uniform3ivCache = {};\r\n this.uniform4fvCache = {};\r\n this.uniform4ivCache = {};\r\n }\r\n\r\n initCanvas() {\r\n if (typeof document !== 'undefined') {\r\n const canvas = document.createElement('canvas');\r\n // Default width and height, to fix webgl issue in safari\r\n canvas.width = 2;\r\n canvas.height = 2;\r\n return canvas;\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n return new OffscreenCanvas(0, 0);\r\n }\r\n }\r\n\r\n initContext() {\r\n const settings = {\r\n alpha: false,\r\n depth: false,\r\n antialias: false\r\n };\r\n return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings);\r\n }\r\n\r\n initPlugins(settings) {\r\n // default plugins\r\n const pluginsToUse = [];\r\n const { source } = this;\r\n if (typeof source === 'string') {\r\n for (let i = 0; i < plugins.length; i++) {\r\n const plugin = plugins[i];\r\n if (source.match(plugin.functionMatch)) {\r\n pluginsToUse.push(plugin);\r\n }\r\n }\r\n } else if (typeof source === 'object') {\r\n // `source` is from object, json\r\n if (settings.pluginNames) { //TODO: in context of JSON support, pluginNames may not exist here\r\n for (let i = 0; i < plugins.length; i++) {\r\n const plugin = plugins[i];\r\n const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name);\r\n if (usePlugin) {\r\n pluginsToUse.push(plugin);\r\n }\r\n }\r\n }\r\n }\r\n return pluginsToUse;\r\n }\r\n\r\n initExtensions() {\r\n this.extensions = {\r\n OES_texture_float: this.context.getExtension('OES_texture_float'),\r\n OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'),\r\n OES_element_index_uint: this.context.getExtension('OES_element_index_uint'),\r\n WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'),\r\n WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.validate) {\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n return;\r\n }\r\n\r\n const { features } = this.constructor;\r\n if (this.optimizeFloatMemory === true && !features.isTextureFloat) {\r\n throw new Error('Float textures are not supported');\r\n } else if (this.precision === 'single' && !features.isFloatRead) {\r\n throw new Error('Single precision not supported');\r\n } else if (!this.graphical && this.precision === null && features.isTextureFloat) {\r\n this.precision = features.isFloatRead ? 'single' : 'unsigned';\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) {\r\n throw new Error('could not instantiate draw buffers extension');\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy === null) {\r\n this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;\r\n } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {\r\n this.fixIntegerDivisionAccuracy = false;\r\n }\r\n\r\n this.checkOutput();\r\n\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n if (argType === 'Array') {\r\n this.output = utils.getDimensions(argType);\r\n } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {\r\n this.output = args[0].output;\r\n } else {\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n\r\n if (this.precision === 'precision') {\r\n this.precision = 'unsigned';\r\n console.warn('Cannot use graphical mode and single precision at the same time');\r\n }\r\n\r\n this.texSize = utils.clone(this.output);\r\n return;\r\n } else if (this.precision === null && features.isTextureFloat) {\r\n this.precision = 'single';\r\n }\r\n\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n\r\n this.checkTextureSize();\r\n }\r\n\r\n updateMaxTexSize() {\r\n const { texSize, canvas } = this;\r\n if (this.maxTexSize === null) {\r\n let canvasIndex = canvases.indexOf(canvas);\r\n if (canvasIndex === -1) {\r\n canvasIndex = canvases.length;\r\n canvases.push(canvas);\r\n maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];\r\n }\r\n this.maxTexSize = maxTexSizes[canvasIndex];\r\n }\r\n if (this.maxTexSize[0] < texSize[0]) {\r\n this.maxTexSize[0] = texSize[0];\r\n }\r\n if (this.maxTexSize[1] < texSize[1]) {\r\n this.maxTexSize[1] = texSize[1];\r\n }\r\n }\r\n\r\n // TODO: move channel checks to new place\r\n _oldtranslateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n\r\n // need this line to automatically get returnType\r\n const translatedSource = functionBuilder.getPrototypeString('kernel');\r\n\r\n if (!this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n let requiredChannels = 0;\r\n const returnTypes = functionBuilder.getReturnTypes();\r\n for (let i = 0; i < returnTypes.length; i++) {\r\n switch (returnTypes[i]) {\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n requiredChannels++;\r\n break;\r\n case 'Array(2)':\r\n requiredChannels += 2;\r\n break;\r\n case 'Array(3)':\r\n requiredChannels += 3;\r\n break;\r\n case 'Array(4)':\r\n requiredChannels += 4;\r\n break;\r\n }\r\n }\r\n\r\n if (features && requiredChannels > features.channelCount) {\r\n throw new Error('Too many channels!');\r\n }\r\n\r\n return this.translatedSource = translatedSource;\r\n }\r\n\r\n setupArguments(args) {\r\n this.kernelArguments = [];\r\n this.argumentTextureCount = 0;\r\n const needsArgumentTypes = this.argumentTypes === null;\r\n // TODO: remove\r\n if (needsArgumentTypes) {\r\n this.argumentTypes = [];\r\n }\r\n this.argumentSizes = [];\r\n this.argumentBitRatios = [];\r\n // TODO: end remove\r\n\r\n if (args.length < this.argumentNames.length) {\r\n throw new Error('not enough arguments for kernel');\r\n } else if (args.length > this.argumentNames.length) {\r\n throw new Error('too many arguments for kernel');\r\n }\r\n\r\n const { context: gl } = this;\r\n let textureIndexes = 0;\r\n for (let index = 0; index < args.length; index++) {\r\n const value = args[index];\r\n const name = this.argumentNames[index];\r\n let type;\r\n if (needsArgumentTypes) {\r\n type = utils.getVariableType(value, this.strictIntegers);\r\n this.argumentTypes.push(type);\r\n } else {\r\n type = this.argumentTypes[index];\r\n }\r\n const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]);\r\n if (KernelValue === null) {\r\n return this.requestFallback(args);\r\n }\r\n const kernelArgument = new KernelValue(value, {\r\n name,\r\n type,\r\n tactic: this.tactic,\r\n origin: 'user',\r\n context: gl,\r\n checkContext: this.checkContext,\r\n kernel: this,\r\n strictIntegers: this.strictIntegers,\r\n onRequestTexture: () => {\r\n return this.context.createTexture();\r\n },\r\n onRequestIndex: () => {\r\n return textureIndexes++;\r\n },\r\n onUpdateValueMismatch: () => {\r\n this.switchingKernels = true;\r\n },\r\n onRequestContextHandle: () => {\r\n return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++;\r\n }\r\n });\r\n this.kernelArguments.push(kernelArgument);\r\n this.argumentSizes.push(kernelArgument.textureSize);\r\n this.argumentBitRatios[index] = kernelArgument.bitRatio;\r\n }\r\n }\r\n\r\n setupConstants(args) {\r\n const { context: gl } = this;\r\n this.kernelConstants = [];\r\n this.forceUploadKernelConstants = [];\r\n let needsConstantTypes = this.constantTypes === null;\r\n if (needsConstantTypes) {\r\n this.constantTypes = {};\r\n }\r\n this.constantBitRatios = {};\r\n let textureIndexes = 0;\r\n for (const name in this.constants) {\r\n const value = this.constants[name];\r\n let type;\r\n if (needsConstantTypes) {\r\n type = utils.getVariableType(value, this.strictIntegers);\r\n this.constantTypes[name] = type;\r\n } else {\r\n type = this.constantTypes[name];\r\n }\r\n const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value);\r\n if (KernelValue === null) {\r\n return this.requestFallback(args);\r\n }\r\n const kernelValue = new KernelValue(value, {\r\n name,\r\n type,\r\n tactic: this.tactic,\r\n origin: 'constants',\r\n context: this.context,\r\n checkContext: this.checkContext,\r\n kernel: this,\r\n strictIntegers: this.strictIntegers,\r\n onRequestTexture: () => {\r\n return this.context.createTexture();\r\n },\r\n onRequestIndex: () => {\r\n return textureIndexes++;\r\n },\r\n onRequestContextHandle: () => {\r\n return gl.TEXTURE0 + this.constantTextureCount++;\r\n }\r\n });\r\n this.constantBitRatios[name] = kernelValue.bitRatio;\r\n this.kernelConstants.push(kernelValue);\r\n if (kernelValue.forceUploadEachRun) {\r\n this.forceUploadKernelConstants.push(kernelValue);\r\n }\r\n }\r\n }\r\n\r\n build() {\r\n this.initExtensions();\r\n this.validateSettings(arguments);\r\n this.setupConstants(arguments);\r\n if (this.fallbackRequested) return;\r\n this.setupArguments(arguments);\r\n if (this.fallbackRequested) return;\r\n this.updateMaxTexSize();\r\n this.translateSource();\r\n const failureResult = this.pickRenderStrategy(arguments);\r\n if (failureResult) {\r\n return failureResult;\r\n }\r\n const { texSize, context: gl, canvas } = this;\r\n gl.enable(gl.SCISSOR_TEST);\r\n if (this.pipeline && this.precision === 'single') {\r\n gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n canvas.width = this.maxTexSize[0];\r\n canvas.height = this.maxTexSize[1];\r\n } else {\r\n gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n canvas.width = this.maxTexSize[0];\r\n canvas.height = this.maxTexSize[1];\r\n }\r\n const threadDim = this.threadDim = Array.from(this.output);\r\n while (threadDim.length < 3) {\r\n threadDim.push(1);\r\n }\r\n\r\n const compiledVertexShader = this.getVertexShader(arguments);\r\n const vertShader = gl.createShader(gl.VERTEX_SHADER);\r\n gl.shaderSource(vertShader, compiledVertexShader);\r\n gl.compileShader(vertShader);\r\n this.vertShader = vertShader;\r\n\r\n const compiledFragmentShader = this.getFragmentShader(arguments);\r\n const fragShader = gl.createShader(gl.FRAGMENT_SHADER);\r\n gl.shaderSource(fragShader, compiledFragmentShader);\r\n gl.compileShader(fragShader);\r\n this.fragShader = fragShader;\r\n\r\n if (this.debug) {\r\n console.log('GLSL Shader Output:');\r\n console.log(compiledFragmentShader);\r\n }\r\n\r\n if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {\r\n throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader));\r\n }\r\n if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {\r\n throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader));\r\n }\r\n\r\n const program = this.program = gl.createProgram();\r\n gl.attachShader(program, vertShader);\r\n gl.attachShader(program, fragShader);\r\n gl.linkProgram(program);\r\n this.framebuffer = gl.createFramebuffer();\r\n this.framebuffer.width = texSize[0];\r\n this.framebuffer.height = texSize[1];\r\n\r\n const vertices = new Float32Array([-1, -1,\r\n 1, -1, -1, 1,\r\n 1, 1\r\n ]);\r\n const texCoords = new Float32Array([\r\n 0, 0,\r\n 1, 0,\r\n 0, 1,\r\n 1, 1\r\n ]);\r\n\r\n const texCoordOffset = vertices.byteLength;\r\n\r\n let buffer = this.buffer;\r\n if (!buffer) {\r\n buffer = this.buffer = gl.createBuffer();\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);\r\n } else {\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\r\n }\r\n\r\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);\r\n gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);\r\n\r\n const aPosLoc = gl.getAttribLocation(this.program, 'aPos');\r\n gl.enableVertexAttribArray(aPosLoc);\r\n gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0);\r\n const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');\r\n gl.enableVertexAttribArray(aTexCoordLoc);\r\n gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n\r\n let i = 0;\r\n gl.useProgram(this.program);\r\n for (let p in this.constants) {\r\n this.kernelConstants[i++].updateValue(this.constants[p]);\r\n }\r\n\r\n if (!this.immutable) {\r\n this._setupOutputTexture();\r\n if (\r\n this.subKernels !== null &&\r\n this.subKernels.length > 0\r\n ) {\r\n this._setupSubOutputTextures();\r\n }\r\n }\r\n }\r\n\r\n translateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n this.translatedSource = functionBuilder.getPrototypeString('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (!subKernel.returnType) {\r\n subKernel.returnType = functionBuilder.getSubKernelResultType(i);\r\n }\r\n }\r\n }\r\n }\r\n\r\n run() {\r\n const { kernelArguments, forceUploadKernelConstants } = this;\r\n const texSize = this.texSize;\r\n const gl = this.context;\r\n\r\n gl.useProgram(this.program);\r\n gl.scissor(0, 0, texSize[0], texSize[1]);\r\n\r\n if (this.dynamicOutput) {\r\n this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));\r\n this.setUniform2iv('uTexSize', texSize);\r\n }\r\n\r\n this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);\r\n\r\n this.switchingKernels = false;\r\n for (let i = 0; i < forceUploadKernelConstants.length; i++) {\r\n const constant = forceUploadKernelConstants[i];\r\n constant.updateValue(this.constants[constant.name]);\r\n if (this.switchingKernels) return;\r\n }\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n kernelArguments[i].updateValue(arguments[i]);\r\n if (this.switchingKernels) return;\r\n }\r\n\r\n if (this.plugins) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.onBeforeRun) {\r\n plugin.onBeforeRun(this);\r\n }\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.pipeline) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (!this.outputTexture || this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return;\r\n }\r\n\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n\r\n if (this.subKernels !== null) {\r\n if (this.immutable) {\r\n this._setupSubOutputTextures();\r\n }\r\n this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap);\r\n }\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n }\r\n\r\n /**\r\n * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run()\r\n * @returns {Object} Output Texture Cache\r\n */\r\n getOutputTexture() {\r\n return this.outputTexture;\r\n }\r\n\r\n /**\r\n * @desc Setup and replace output texture\r\n */\r\n _setupOutputTexture() {\r\n const gl = this.context;\r\n const texSize = this.texSize;\r\n const texture = this.outputTexture = this.context.createTexture();\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // if (this.precision === 'single') {\r\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n // } else {\r\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n // }\r\n if (this.precision === 'single') {\r\n if (this.pipeline) {\r\n // TODO: investigate if webgl1 can handle gl.RED usage in gl.texImage2D, otherwise, simplify the below\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n }\r\n break;\r\n case 'Array(2)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n case 'Array(3)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n case 'Array(4)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n default:\r\n if (!this.graphical) {\r\n throw new Error('Unhandled return type');\r\n }\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n }\r\n\r\n /**\r\n * @desc Setup and replace sub-output textures\r\n */\r\n _setupSubOutputTextures() {\r\n const gl = this.context;\r\n const texSize = this.texSize;\r\n this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];\r\n this.subKernelOutputTextures = [];\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const texture = this.context.createTexture();\r\n this.subKernelOutputTextures.push(texture);\r\n this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n if (this.precision === 'single') {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);\r\n }\r\n }\r\n\r\n /**\r\n * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument)\r\n * @param {String} name - Name of the subkernel, argument, or kernel.\r\n * @returns {Object} Texture cache\r\n */\r\n getTextureCache(name) {\r\n if (this.textureCache.hasOwnProperty(name)) {\r\n return this.textureCache[name];\r\n }\r\n return this.textureCache[name] = this.context.createTexture();\r\n }\r\n\r\n /**\r\n * @desc removes a texture from the kernel's cache\r\n * @param {String} name - Name of texture\r\n */\r\n detachTextureCache(name) {\r\n delete this.textureCache[name];\r\n }\r\n\r\n setUniform1f(name, value) {\r\n if (this.uniform1fCache.hasOwnProperty(name)) {\r\n const cache = this.uniform1fCache[name];\r\n if (value === cache) {\r\n return;\r\n }\r\n }\r\n this.uniform1fCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform1f(loc, value);\r\n }\r\n\r\n setUniform1i(name, value) {\r\n if (this.uniform1iCache.hasOwnProperty(name)) {\r\n const cache = this.uniform1iCache[name];\r\n if (value === cache) {\r\n return;\r\n }\r\n }\r\n this.uniform1iCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform1i(loc, value);\r\n }\r\n\r\n setUniform2f(name, value1, value2) {\r\n if (this.uniform2fCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2fCache[name];\r\n if (\r\n value1 === cache[0] &&\r\n value2 === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2fCache[name] = [value1, value2];\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2f(loc, value1, value2);\r\n }\r\n\r\n setUniform2fv(name, value) {\r\n if (this.uniform2fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2fv(loc, value);\r\n }\r\n\r\n setUniform2iv(name, value) {\r\n if (this.uniform2ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2iv(loc, value);\r\n }\r\n\r\n setUniform3fv(name, value) {\r\n if (this.uniform3fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3fv(loc, value);\r\n }\r\n\r\n setUniform3iv(name, value) {\r\n if (this.uniform3ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3iv(loc, value);\r\n }\r\n\r\n setUniform3fv(name, value) {\r\n if (this.uniform3fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3fv(loc, value);\r\n }\r\n\r\n setUniform4iv(name, value) {\r\n if (this.uniform4ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform4ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2] &&\r\n value[3] === cache[3]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform4ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform4iv(loc, value);\r\n }\r\n\r\n setUniform4fv(name, value) {\r\n if (this.uniform4fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform4fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2] &&\r\n value[3] === cache[3]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform4fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform4fv(loc, value);\r\n }\r\n\r\n /**\r\n * @desc Return WebGlUniformLocation for various variables\r\n * related to webGl program, such as user-defined variables,\r\n * as well as, dimension sizes, etc.\r\n */\r\n getUniformLocation(name) {\r\n if (this.programUniformLocationCache.hasOwnProperty(name)) {\r\n return this.programUniformLocationCache[name];\r\n }\r\n return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name);\r\n }\r\n\r\n /**\r\n * @desc Generate Shader artifacts for the kernel program.\r\n * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)\r\n */\r\n _getFragShaderArtifactMap(args) {\r\n return {\r\n HEADER: this._getHeaderString(),\r\n LOOP_MAX: this._getLoopMaxString(),\r\n PLUGINS: this._getPluginsString(),\r\n CONSTANTS: this._getConstantsString(),\r\n DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),\r\n ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),\r\n DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(),\r\n INJECTED_NATIVE: this._getInjectedNative(),\r\n MAIN_CONSTANTS: this._getMainConstantsString(),\r\n MAIN_ARGUMENTS: this._getMainArgumentsString(args),\r\n KERNEL: this.getKernelString(),\r\n MAIN_RESULT: this.getMainResultString(),\r\n FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),\r\n INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),\r\n SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),\r\n SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Generate Shader artifacts for the kernel program.\r\n * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)\r\n */\r\n _getVertShaderArtifactMap(args) {\r\n return {\r\n FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),\r\n INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),\r\n SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),\r\n SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Get the header string for the program.\r\n * This returns an empty string if no sub-kernels are defined.\r\n *\r\n * @returns {String} result\r\n */\r\n _getHeaderString() {\r\n return (\r\n this.subKernels !== null ?\r\n '#extension GL_EXT_draw_buffers : require\\n' :\r\n ''\r\n );\r\n }\r\n\r\n /**\r\n * @desc Get the maximum loop size String.\r\n * @returns {String} result\r\n */\r\n _getLoopMaxString() {\r\n return (\r\n this.loopMaxIterations ?\r\n ` ${parseInt(this.loopMaxIterations)};\\n` :\r\n ' 1000;\\n'\r\n );\r\n }\r\n\r\n _getPluginsString() {\r\n if (!this.plugins) return '\\n';\r\n return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel\r\n * @returns {String} result\r\n */\r\n _getConstantsString() {\r\n const result = [];\r\n const { threadDim, texSize } = this;\r\n if (this.dynamicOutput) {\r\n result.push(\r\n 'uniform ivec3 uOutputDim',\r\n 'uniform ivec2 uTexSize'\r\n );\r\n } else {\r\n result.push(\r\n `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,\r\n `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`\r\n );\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n /**\r\n * @desc Get texture coordinate string for the program\r\n * @returns {String} result\r\n */\r\n _getTextureCoordinate() {\r\n const subKernels = this.subKernels;\r\n if (subKernels === null || subKernels.length < 1) {\r\n return 'varying vec2 vTexCoord;\\n';\r\n } else {\r\n return 'out vec2 vTexCoord;\\n';\r\n }\r\n }\r\n\r\n /**\r\n * @desc Get Decode32 endianness string for little-endian and big-endian\r\n * @returns {String} result\r\n */\r\n _getDecode32EndiannessString() {\r\n return (\r\n this.endianness === 'LE' ?\r\n '' :\r\n ' texel.rgba = texel.abgr;\\n'\r\n );\r\n }\r\n\r\n /**\r\n * @desc Get Encode32 endianness string for little-endian and big-endian\r\n * @returns {String} result\r\n */\r\n _getEncode32EndiannessString() {\r\n return (\r\n this.endianness === 'LE' ?\r\n '' :\r\n ' texel.rgba = texel.abgr;\\n'\r\n );\r\n }\r\n\r\n /**\r\n * @desc if fixIntegerDivisionAccuracy provide method to replace /\r\n * @returns {String} result\r\n */\r\n _getDivideWithIntegerCheckString() {\r\n return this.fixIntegerDivisionAccuracy ?\r\n `float div_with_int_check(float x, float y) {\r\n if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\r\n return float(int(x)/int(y));\r\n }\r\n return x / y;\r\n}` :\r\n '';\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {String} result\r\n */\r\n _getMainArgumentsString(args) {\r\n const results = [];\r\n const { argumentNames } = this;\r\n for (let i = 0; i < argumentNames.length; i++) {\r\n results.push(this.kernelArguments[i].getSource(args[i]));\r\n }\r\n return results.join('');\r\n }\r\n\r\n _getInjectedNative() {\r\n return this.injectedNative || '';\r\n }\r\n\r\n _getMainConstantsString() {\r\n const result = [];\r\n const { constants } = this;\r\n if (constants) {\r\n let i = 0;\r\n for (const name in constants) {\r\n result.push(this.kernelConstants[i++].getSource(this.constants[name]));\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * @desc Get Kernel program string (in *glsl*) for a kernel.\r\n * @returns {String} result\r\n */\r\n getKernelString() {\r\n let kernelResultDeclaration;\r\n switch (this.returnType) {\r\n case 'Array(2)':\r\n kernelResultDeclaration = 'vec2 kernelResult';\r\n break;\r\n case 'Array(3)':\r\n kernelResultDeclaration = 'vec3 kernelResult';\r\n break;\r\n case 'Array(4)':\r\n kernelResultDeclaration = 'vec4 kernelResult';\r\n break;\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n kernelResultDeclaration = 'float kernelResult';\r\n break;\r\n default:\r\n if (this.graphical) {\r\n kernelResultDeclaration = 'float kernelResult';\r\n } else {\r\n throw new Error(`unrecognized output type \"${ this.returnType }\"`);\r\n }\r\n }\r\n\r\n const result = [];\r\n const subKernels = this.subKernels;\r\n if (subKernels !== null) {\r\n result.push(\r\n kernelResultDeclaration\r\n );\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const subKernel = subKernels[i];\r\n result.push(\r\n subKernel.returnType === 'Integer' ?\r\n `int subKernelResult_${ subKernel.name } = 0` :\r\n `float subKernelResult_${ subKernel.name } = 0.0`\r\n );\r\n }\r\n break;\r\n case 'Array(2)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec2 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n case 'Array(3)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec3 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n case 'Array(4)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec4 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n }\r\n } else {\r\n result.push(\r\n kernelResultDeclaration\r\n );\r\n }\r\n\r\n return utils.linesToString(result) + this.translatedSource;\r\n }\r\n\r\n getMainResultGraphical() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragColor = actualColor',\r\n ]);\r\n }\r\n\r\n getMainResultPackedPixels() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return this.getMainResultKernelPackedPixels() +\r\n this.getMainResultSubKernelPackedPixels();\r\n default:\r\n throw new Error(`packed output only usable with Numbers, \"${this.returnType}\" specified`);\r\n }\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultKernelPackedPixels() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`\r\n ]);\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultSubKernelPackedPixels() {\r\n const result = [];\r\n if (!this.subKernels) return '';\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`\r\n );\r\n }\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultMemoryOptimizedFloats() {\r\n const result = [\r\n ' index *= 4',\r\n ];\r\n\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n const channels = ['r', 'g', 'b', 'a'];\r\n for (let i = 0; i < channels.length; i++) {\r\n const channel = channels[i];\r\n this.getMainResultKernelMemoryOptimizedFloats(result, channel);\r\n this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);\r\n if (i + 1 < channels.length) {\r\n result.push(' index += 1');\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);\r\n }\r\n\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultKernelMemoryOptimizedFloats(result, channel) {\r\n result.push(\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` gl_FragData[0].${channel} = kernelResult`,\r\n );\r\n }\r\n\r\n getMainResultSubKernelMemoryOptimizedFloats(result, channel) {\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n getMainResultKernelNumberTexture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelNumberTexture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray2Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult[0]',\r\n ' gl_FragData[0][1] = kernelResult[1]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray2Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray3Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult[0]',\r\n ' gl_FragData[0][1] = kernelResult[1]',\r\n ' gl_FragData[0][2] = kernelResult[2]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray3Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray4Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray4Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n }\r\n break;\r\n case 'Array(2)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n );\r\n }\r\n break;\r\n case 'Array(3)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n );\r\n }\r\n break;\r\n case 'Array(4)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`,\r\n );\r\n }\r\n break;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * @param {String} src - Shader string\r\n * @param {Object} map - Variables/Constants associated with shader\r\n */\r\n replaceArtifacts(src, map) {\r\n return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\\n/g, (match, artifact) => {\r\n if (map.hasOwnProperty(artifact)) {\r\n return map[artifact];\r\n }\r\n throw `unhandled artifact ${artifact}`;\r\n });\r\n }\r\n\r\n /**\r\n * @desc Get the fragment shader String.\r\n * If the String hasn't been compiled yet,\r\n * then this method compiles it as well\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {string} Fragment Shader string\r\n */\r\n getFragmentShader(args) {\r\n if (this.compiledFragmentShader !== null) {\r\n return this.compiledFragmentShader;\r\n }\r\n return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args));\r\n }\r\n\r\n /**\r\n * @desc Get the vertical shader String\r\n * @param {Array|IArguments} args - The actual parameters sent to the Kernel\r\n * @returns {string} Vertical Shader string\r\n */\r\n getVertexShader(args) {\r\n if (this.compiledVertexShader !== null) {\r\n return this.compiledVertexShader;\r\n }\r\n return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args));\r\n }\r\n\r\n /**\r\n * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.\r\n */\r\n toString() {\r\n const setupContextString = utils.linesToString([\r\n `const gl = context`,\r\n ]);\r\n return glKernelString(this.constructor, arguments, this, setupContextString);\r\n }\r\n\r\n destroy(removeCanvasReferences) {\r\n if (this.outputTexture) {\r\n this.context.deleteTexture(this.outputTexture);\r\n }\r\n if (this.buffer) {\r\n this.context.deleteBuffer(this.buffer);\r\n }\r\n if (this.framebuffer) {\r\n this.context.deleteFramebuffer(this.framebuffer);\r\n }\r\n if (this.vertShader) {\r\n this.context.deleteShader(this.vertShader);\r\n }\r\n if (this.fragShader) {\r\n this.context.deleteShader(this.fragShader);\r\n }\r\n if (this.program) {\r\n this.context.deleteProgram(this.program);\r\n }\r\n\r\n const keys = Object.keys(this.textureCache);\r\n\r\n for (let i = 0; i < keys.length; i++) {\r\n const name = keys[i];\r\n this.context.deleteTexture(this.textureCache[name]);\r\n }\r\n\r\n if (this.subKernelOutputTextures) {\r\n for (let i = 0; i < this.subKernelOutputTextures.length; i++) {\r\n this.context.deleteTexture(this.subKernelOutputTextures[i]);\r\n }\r\n }\r\n if (removeCanvasReferences) {\r\n const idx = canvases.indexOf(this.canvas);\r\n if (idx >= 0) {\r\n canvases[idx] = null;\r\n maxTexSizes[idx] = null;\r\n }\r\n }\r\n this.destroyExtensions();\r\n delete this.context;\r\n delete this.canvas;\r\n }\r\n\r\n destroyExtensions() {\r\n this.extensions.OES_texture_float = null;\r\n this.extensions.OES_texture_float_linear = null;\r\n this.extensions.OES_element_index_uint = null;\r\n this.extensions.WEBGL_draw_buffers = null;\r\n }\r\n\r\n static destroyContext(context) {\r\n const extension = context.getExtension('WEBGL_lose_context');\r\n if (extension) {\r\n extension.loseContext();\r\n }\r\n }\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON();\r\n return json;\r\n }\r\n}\r\n","import { WebGLFunctionNode } from '../web-gl/function-node';\r\n\r\n/**\r\n * @class WebGL2FunctionNode\r\n * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective webGL code.\r\n * @extends WebGLFunctionNode\r\n * @returns the converted webGL function string\r\n */\r\nexport class WebGL2FunctionNode extends WebGLFunctionNode {\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput(\r\n 'IdentifierExpression - not an Identifier',\r\n idtNode\r\n );\r\n }\r\n\r\n const type = this.getType(idtNode);\r\n\r\n if (idtNode.name === 'Infinity') {\r\n retArr.push('intBitsToFloat(2139095039)');\r\n } else if (type === 'Boolean') {\r\n if (this.argumentNames.indexOf(idtNode.name) > -1) {\r\n retArr.push(`bool(user_${idtNode.name})`);\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n\r\n return retArr;\r\n }\r\n}\r\n","// language=GLSL\r\nexport const fragmentShader = `#version 300 es\r\n__HEADER__;\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\r\n\r\nconst int LOOP_MAX = __LOOP_MAX__;\r\n\r\n__PLUGINS__;\r\n__CONSTANTS__;\r\n\r\nin vec2 vTexCoord;\r\n\r\nconst int BIT_COUNT = 32;\r\nint modi(int x, int y) {\r\n return x - y * (x / y);\r\n}\r\n\r\nint bitwiseOr(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseXOR(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseAnd(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 && b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseNot(int a) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (modi(a, 2) == 0) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n n = n * 2;\r\n }\r\n return result;\r\n}\r\nint bitwiseZeroFillLeftShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n *= 2;\r\n }\r\n\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nint bitwiseSignedRightShift(int num, int shifts) {\r\n return int(floor(float(num) / pow(2.0, float(shifts))));\r\n}\r\n\r\nint bitwiseZeroFillRightShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n /= 2;\r\n }\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nvec2 integerMod(vec2 x, float y) {\r\n vec2 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec3 integerMod(vec3 x, float y) {\r\n vec3 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec4 integerMod(vec4 x, vec4 y) {\r\n vec4 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nfloat integerMod(float x, float y) {\r\n float res = floor(mod(x, y));\r\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\r\n}\r\n\r\nint integerMod(int x, int y) {\r\n return x - (y * int(x/y));\r\n}\r\n\r\n__DIVIDE_WITH_INTEGER_CHECK__;\r\n\r\n// Here be dragons!\r\n// DO NOT OPTIMIZE THIS CODE\r\n// YOU WILL BREAK SOMETHING ON SOMEBODY\\'S MACHINE\r\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\r\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\r\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\r\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\r\nfloat decode32(vec4 texel) {\r\n __DECODE32_ENDIANNESS__;\r\n texel *= 255.0;\r\n vec2 gte128;\r\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\r\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\r\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\r\n float res = exp2(round(exponent));\r\n texel.b = texel.b - 128.0 * gte128.x;\r\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\r\n res *= gte128.y * -2.0 + 1.0;\r\n return res;\r\n}\r\n\r\nfloat decode16(vec4 texel, int index) {\r\n int channel = integerMod(index, 2);\r\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\r\n}\r\n\r\nfloat decode8(vec4 texel, int index) {\r\n int channel = integerMod(index, 4);\r\n return texel[channel] * 255.0;\r\n}\r\n\r\nvec4 legacyEncode32(float f) {\r\n float F = abs(f);\r\n float sign = f < 0.0 ? 1.0 : 0.0;\r\n float exponent = floor(log2(F));\r\n float mantissa = (exp2(-exponent) * F);\r\n // exponent += floor(log2(mantissa));\r\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\r\n texel.rg = integerMod(texel.rg, 256.0);\r\n texel.b = integerMod(texel.b, 128.0);\r\n texel.a = exponent*0.5 + 63.5;\r\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\r\n texel = floor(texel);\r\n texel *= 0.003921569; // 1/255\r\n __ENCODE32_ENDIANNESS__;\r\n return texel;\r\n}\r\n\r\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\r\nvec4 encode32(float value) {\r\n if (value == 0.0) return vec4(0, 0, 0, 0);\r\n\r\n float exponent;\r\n float mantissa;\r\n vec4 result;\r\n float sgn;\r\n\r\n sgn = step(0.0, -value);\r\n value = abs(value);\r\n\r\n exponent = floor(log2(value));\r\n\r\n mantissa = value*pow(2.0, -exponent)-1.0;\r\n exponent = exponent+127.0;\r\n result = vec4(0,0,0,0);\r\n\r\n result.a = floor(exponent/2.0);\r\n exponent = exponent - result.a*2.0;\r\n result.a = result.a + 128.0*sgn;\r\n\r\n result.b = floor(mantissa * 128.0);\r\n mantissa = mantissa - result.b / 128.0;\r\n result.b = result.b + exponent*128.0;\r\n\r\n result.g = floor(mantissa*32768.0);\r\n mantissa = mantissa - result.g/32768.0;\r\n\r\n result.r = floor(mantissa*8388608.0);\r\n return result/255.0;\r\n}\r\n// Dragons end here\r\n\r\nint index;\r\nivec3 threadId;\r\n\r\nivec3 indexTo3D(int idx, ivec3 texDim) {\r\n int z = int(idx / (texDim.x * texDim.y));\r\n idx -= z * int(texDim.x * texDim.y);\r\n int y = int(idx / texDim.x);\r\n int x = int(integerMod(idx, texDim.x));\r\n return ivec3(x, y, z);\r\n}\r\n\r\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return decode32(texel);\r\n}\r\n\r\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int w = texSize.x * 2;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\r\n return decode16(texel, index);\r\n}\r\n\r\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int w = texSize.x * 4;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\r\n return decode8(texel, index);\r\n}\r\n\r\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int channel = integerMod(index, 4);\r\n index = index / 4;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n index = index / 4;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return texel[channel];\r\n}\r\n\r\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture(tex, st / vec2(texSize));\r\n}\r\n\r\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture(tex, vec3(st / vec2(texSize), z));\r\n}\r\n\r\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return result[0];\r\n}\r\n\r\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec2(result[0], result[1]);\r\n}\r\n\r\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n index = index / 2;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n if (channel == 0) return vec2(texel.r, texel.g);\r\n if (channel == 1) return vec2(texel.b, texel.a);\r\n return vec2(0.0, 0.0);\r\n}\r\n\r\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec3(result[0], result[1], result[2]);\r\n}\r\n\r\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\r\n int vectorIndex = fieldIndex / 4;\r\n int vectorOffset = fieldIndex - vectorIndex * 4;\r\n int readY = vectorIndex / texSize.x;\r\n int readX = vectorIndex - readY * texSize.x;\r\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\r\n\r\n if (vectorOffset == 0) {\r\n return tex1.xyz;\r\n } else if (vectorOffset == 1) {\r\n return tex1.yzw;\r\n } else {\r\n readX++;\r\n if (readX >= texSize.x) {\r\n readX = 0;\r\n readY++;\r\n }\r\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\r\n if (vectorOffset == 2) {\r\n return vec3(tex1.z, tex1.w, tex2.x);\r\n } else {\r\n return vec3(tex1.w, tex2.x, tex2.y);\r\n }\r\n }\r\n}\r\n\r\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n return getImage2D(tex, texSize, texDim, z, y, x);\r\n}\r\n\r\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return vec4(texel.r, texel.g, texel.b, texel.a);\r\n}\r\n\r\nvec4 actualColor;\r\nvoid color(float r, float g, float b, float a) {\r\n actualColor = vec4(r,g,b,a);\r\n}\r\n\r\nvoid color(float r, float g, float b) {\r\n color(r,g,b,1.0);\r\n}\r\n\r\n__INJECTED_NATIVE__;\r\n__MAIN_CONSTANTS__;\r\n__MAIN_ARGUMENTS__;\r\n__KERNEL__;\r\n\r\nvoid main(void) {\r\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\r\n __MAIN_RESULT__;\r\n}`;\r\n","// language=GLSL\r\nexport const vertexShader = `#version 300 es\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nin vec2 aPos;\r\nin vec2 aTexCoord;\r\n\r\nout vec2 vTexCoord;\r\nuniform vec2 ratio;\r\n\r\nvoid main(void) {\r\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\r\n vTexCoord = aTexCoord;\r\n}`;\r\n","import { WebGLKernelValueBoolean } from '../../web-gl/kernel-value/boolean';\r\n\r\nexport class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {}\r\n","import { WebGLKernelValueFloat } from '../../web-gl/kernel-value/float';\r\n\r\nexport class WebGL2KernelValueFloat extends WebGLKernelValueFloat {}\r\n","import { WebGLKernelValueInteger } from '../../web-gl/kernel-value/integer';\r\n\r\nexport class WebGL2KernelValueInteger extends WebGLKernelValueInteger {\r\n getSource(value) {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n if (this.origin === 'constants') {\r\n return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\\n`;\r\n }\r\n return `uniform ${ variablePrecision } int ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueHTMLImage } from '../../web-gl/kernel-value/html-image';\r\n\r\nexport class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicHTMLImage } from '../../web-gl/kernel-value/dynamic-html-image';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from '../../web-gl/kernel-value/index';\r\n\r\nexport class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.checkSize(value[0].width, value[0].height);\r\n this.requestTexture();\r\n this.dimensions = [value[0].width, value[0].height, value.length];\r\n this.textureSize = [value[0].width, value[0].height];\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2DArray ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(images) {\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\r\n // Upload the images into the texture.\r\n gl.texImage3D(\r\n gl.TEXTURE_2D_ARRAY,\r\n 0,\r\n gl.RGBA,\r\n images[0].width,\r\n images[0].height,\r\n images.length,\r\n 0,\r\n gl.RGBA,\r\n gl.UNSIGNED_BYTE,\r\n null\r\n );\r\n for (let i = 0; i < images.length; i++) {\r\n const xOffset = 0;\r\n const yOffset = 0;\r\n const imageDepth = 1;\r\n gl.texSubImage3D(\r\n gl.TEXTURE_2D_ARRAY,\r\n 0,\r\n xOffset,\r\n yOffset,\r\n i,\r\n images[i].width,\r\n images[i].height,\r\n imageDepth,\r\n gl.RGBA,\r\n gl.UNSIGNED_BYTE,\r\n this.uploadValue = images[i]\r\n );\r\n }\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { WebGL2KernelValueHTMLImageArray } from './html-image-array';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2DArray ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(images) {\r\n const { width, height } = images[0];\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, images.length];\r\n this.textureSize = [width, height];\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(images);\r\n }\r\n}\r\n","import { WebGL2KernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {}\r\n","import { WebGL2KernelValueDynamicHTMLImage } from './dynamic-html-image';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleInput } from '../../web-gl/kernel-value/single-input';\r\n\r\nexport class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleInput } from '../../web-gl2/kernel-value/single-input';\r\n\r\nexport class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedInput } from '../../web-gl/kernel-value/unsigned-input';\r\n\r\nexport class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicUnsignedInput } from '../../web-gl/kernel-value/dynamic-unsigned-input';\r\n\r\nexport class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/memory-optimized-number-texture';\r\n\r\nexport class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {\r\n getSource() {\r\n const { id, sizeId, textureSize, dimensionsId, dimensions } = this;\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform sampler2D ${id}`,\r\n `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nexport class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueNumberTexture } from '../../web-gl/kernel-value/number-texture';\r\n\r\nexport class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture {\r\n getSource() {\r\n const { id, sizeId, textureSize, dimensionsId, dimensions } = this;\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${id}`,\r\n `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicNumberTexture } from '../../web-gl/kernel-value/dynamic-number-texture';\r\n\r\nexport class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray } from '../../web-gl/kernel-value/single-array';\r\n\r\nexport class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray } from '../../web-gl2/kernel-value/single-array';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray1DI } from '../../web-gl/kernel-value/single-array1d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray1DI } from '../../web-gl2/kernel-value/single-array1d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray2DI } from '../../web-gl/kernel-value/single-array2d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray2DI } from '../../web-gl2/kernel-value/single-array2d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray3DI } from '../../web-gl/kernel-value/single-array3d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray3DI } from '../../web-gl2/kernel-value/single-array3d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueSingleArray2 } from '../../web-gl/kernel-value/single-array2';\r\n\r\nexport class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {}\r\n","import { WebGLKernelValueSingleArray3 } from '../../web-gl/kernel-value/single-array3';\r\n\r\nexport class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {}\r\n","import { WebGLKernelValueSingleArray4 } from '../../web-gl/kernel-value/single-array4';\r\n\r\nexport class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedArray } from '../../web-gl/kernel-value/unsigned-array';\r\n\r\nexport class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicUnsignedArray } from '../../web-gl/kernel-value/dynamic-unsigned-array';\r\n\r\nexport class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { WebGL2KernelValueBoolean } from './kernel-value/boolean';\r\nimport { WebGL2KernelValueFloat } from './kernel-value/float';\r\nimport { WebGL2KernelValueInteger } from './kernel-value/integer';\r\n\r\nimport { WebGL2KernelValueHTMLImage } from './kernel-value/html-image';\r\nimport { WebGL2KernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image';\r\n\r\nimport { WebGL2KernelValueHTMLImageArray } from './kernel-value/html-image-array';\r\nimport { WebGL2KernelValueDynamicHTMLImageArray } from './kernel-value/dynamic-html-image-array';\r\n\r\nimport { WebGL2KernelValueHTMLVideo } from './kernel-value/html-video';\r\nimport { WebGL2KernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video';\r\n\r\nimport { WebGL2KernelValueSingleInput } from './kernel-value/single-input';\r\nimport { WebGL2KernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input';\r\n\r\nimport { WebGL2KernelValueUnsignedInput } from './kernel-value/unsigned-input';\r\nimport { WebGL2KernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input';\r\n\r\nimport { WebGL2KernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture';\r\nimport { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nimport { WebGL2KernelValueNumberTexture } from './kernel-value/number-texture';\r\nimport { WebGL2KernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture';\r\n\r\nimport { WebGL2KernelValueSingleArray } from './kernel-value/single-array';\r\nimport { WebGL2KernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array';\r\n\r\nimport { WebGL2KernelValueSingleArray1DI } from './kernel-value/single-array1d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray2DI } from './kernel-value/single-array2d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray3DI } from './kernel-value/single-array3d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray2 } from './kernel-value/single-array2';\r\nimport { WebGL2KernelValueSingleArray3 } from './kernel-value/single-array3';\r\nimport { WebGL2KernelValueSingleArray4 } from './kernel-value/single-array4';\r\n\r\nimport { WebGL2KernelValueUnsignedArray } from './kernel-value/unsigned-array';\r\nimport { WebGL2KernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array';\r\n\r\nexport const kernelValueMaps = {\r\n unsigned: {\r\n dynamic: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Array': WebGL2KernelValueDynamicUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGL2KernelValueDynamicUnsignedInput,\r\n 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Array': WebGL2KernelValueUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGL2KernelValueUnsignedInput,\r\n 'NumberTexture': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueHTMLVideo,\r\n }\r\n },\r\n single: {\r\n dynamic: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Array': WebGL2KernelValueDynamicSingleArray,\r\n 'Array(2)': WebGL2KernelValueSingleArray2,\r\n 'Array(3)': WebGL2KernelValueSingleArray3,\r\n 'Array(4)': WebGL2KernelValueSingleArray4,\r\n 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Input': WebGL2KernelValueDynamicSingleInput,\r\n 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Array': WebGL2KernelValueSingleArray,\r\n 'Array(2)': WebGL2KernelValueSingleArray2,\r\n 'Array(3)': WebGL2KernelValueSingleArray3,\r\n 'Array(4)': WebGL2KernelValueSingleArray4,\r\n 'Array1D(2)': WebGL2KernelValueSingleArray1DI,\r\n 'Array1D(3)': WebGL2KernelValueSingleArray1DI,\r\n 'Array1D(4)': WebGL2KernelValueSingleArray1DI,\r\n 'Array2D(2)': WebGL2KernelValueSingleArray2DI,\r\n 'Array2D(3)': WebGL2KernelValueSingleArray2DI,\r\n 'Array2D(4)': WebGL2KernelValueSingleArray2DI,\r\n 'Array3D(2)': WebGL2KernelValueSingleArray3DI,\r\n 'Array3D(3)': WebGL2KernelValueSingleArray3DI,\r\n 'Array3D(4)': WebGL2KernelValueSingleArray3DI,\r\n 'Input': WebGL2KernelValueSingleInput,\r\n 'NumberTexture': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueHTMLVideo,\r\n }\r\n },\r\n};\r\n\r\nexport function lookupKernelValueType(type, dynamic, precision, value) {\r\n if (!type) {\r\n throw new Error('type missing');\r\n }\r\n if (!dynamic) {\r\n throw new Error('dynamic missing');\r\n }\r\n if (!precision) {\r\n throw new Error('precision missing');\r\n }\r\n if (value.type) {\r\n type = value.type;\r\n }\r\n const types = kernelValueMaps[precision][dynamic];\r\n if (types[type] === false) {\r\n return null;\r\n } else if (types[type] === undefined) {\r\n throw new Error(`Could not find a KernelValue for ${ type }`);\r\n }\r\n return types[type];\r\n}\r\n","import { WebGLKernel } from '../web-gl/kernel';\r\nimport { WebGL2FunctionNode } from './function-node';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { utils } from '../../utils';\r\nimport { fragmentShader } from './fragment-shader';\r\nimport { vertexShader } from './vertex-shader';\r\nimport { lookupKernelValueType } from './kernel-value-maps';\r\n\r\nlet isSupported = null;\r\nlet testCanvas = null;\r\nlet testContext = null;\r\nlet testExtensions = null;\r\n\r\n/**\r\n *\r\n * @type {IKernelFeatures}\r\n */\r\nlet features = null;\r\n\r\n/**\r\n * @extends WebGLKernel\r\n */\r\nexport class WebGL2Kernel extends WebGLKernel {\r\n static get isSupported() {\r\n if (isSupported !== null) {\r\n return isSupported;\r\n }\r\n this.setupFeatureChecks();\r\n isSupported = this.isContextMatch(testContext);\r\n return isSupported;\r\n }\r\n\r\n static setupFeatureChecks() {\r\n if (typeof document !== 'undefined') {\r\n testCanvas = document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n testCanvas = new OffscreenCanvas(0, 0);\r\n }\r\n if (!testCanvas) return;\r\n testContext = testCanvas.getContext('webgl2');\r\n if (!testContext || !testContext.getExtension) return;\r\n testExtensions = {\r\n EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'),\r\n OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),\r\n };\r\n features = this.getFeatures();\r\n }\r\n\r\n static isContextMatch(context) {\r\n // from global\r\n if (typeof WebGL2RenderingContext !== 'undefined') {\r\n return context instanceof WebGL2RenderingContext;\r\n }\r\n return false;\r\n }\r\n\r\n static getFeatures() {\r\n return Object.freeze({\r\n isFloatRead: this.getIsFloatRead(),\r\n isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),\r\n kernelMap: true,\r\n isTextureFloat: true,\r\n channelCount: this.getChannelCount(),\r\n maxTextureSize: this.getMaxTextureSize(),\r\n });\r\n }\r\n\r\n static getIsTextureFloat() {\r\n return true;\r\n }\r\n\r\n static getIsIntegerDivisionAccurate() {\r\n return super.getIsIntegerDivisionAccurate();\r\n }\r\n\r\n static getChannelCount() {\r\n return testContext.getParameter(testContext.MAX_DRAW_BUFFERS);\r\n }\r\n\r\n static getMaxTextureSize() {\r\n return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);\r\n }\r\n\r\n static lookupKernelValueType(type, dynamic, precision, value) {\r\n return lookupKernelValueType(type, dynamic, precision, value);\r\n }\r\n\r\n static get testCanvas() {\r\n return testCanvas;\r\n }\r\n\r\n static get testContext() {\r\n return testContext;\r\n }\r\n\r\n /**\r\n *\r\n * @returns {{isFloatRead: Boolean, isIntegerDivisionAccurate: Boolean, kernelMap: Boolean, isTextureFloat: Boolean}}\r\n */\r\n static get features() {\r\n return features;\r\n }\r\n\r\n static get fragmentShader() {\r\n return fragmentShader;\r\n }\r\n static get vertexShader() {\r\n return vertexShader;\r\n }\r\n\r\n initContext() {\r\n const settings = {\r\n alpha: false,\r\n depth: false,\r\n antialias: false\r\n };\r\n const context = this.canvas.getContext('webgl2', settings);\r\n return context;\r\n }\r\n\r\n initExtensions() {\r\n this.extensions = {\r\n EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'),\r\n OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.validate) {\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n return;\r\n }\r\n\r\n const features = this.constructor.features;\r\n if (this.precision === 'single' && !features.isFloatRead) {\r\n throw new Error('Float texture outputs are not supported');\r\n } else if (!this.graphical && this.precision === null) {\r\n this.precision = features.isFloatRead ? 'single' : 'unsigned';\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy === null) {\r\n this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;\r\n } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {\r\n this.fixIntegerDivisionAccuracy = false;\r\n }\r\n\r\n this.checkOutput();\r\n\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n switch (argType) {\r\n case 'Array':\r\n this.output = utils.getDimensions(argType);\r\n break;\r\n case 'NumberTexture':\r\n case 'MemoryOptimizedNumberTexture':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n this.output = args[0].output;\r\n break;\r\n default:\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n\r\n if (this.precision === 'single') {\r\n console.warn('Cannot use graphical mode and single precision at the same time');\r\n this.precision = 'unsigned';\r\n }\r\n\r\n this.texSize = utils.clone(this.output);\r\n return;\r\n } else if (!this.graphical && this.precision === null && features.isTextureFloat) {\r\n this.precision = 'single';\r\n }\r\n\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n\r\n this.checkTextureSize();\r\n }\r\n\r\n translateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n this.translatedSource = functionBuilder.getPrototypeString('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (!subKernel.returnType) {\r\n subKernel.returnType = functionBuilder.getSubKernelResultType(i);\r\n }\r\n }\r\n }\r\n }\r\n\r\n run() {\r\n const { kernelArguments, texSize, forceUploadKernelConstants } = this;\r\n const gl = this.context;\r\n\r\n gl.useProgram(this.program);\r\n gl.scissor(0, 0, texSize[0], texSize[1]);\r\n\r\n if (this.dynamicOutput) {\r\n this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));\r\n this.setUniform2iv('uTexSize', texSize);\r\n }\r\n\r\n this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);\r\n\r\n this.switchingKernels = false;\r\n for (let i = 0; i < forceUploadKernelConstants.length; i++) {\r\n const constant = forceUploadKernelConstants[i];\r\n constant.updateValue(this.constants[constant.name]);\r\n if (this.switchingKernels) return;\r\n }\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n kernelArguments[i].updateValue(arguments[i]);\r\n if (this.switchingKernels) return;\r\n }\r\n\r\n if (this.plugins) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.onBeforeRun) {\r\n plugin.onBeforeRun(this);\r\n }\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.pipeline) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (!this.outputTexture || this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context\r\n });\r\n }\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return;\r\n }\r\n\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n\r\n if (this.subKernels !== null) {\r\n if (this.immutable) {\r\n this._setupSubOutputTextures();\r\n }\r\n gl.drawBuffers(this.drawBuffersMap);\r\n }\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n }\r\n\r\n drawBuffers() {\r\n this.context.drawBuffers(this.drawBuffersMap);\r\n }\r\n\r\n getOutputTexture() {\r\n return this.outputTexture;\r\n }\r\n\r\n _setupOutputTexture() {\r\n const { texSize } = this;\r\n const gl = this.context;\r\n const texture = this.outputTexture = gl.createTexture();\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n if (this.precision === 'single') {\r\n if (this.pipeline) {\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n } else {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]);\r\n }\r\n break;\r\n case 'Array(2)':\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]);\r\n break;\r\n case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable\r\n case 'Array(4)':\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n break;\r\n default:\r\n throw new Error('Unhandled return type');\r\n }\r\n } else {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n }\r\n\r\n _setupSubOutputTextures() {\r\n const { texSize } = this;\r\n const gl = this.context;\r\n this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];\r\n this.subKernelOutputTextures = [];\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const texture = this.context.createTexture();\r\n this.subKernelOutputTextures.push(texture);\r\n this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // TODO: upgrade this\r\n if (this.precision === 'single') {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @desc Get the header string for the program.\r\n * This returns an empty string if no sub-kernels are defined.\r\n *\r\n * @returns {String} result\r\n */\r\n _getHeaderString() {\r\n return '';\r\n }\r\n\r\n /**\r\n * @desc Get texture coordinate string for the program\r\n * @returns {String} result\r\n */\r\n _getTextureCoordinate() {\r\n const subKernels = this.subKernels;\r\n if (subKernels === null || subKernels.length < 1) {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'in lowp vec2 vTexCoord;\\n';\r\n case 'performance':\r\n return 'in highp vec2 vTexCoord;\\n';\r\n case 'balanced':\r\n default:\r\n return 'in mediump vec2 vTexCoord;\\n';\r\n }\r\n } else {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'out lowp vec2 vTexCoord;\\n';\r\n case 'performance':\r\n return 'out highp vec2 vTexCoord;\\n';\r\n case 'balanced':\r\n default:\r\n return 'out mediump vec2 vTexCoord;\\n';\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {String} result\r\n */\r\n _getMainArgumentsString(args) {\r\n const result = [];\r\n const argumentNames = this.argumentNames;\r\n for (let i = 0; i < argumentNames.length; i++) {\r\n result.push(this.kernelArguments[i].getSource(args[i]));\r\n }\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * @desc Get Kernel program string (in *glsl*) for a kernel.\r\n * @returns {String} result\r\n */\r\n getKernelString() {\r\n let kernelResultDeclaration;\r\n switch (this.returnType) {\r\n case 'Array(2)':\r\n kernelResultDeclaration = 'vec2 kernelResult';\r\n break;\r\n case 'Array(3)':\r\n kernelResultDeclaration = 'vec3 kernelResult';\r\n break;\r\n case 'Array(4)':\r\n kernelResultDeclaration = 'vec4 kernelResult';\r\n break;\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n kernelResultDeclaration = 'float kernelResult';\r\n break;\r\n default:\r\n if (this.graphical) {\r\n kernelResultDeclaration = 'float kernelResult';\r\n } else {\r\n throw new Error(`unrecognized output type \"${ this.returnType }\"`);\r\n }\r\n }\r\n\r\n const result = [];\r\n const subKernels = this.subKernels;\r\n if (subKernels !== null) {\r\n result.push(\r\n kernelResultDeclaration,\r\n 'layout(location = 0) out vec4 data0'\r\n );\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const subKernel = subKernels[i];\r\n result.push(\r\n subKernel.returnType === 'Integer' ?\r\n `int subKernelResult_${ subKernel.name } = 0` :\r\n `float subKernelResult_${ subKernel.name } = 0.0`,\r\n `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`\r\n );\r\n }\r\n } else {\r\n result.push(\r\n 'out vec4 data0',\r\n kernelResultDeclaration\r\n );\r\n }\r\n\r\n return utils.linesToString(result) + this.translatedSource;\r\n }\r\n\r\n getMainResultGraphical() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0 = actualColor',\r\n ]);\r\n }\r\n\r\n getMainResultPackedPixels() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return this.getMainResultKernelPackedPixels() +\r\n this.getMainResultSubKernelPackedPixels();\r\n default:\r\n throw new Error(`packed output only usable with Numbers, \"${this.returnType}\" specified`);\r\n }\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultKernelPackedPixels() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`\r\n ]);\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultSubKernelPackedPixels() {\r\n const result = [];\r\n if (!this.subKernels) return '';\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`\r\n );\r\n }\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultMemoryOptimizedFloats() {\r\n const result = [\r\n ' index *= 4',\r\n ];\r\n\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n const channels = ['r', 'g', 'b', 'a'];\r\n for (let i = 0; i < channels.length; i++) {\r\n const channel = channels[i];\r\n this.getMainResultKernelMemoryOptimizedFloats(result, channel);\r\n this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);\r\n if (i + 1 < channels.length) {\r\n result.push(' index += 1');\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);\r\n }\r\n\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultKernelMemoryOptimizedFloats(result, channel) {\r\n result.push(\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` data0.${channel} = kernelResult`,\r\n );\r\n }\r\n\r\n getMainResultSubKernelMemoryOptimizedFloats(result, channel) {\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n getMainResultKernelNumberTexture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelNumberTexture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray2Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult[0]',\r\n ' data0[1] = kernelResult[1]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray2Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,\r\n ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray3Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult[0]',\r\n ' data0[1] = kernelResult[1]',\r\n ' data0[2] = kernelResult[2]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray3Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,\r\n ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,\r\n ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray4Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0 = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray4Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n destroyExtensions() {\r\n this.extensions.EXT_color_buffer_float = null;\r\n this.extensions.OES_texture_float_linear = null;\r\n }\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON();\r\n return json;\r\n }\r\n}\r\n","import { utils } from './utils';\r\n\r\n/**\r\n * Makes kernels easier for mortals (including me)\r\n * @param kernel\r\n * @returns {function()}\r\n */\r\nexport function kernelRunShortcut(kernel) {\r\n let run = function() {\r\n kernel.build.apply(kernel, arguments);\r\n if (kernel.renderKernels) {\r\n run = function() {\r\n kernel.run.apply(kernel, arguments);\r\n if (kernel.switchingKernels) {\r\n kernel.switchingKernels = false;\r\n return kernel.onRequestSwitchKernel(arguments, kernel);\r\n }\r\n return kernel.renderKernels();\r\n };\r\n } else if (kernel.renderOutput) {\r\n run = function() {\r\n kernel.run.apply(kernel, arguments);\r\n if (kernel.switchingKernels) {\r\n kernel.switchingKernels = false;\r\n return kernel.onRequestSwitchKernel(arguments, kernel);\r\n }\r\n return kernel.renderOutput();\r\n };\r\n } else {\r\n run = function() {\r\n return kernel.run.apply(kernel, arguments);\r\n };\r\n }\r\n return run.apply(kernel, arguments);\r\n };\r\n const shortcut = function() {\r\n return run.apply(kernel, arguments);\r\n };\r\n /**\r\n * Run kernel in async mode\r\n * @returns {Promise}\r\n */\r\n shortcut.exec = function() {\r\n return new Promise((accept, reject) => {\r\n try {\r\n accept(run.apply(this, arguments));\r\n } catch (e) {\r\n reject(e);\r\n }\r\n });\r\n };\r\n shortcut.replaceKernel = function(replacementKernel) {\r\n kernel = replacementKernel;\r\n bindKernelToShortcut(kernel, shortcut);\r\n shortcut.kernel = kernel;\r\n };\r\n\r\n bindKernelToShortcut(kernel, shortcut);\r\n shortcut.kernel = kernel;\r\n return shortcut;\r\n}\r\n\r\nfunction bindKernelToShortcut(kernel, shortcut) {\r\n const properties = utils.allPropertiesOf(kernel);\r\n for (let i = 0; i < properties.length; i++) {\r\n const property = properties[i];\r\n if (property[0] === '_' && property[1] === '_') continue;\r\n if (typeof kernel[property] === 'function') {\r\n if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') {\r\n shortcut[property] = function() {\r\n kernel[property].apply(kernel, arguments);\r\n return shortcut;\r\n };\r\n } else {\r\n if (property === 'toString') {\r\n shortcut.toString = function() {\r\n return kernel.toString.apply(kernel, arguments);\r\n };\r\n } else {\r\n shortcut[property] = kernel[property].bind(kernel);\r\n }\r\n }\r\n } else {\r\n shortcut.__defineGetter__(property, () => {\r\n return kernel[property];\r\n });\r\n shortcut.__defineSetter__(property, (value) => {\r\n kernel[property] = value;\r\n });\r\n }\r\n }\r\n}\r\n","import { gpuMock } from 'gpu-mock.js';\r\nimport { CPUKernel } from './backend/cpu/kernel';\r\nimport { WebGL2Kernel } from './backend/web-gl2/kernel';\r\nimport { WebGLKernel } from './backend/web-gl/kernel';\r\nimport { kernelRunShortcut } from './kernel-run-shortcut';\r\nimport {\r\n functionToIFunction,\r\n getFunctionNameFromString,\r\n isFunction,\r\n warnDeprecated\r\n} from './common';\r\nimport { getVariableType } from './utils';\r\n\r\n/**\r\n * @type {Kernel[]}\r\n */\r\nconst kernelOrder = [ WebGL2Kernel, WebGLKernel ];\r\n\r\n/**\r\n * @type {string[]}\r\n */\r\nconst kernelTypes = [ 'gpu', 'cpu' ];\r\n\r\nconst internalKernels = {\r\n 'webgl2': WebGL2Kernel,\r\n 'webgl': WebGLKernel,\r\n};\r\n\r\nlet validate = true;\r\n\r\n/**\r\n * The GPU.js library class which manages the GPU context for the creating kernels\r\n */\r\nexport class GPU {\r\n static disableValidation() {\r\n validate = false;\r\n }\r\n\r\n static enableValidation() {\r\n validate = true;\r\n }\r\n\r\n static get isGPUSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported);\r\n }\r\n\r\n /**\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isKernelMapSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap);\r\n }\r\n\r\n /**\r\n * @desc TRUE is platform supports OffscreenCanvas\r\n */\r\n static get isOffscreenCanvasSupported() {\r\n return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined';\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports WebGL\r\n */\r\n static get isWebGLSupported() {\r\n return WebGLKernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports WebGL2\r\n */\r\n static get isWebGL2Supported() {\r\n return WebGL2Kernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports HeadlessGL\r\n */\r\n static get isHeadlessGLSupported() {\r\n return false;\r\n }\r\n\r\n /**\r\n *\r\n * @desc TRUE if platform supports Canvas\r\n */\r\n static get isCanvasSupported() {\r\n return typeof HTMLCanvasElement !== 'undefined';\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports HTMLImageArray}\r\n */\r\n static get isGPUHTMLImageArraySupported() {\r\n return WebGL2Kernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports single precision}\r\n * @returns {boolean}\r\n */\r\n static get isSinglePrecisionSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat);\r\n }\r\n\r\n /**\r\n * Creates an instance of GPU.\r\n * @param {IGPUSettings} [settings] - Settings to set mode, and other properties\r\n */\r\n constructor(settings) {\r\n settings = settings || {};\r\n this.canvas = settings.canvas || null;\r\n this.context = settings.context || null;\r\n this.mode = settings.mode;\r\n this.Kernel = null;\r\n this.kernels = [];\r\n this.functions = [];\r\n this.nativeFunctions = [];\r\n this.injectedNative = null;\r\n if (this.mode === 'dev') return;\r\n this.chooseKernel();\r\n // add functions from settings\r\n if (settings.functions) {\r\n for (let i = 0; i < settings.functions.length; i++) {\r\n this.addFunction(settings.functions[i]);\r\n }\r\n }\r\n\r\n // add native functions from settings\r\n if (settings.nativeFunctions) {\r\n for (const p in settings.nativeFunctions) {\r\n this.addNativeFunction(p, settings.nativeFunctions[p]);\r\n }\r\n }\r\n }\r\n\r\n getValidate() {\r\n return validate;\r\n }\r\n\r\n /**\r\n * Choose kernel type and save on .Kernel property of GPU\r\n */\r\n chooseKernel() {\r\n if (this.Kernel) return;\r\n\r\n let Kernel = null;\r\n\r\n if (this.context) {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n const ExternalKernel = kernelOrder[i];\r\n if (ExternalKernel.isContextMatch(this.context)) {\r\n if (!ExternalKernel.isSupported) {\r\n throw new Error(`Kernel type ${ExternalKernel.name} not supported`);\r\n }\r\n Kernel = ExternalKernel;\r\n break;\r\n }\r\n }\r\n if (Kernel === null) {\r\n throw new Error('unknown Context');\r\n }\r\n } else if (this.mode) {\r\n if (this.mode in internalKernels) {\r\n if (!validate || internalKernels[this.mode].isSupported) {\r\n Kernel = internalKernels[this.mode];\r\n }\r\n } else if (this.mode === 'gpu') {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n if (kernelOrder[i].isSupported) {\r\n Kernel = kernelOrder[i];\r\n break;\r\n }\r\n }\r\n } else if (this.mode === 'cpu') {\r\n Kernel = CPUKernel;\r\n }\r\n if (!Kernel) {\r\n throw new Error(`A requested mode of \"${this.mode}\" and is not supported`);\r\n }\r\n } else {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n if (kernelOrder[i].isSupported) {\r\n Kernel = kernelOrder[i];\r\n break;\r\n }\r\n }\r\n if (!Kernel) {\r\n Kernel = CPUKernel;\r\n }\r\n }\r\n\r\n if (!this.mode) {\r\n this.mode = Kernel.mode;\r\n }\r\n this.Kernel = Kernel;\r\n }\r\n\r\n /**\r\n * @desc This creates a callable function object to call the kernel function with the argument parameter set\r\n * @param {Function|String|object} source - The calling to perform the conversion\r\n * @param {Object} [settings] - The parameter configuration object\r\n * @return {Kernel} callable function to run\r\n */\r\n createKernel(source, settings) {\r\n if (typeof source === 'undefined') {\r\n throw new Error('Missing source parameter');\r\n }\r\n if (typeof source !== 'object' && !isFunction(source) && typeof source !== 'string') {\r\n throw new Error('source parameter not a function');\r\n }\r\n\r\n if (this.mode === 'dev') {\r\n const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings));\r\n this.kernels.push(devKernel);\r\n return devKernel;\r\n }\r\n\r\n source = typeof source === 'function' ? source.toString() : source;\r\n const switchableKernels = {};\r\n const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {};\r\n // handle conversion of argumentTypes\r\n if (settings && typeof settings.argumentTypes === 'object') {\r\n settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);\r\n }\r\n\r\n function onRequestFallback(args) {\r\n const fallbackKernel = new CPUKernel(source, {\r\n argumentTypes: kernelRun.argumentTypes,\r\n constantTypes: kernelRun.constantTypes,\r\n graphical: kernelRun.graphical,\r\n loopMaxIterations: kernelRun.loopMaxIterations,\r\n constants: kernelRun.constants,\r\n dynamicOutput: kernelRun.dynamicOutput,\r\n dynamicArgument: kernelRun.dynamicArguments,\r\n output: kernelRun.output,\r\n precision: kernelRun.precision,\r\n pipeline: kernelRun.pipeline,\r\n immutable: kernelRun.immutable,\r\n optimizeFloatMemory: kernelRun.optimizeFloatMemory,\r\n fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy,\r\n functions: kernelRun.functions,\r\n nativeFunctions: kernelRun.nativeFunctions,\r\n injectedNative: kernelRun.injectedNative,\r\n subKernels: kernelRun.subKernels,\r\n strictIntegers: kernelRun.strictIntegers,\r\n debug: kernelRun.debug,\r\n warnVarUsage: kernelRun.warnVarUsage,\r\n });\r\n fallbackKernel.build.apply(fallbackKernel, args);\r\n const result = fallbackKernel.run.apply(fallbackKernel, args);\r\n kernelRun.replaceKernel(fallbackKernel);\r\n return result;\r\n }\r\n\r\n function onRequestSwitchKernel(args, kernel) {\r\n const argumentTypes = new Array(args.length);\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n const type = kernel.argumentTypes[i];\r\n if (arg.type) {\r\n argumentTypes[i] = arg.type;\r\n } else {\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'ArrayTexture(1)':\r\n argumentTypes[i] = getVariableType(arg);\r\n break;\r\n default:\r\n argumentTypes[i] = type;\r\n }\r\n }\r\n }\r\n const signature = argumentTypes.join(',');\r\n const existingKernel = switchableKernels[signature];\r\n if (existingKernel) {\r\n existingKernel.run.apply(existingKernel, args);\r\n if (existingKernel.renderKernels) {\r\n return existingKernel.renderKernels();\r\n } else {\r\n return existingKernel.renderOutput();\r\n }\r\n }\r\n\r\n const newKernel = switchableKernels[signature] = new kernel.constructor(source, {\r\n argumentTypes,\r\n constantTypes: kernel.constantTypes,\r\n graphical: kernel.graphical,\r\n loopMaxIterations: kernel.loopMaxIterations,\r\n constants: kernel.constants,\r\n dynamicOutput: kernel.dynamicOutput,\r\n dynamicArgument: kernel.dynamicArguments,\r\n context: kernel.context,\r\n canvas: kernel.canvas,\r\n output: kernel.output,\r\n precision: kernel.precision,\r\n pipeline: kernel.pipeline,\r\n immutable: kernel.immutable,\r\n optimizeFloatMemory: kernel.optimizeFloatMemory,\r\n fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy,\r\n functions: kernel.functions,\r\n nativeFunctions: kernel.nativeFunctions,\r\n injectedNative: kernel.injectedNative,\r\n subKernels: kernel.subKernels,\r\n strictIntegers: kernel.strictIntegers,\r\n debug: kernel.debug,\r\n gpu: kernel.gpu,\r\n validate,\r\n warnVarUsage: kernel.warnVarUsage,\r\n returnType: kernel.returnType,\r\n onRequestFallback,\r\n onRequestSwitchKernel,\r\n });\r\n newKernel.build.apply(newKernel, args);\r\n newKernel.run.apply(newKernel, args);\r\n kernelRun.replaceKernel(newKernel);\r\n if (newKernel.renderKernels) {\r\n return newKernel.renderKernels();\r\n } else {\r\n return newKernel.renderOutput();\r\n }\r\n }\r\n const mergedSettings = Object.assign({\r\n context: this.context,\r\n canvas: this.canvas,\r\n functions: this.functions,\r\n nativeFunctions: this.nativeFunctions,\r\n injectedNative: this.injectedNative,\r\n gpu: this,\r\n validate,\r\n onRequestFallback,\r\n onRequestSwitchKernel\r\n }, settingsCopy);\r\n\r\n const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings));\r\n\r\n //if canvas didn't come from this, propagate from kernel\r\n if (!this.canvas) {\r\n this.canvas = kernelRun.canvas;\r\n }\r\n\r\n //if context didn't come from this, propagate from kernel\r\n if (!this.context) {\r\n this.context = kernelRun.context;\r\n }\r\n\r\n this.kernels.push(kernelRun);\r\n\r\n return kernelRun;\r\n }\r\n\r\n /**\r\n *\r\n * Create a super kernel which executes sub kernels\r\n * and saves their output to be used with the next sub kernel.\r\n * This can be useful if we want to save the output on one kernel,\r\n * and then use it as an input to another kernel. *Machine Learning*\r\n *\r\n * @param {Object|Array} subKernels - Sub kernels for this kernel\r\n * @param {Function} rootKernel - Root kernel\r\n *\r\n * @returns {Function} callable kernel function\r\n *\r\n * @example\r\n * const megaKernel = gpu.createKernelMap({\r\n * addResult: function add(a, b) {\r\n * return a[this.thread.x] + b[this.thread.x];\r\n * },\r\n * multiplyResult: function multiply(a, b) {\r\n * return a[this.thread.x] * b[this.thread.x];\r\n * },\r\n * }, function(a, b, c) {\r\n * return multiply(add(a, b), c);\r\n * });\r\n *\r\n * megaKernel(a, b, c);\r\n *\r\n * Note: You can also define subKernels as an array of functions.\r\n * > [add, multiply]\r\n *\r\n */\r\n createKernelMap() {\r\n let fn;\r\n let settings;\r\n if (typeof arguments[arguments.length - 2] === 'function') {\r\n fn = arguments[arguments.length - 2];\r\n settings = arguments[arguments.length - 1];\r\n } else {\r\n fn = arguments[arguments.length - 1];\r\n }\r\n\r\n if (this.mode !== 'dev') {\r\n if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) {\r\n if (this.mode && kernelTypes.indexOf(this.mode) < 0) {\r\n throw new Error(`kernelMap not supported on ${this.Kernel.name}`);\r\n }\r\n }\r\n }\r\n\r\n const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings);\r\n // handle conversion of argumentTypes\r\n if (settings && typeof settings.argumentTypes === 'object') {\r\n settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);\r\n }\r\n\r\n if (Array.isArray(arguments[0])) {\r\n settingsCopy.subKernels = [];\r\n const functions = arguments[0];\r\n for (let i = 0; i < functions.length; i++) {\r\n const source = functions[i].toString();\r\n const name = getFunctionNameFromString(source);\r\n settingsCopy.subKernels.push({\r\n name,\r\n source,\r\n property: i,\r\n });\r\n }\r\n } else {\r\n settingsCopy.subKernels = [];\r\n const functions = arguments[0];\r\n for (let p in functions) {\r\n if (!functions.hasOwnProperty(p)) continue;\r\n const source = functions[p].toString();\r\n const name = getFunctionNameFromString(source);\r\n settingsCopy.subKernels.push({\r\n name: name || p,\r\n source,\r\n property: p,\r\n });\r\n }\r\n }\r\n const kernel = this.createKernel(fn, settingsCopy);\r\n\r\n return kernel;\r\n }\r\n\r\n /**\r\n *\r\n * Combine different kernels into one super Kernel,\r\n * useful to perform multiple operations inside one\r\n * kernel without the penalty of data transfer between\r\n * cpu and gpu.\r\n *\r\n * The number of kernel functions sent to this method can be variable.\r\n * You can send in one, two, etc.\r\n *\r\n * @param {Function} subKernels - Kernel function(s) to combine.\r\n * @param {Function} rootKernel - Root kernel to combine kernels into\r\n *\r\n * @example\r\n * combineKernels(add, multiply, function(a,b,c){\r\n * return add(multiply(a,b), c)\r\n * })\r\n *\r\n * @returns {Function} Callable kernel function\r\n *\r\n */\r\n combineKernels() {\r\n const firstKernel = arguments[0];\r\n const combinedKernel = arguments[arguments.length - 1];\r\n if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel;\r\n const canvas = arguments[0].canvas;\r\n const context = arguments[0].context;\r\n const max = arguments.length - 1;\r\n for (let i = 0; i < max; i++) {\r\n arguments[i]\r\n .setCanvas(canvas)\r\n .setContext(context)\r\n .setPipeline(true);\r\n }\r\n\r\n return function() {\r\n const texture = combinedKernel.apply(this, arguments);\r\n if (texture.toArray) {\r\n return texture.toArray();\r\n }\r\n return texture;\r\n };\r\n }\r\n\r\n /**\r\n * @desc Adds additional functions, that the kernel may call.\r\n * @param {Function|String} source - Javascript function to convert\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {GPU} returns itself\r\n */\r\n addFunction(source, settings) {\r\n this.functions.push(functionToIFunction(source, settings));\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Adds additional native functions, that the kernel may call.\r\n * @param {String} name - native function name, used for reverse lookup\r\n * @param {String} source - the native function implementation, as it would be defined in it's entirety\r\n * @param {object} [settings]\r\n * @returns {GPU} returns itself\r\n */\r\n addNativeFunction(name, source, settings) {\r\n if (this.kernels.length > 0) {\r\n throw new Error('Cannot call \"addNativeFunction\" after \"createKernels\" has been called.');\r\n }\r\n settings = settings || {};\r\n const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {};\r\n this.nativeFunctions.push({\r\n name,\r\n source,\r\n settings,\r\n argumentTypes,\r\n argumentNames,\r\n returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source),\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Inject a string just before translated kernel functions\r\n * @param {String} source\r\n * @return {GPU}\r\n */\r\n injectNative(source) {\r\n this.injectedNative = source;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Destroys all memory associated with gpu.js & the webGl if we created it\r\n */\r\n destroy() {\r\n if (!this.kernels) return;\r\n // perform on next run loop - for some reason we dont get lose context events\r\n // if webGl is created and destroyed in the same run loop.\r\n setTimeout(() => {\r\n for (let i = 0; i < this.kernels.length; i++) {\r\n this.kernels[i].destroy(true); // remove canvas if exists\r\n }\r\n // all kernels are associated with one context, go ahead and take care of it here\r\n let firstKernel = this.kernels[0];\r\n if (firstKernel) {\r\n // if it is shortcut\r\n if (firstKernel.kernel) {\r\n firstKernel = firstKernel.kernel;\r\n }\r\n if (firstKernel.constructor.destroyContext) {\r\n firstKernel.constructor.destroyContext(this.context);\r\n }\r\n }\r\n }, 0);\r\n }\r\n}\r\n\r\nfunction upgradeDeprecatedCreateKernelSettings(settings) {\r\n if (!settings) {\r\n return {};\r\n }\r\n const upgradedSettings = Object.assign({}, settings);\r\n\r\n if (settings.hasOwnProperty('floatOutput')) {\r\n warnDeprecated('setting', 'floatOutput', 'precision');\r\n upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned';\r\n }\r\n if (settings.hasOwnProperty('outputToTexture')) {\r\n warnDeprecated('setting', 'outputToTexture', 'pipeline');\r\n upgradedSettings.pipeline = Boolean(settings.outputToTexture);\r\n }\r\n if (settings.hasOwnProperty('outputImmutable')) {\r\n warnDeprecated('setting', 'outputImmutable', 'immutable');\r\n upgradedSettings.immutable = Boolean(settings.outputImmutable);\r\n }\r\n if (settings.hasOwnProperty('floatTextures')) {\r\n warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory');\r\n upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures);\r\n }\r\n return upgradedSettings;\r\n}\r\n","import { utils } from './utils';\r\n\r\n/**\r\n * @param name\r\n * @param source\r\n * @returns {Function}\r\n */\r\nexport function alias(name, source) {\r\n const fnString = source.toString();\r\n return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) {\r\n ${ utils.getFunctionBodyFromString(fnString) }\r\n}`)();\r\n}\r\n","import { GPU } from './base-gpu';\r\nimport { alias } from './alias';\r\nimport { utils } from './utils';\r\nimport * as common from './common';\r\nimport { Input, input } from './input';\r\nimport { Texture } from './texture';\r\nimport { FunctionBuilder } from './backend/function-builder';\r\nimport { FunctionNode } from './backend/function-node';\r\nimport { CPUFunctionNode } from './backend/cpu/function-node';\r\nimport { CPUKernel } from './backend/cpu/kernel';\r\nimport { WebGLFunctionNode } from './backend/web-gl/function-node';\r\nimport { WebGLKernel } from './backend/web-gl/kernel';\r\nimport { WebGL2FunctionNode } from './backend/web-gl2/function-node';\r\nimport { WebGL2Kernel } from './backend/web-gl2/kernel';\r\nimport { GLKernel } from './backend/gl/kernel';\r\nimport { Kernel } from './backend/kernel';\r\n\r\n/**\r\n * Stub for HeadlessGL.\r\n */\r\nclass HeadlessGLKernel extends WebGLKernel {\r\n static get isSupported() { return false }\r\n static isContextMatch() { return false }\r\n static getIsTextureFloat() { return false }\r\n static getIsDrawBuffers() { return false }\r\n static getChannelCount() { return 1 }\r\n static get testCanvas() { return null }\r\n static get testContext() { return null }\r\n static get features() { return null }\r\n static setupFeatureChecks() {}\r\n static destroyContext() {}\r\n initCanvas() { return {} }\r\n initContext() { return null }\r\n toString() { return '' }\r\n initExtensions() {}\r\n build() {}\r\n destroyExtensions() {}\r\n setOutput() {}\r\n\r\n static getFeatures() {\r\n return Object.freeze({\r\n isFloatRead: false,\r\n isIntegerDivisionAccurate: false,\r\n isTextureFloat: false,\r\n isDrawBuffers: false,\r\n kernelMap: false,\r\n channelCount: 1,\r\n });\r\n }\r\n};\r\n\r\nconst lib = GPU;\r\nlib.alias = alias;\r\nlib.CPUFunctionNode = CPUFunctionNode;\r\nlib.CPUKernel = CPUKernel;\r\nlib.FunctionBuilder = FunctionBuilder;\r\nlib.FunctionNode = FunctionNode;\r\nlib.HeadlessGLKernel = HeadlessGLKernel;\r\nlib.Input = Input;\r\nlib.input = input;\r\nlib.Texture = Texture;\r\nlib.utils = { ...common, ...utils };\r\nlib.WebGL2FunctionNode = WebGL2FunctionNode;\r\nlib.WebGL2Kernel = WebGL2Kernel;\r\nlib.WebGLFunctionNode = WebGLFunctionNode;\r\nlib.WebGLKernel = WebGLKernel;\r\nlib.GLKernel = GLKernel;\r\nlib.Kernel = Kernel;\r\n\r\nexport default lib;\r\n"],"names":["utils","parse","typeMap","name","glWiretap","fragmentShader","vertexShader","kernelValueMaps","lookupKernelValueType","isSupported","testCanvas","testContext","testExtensions","features","gpuMock"],"mappings":";;;;;;;;;;;;;;;;;EAAA,SAAS,cAAc,CAAC,IAAI,EAAE;IAC5B,MAAM,YAAY,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;MACpC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;MACpB,IAAI,GAAG,CAAC,OAAO,EAAE;QACf,YAAY,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;OACjC,MAAM;QACL,YAAY,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;OACvB;KACF;IACD,OAAO,YAAY,CAAC;GACrB;EAED,SAAS,MAAM,GAAG;IAChB,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;MACtC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;MAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;MAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;MAClB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;KACrC;IACD,OAAO,GAAG,CAAC;GACZ;EAED,SAAS,MAAM,GAAG;IAChB,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;MACtC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;MAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;OACrC;MACD,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;KACjB;IACD,OAAO,MAAM,CAAC;GACf;EAED,SAAS,eAAe,GAAG;IACzB,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;MACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;OAC5B;KACF;GACF;EAED,SAAS,MAAM,GAAG;IAChB,MAAM,IAAI,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;MACtC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;MACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;UACtC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;UAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;UAClB,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;UAClB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;SACrC;QACD,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;OACjB;MACD,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;KAClB;IACD,OAAO,IAAI,CAAC;GACb;EAED,SAAS,WAAW,CAAC,MAAM,EAAE;IAC3B,MAAM,CAAC,SAAS,GAAG,CAAC,MAAM,KAAK;MAC7B,MAAM,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;MACpC,IAAI,MAAM,CAAC,SAAS,EAAE;QACpB,cAAc,CAAC,MAAM,CAAC,CAAC;OACxB;KACF,CAAC;IACF,MAAM,CAAC,MAAM,GAAG,MAAM;MACpB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;KAC5C,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,CAAC,IAAI,KAAK;MAC9B,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;MACxB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,CAAC,IAAI,KAAK;MAC9B,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC;MACxB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,KAAK;MAC3B,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;MACrB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,UAAU,GAAG,CAAC,IAAI,KAAK;MAC5B,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;MACtB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,IAAI,GAAG,WAAW;MACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK;QACtC,IAAI;UACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;SAC1C,CAAC,MAAM,CAAC,EAAE;UACT,MAAM,CAAC,CAAC,CAAC,CAAC;SACX;OACF,CAAC,CAAC;KACJ,CAAC;IACF,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,KAAK;MAC3B,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;MAE7B,OAAO,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC1F,CAAC;IACF,MAAM,CAAC,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;MAClC,IAAI,OAAO,CAAC,KAAK,WAAW,EAAE;QAC5B,CAAC,GAAG,CAAC,CAAC;OACP;MAED,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;MACxB,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;MACxB,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;MACxB,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;MAExB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;MAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;MAE/B,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;MAC1B,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;MAEvC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;MAE5B,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;MACrC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;MACrC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;MACrC,MAAM,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;KACtC,CAAC;IAGF,MAAM,CAAC,eAAe,GAAG,MAAM;MAC7B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,sBAAsB,GAAG,MAAM;MACpC,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,gBAAgB,GAAG,MAAM;MAC9B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,QAAQ,GAAG,MAAM;MACtB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,oBAAoB,GAAG,MAAM;MAClC,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,WAAW,GAAG,MAAM;MACzB,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,MAAM;MAC1B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,MAAM;MAC1B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,MAAM;MAC1B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,YAAY,GAAG,MAAM;MAC1B,OAAO,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,gBAAgB,GAAG,MAAM,EAAE,CAAC;IACnC,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE;MACrC,cAAc,CAAC,MAAM,CAAC,CAAC;KACxB;IACD,OAAO,MAAM,CAAC;GACf;EAED,SAAS,cAAc,CAAC,MAAM,EAAE;IAC9B,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE;MACpD,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;MAC9C,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;MACzD,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;KAC1B,MAAM;MACL,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;MAC9C,MAAM,CAAC,UAAU,GAAG,EAAE,IAAI,EAAE,CAAC;MAC7B,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;KAC1B;GACF;EAED,SAAS,WAAW,CAAC,MAAM,EAAE;IAC3B,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,IAAI,MAAM,CAAC,MAAM,EAAE;MACjB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QACvB,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACvB,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;OACtB,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QAC9B,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACrB,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;OACnB,MAAM;QACL,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC;QACnB,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC;OAChB;KACF,MAAM;MACL,MAAM,GAAG,MAAM,CAAC;KACjB;IACD,OAAO,MAAM,CAAC;GACf;EAED,SAAS,OAAO,CAAC,EAAE,EAAE,QAAQ,GAAG,EAAE,EAAE;IAClC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACrE,SAAS,MAAM,GAAG;MAChB,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;QACnB,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;OACxC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE;QAC1B,IAAI,MAAM,CAAC,SAAS,EAAE;UACpB,OAAO,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;SACjD;QACD,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;OACxC,MAAM;QACL,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;OACxC;KACF;IACD,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;IAChB,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC;IAC9C,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC;IAC1C,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC;IACxC,MAAM,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,IAAI,KAAK,CAAC;IAC/C,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,CAAC,MAAM,GAAG;MACd,CAAC,EAAE,CAAC;MACJ,CAAC,EAAE,CAAC;MACJ,CAAC,EAAE,CAAC;KACL,CAAC;IACF,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;GAC5B;EAED,SAAS,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;IAEzC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;IAE9B,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC,EAAE;MACnC,MAAM,SAAS,GAAG,CAAC,GAAG,WAAW,CAAC;MAClC,MAAM,YAAY,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;MAGpD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;MAG9D,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;MAGvE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;KAChC;IACD,OAAO,MAAM,CAAC;GACf;EAED,cAAc,GAAG;IACf,OAAO;GACR,CAAC;;;ECnQF,MAAM,cAAc,GAAG,YAAY,CAAC;EACpC,MAAM,aAAa,GAAG,kBAAkB,CAAC;EACzC,MAAM,cAAc,GAAG,kCAAkC,CAAC;AAO1D,EAAO,SAAS,UAAU,CAAC,OAAO,EAAE;EACpC,EAAE,OAAO,OAAO,OAAO,CAAC,KAAK,UAAU,CAAC;EACxC,CAAC,AAOM,SAAS,yBAAyB,CAAC,OAAO,EAAE;EACnD,EAAE,OAAO,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;EAC/C,CAAC,AAQM,SAAS,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE;EACtD,EAAE,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC5B,EAAE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;EACrH,EAAE,MAAM,YAAY,GAAG,OAAO,MAAM,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;EAE/E,EAAE,IAAI,aAAa,GAAG,EAAE,CAAC;EAEzB,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE;EAC7C,IAAI,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;EAC3C,GAAG,MAAM,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,EAAE;EACzD,IAAI,aAAa,GAAG,0BAA0B,CAAC,YAAY,CAAC;EAC5D,OAAO,GAAG,CAAC,IAAI,IAAI,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;EACvD,GAAG,MAAM;EACT,IAAI,aAAa,GAAG,QAAQ,CAAC,aAAa,IAAI,EAAE,CAAC;EACjD,GAAG;EAEH,EAAE,OAAO;EACT,IAAI,MAAM,EAAE,YAAY;EACxB,IAAI,aAAa;EACjB,IAAI,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,IAAI;EAC3C,GAAG,CAAC;EACJ,CAAC,AAEM,SAAS,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;EACvD,EAAE,MAAM,GAAG,GAAG,OAAO;EACrB,MAAM,CAAC,2BAA2B,GAAG,OAAO,EAAE,CAAC,CAAC;EAChD,MAAM,qBAAqB,CAAC;EAC5B,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,2BAA2B,GAAG,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,wDAAwD,CAAC,EAAC;EACrI,CAAC,AASM,SAAS,gBAAgB,CAAC,EAAE,EAAE;EACrC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE;EAC9B,IAAI,QAAQ,EAAE;EACd,OAAO,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC;EAClC,OAAO,WAAW,EAAE,KAAK,UAAU,EAAE;EACrC,GAAG;EACH,EAAE,OAAO,KAAK,CAAC;EACf,CAAC,AAOM,SAAS,0BAA0B,CAAC,EAAE,EAAE;EAC/C,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;EAC/C,EAAE,IAAI,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;EAC7F,EAAE,IAAI,MAAM,KAAK,IAAI,EAAE;EACvB,IAAI,MAAM,GAAG,EAAE,CAAC;EAChB,GAAG;EACH,EAAE,OAAO,MAAM,CAAC;EAChB,CAAC,AAOM,SAAS,OAAO,CAAC,KAAK,EAAE;EAC/B,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;EAC9B,CAAC,AAEM,SAAS,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE;EAClE,EAAE,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACrC,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACnC,IAAI,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;EAC7B,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;EACzD,GAAG;EACH,EAAE,OAAO,QAAQ,CAAC;EAClB,CAAC,AAEM,SAAS,2BAA2B,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE;EACzE,EAAE,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACpC,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;EACxD,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;EAC3D,KAAK;EACL,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC3B,GAAG;EACH,EAAE,OAAO,QAAQ,CAAC;EAClB,CAAC,AAEM,SAAS,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE;EAC1C,EAAE,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EACxE,EAAE,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC;EAC9B,EAAE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;EAC1B,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC;EACpB,EAAE,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE;EAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAC3E,GAAG,MAAM;EACT,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;EAC3D,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;EAChD,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5B,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAC1D,GAAG;EACH,EAAE,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC3B,CAAC;;;;;;;;;;;;;;;ECxIM,MAAM,KAAK,CAAC;EACnB,EAAE,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE;EAC3B,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;EACvB,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;EAC7B,MAAM,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;EACvB,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;EACpC,MAAM,IAAI,IAAI,CAAC,CAAC,EAAE;EAClB,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7D,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,EAAE;EACzB,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACrD,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7C,OAAO;EACP,KAAK;EAEL,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;EAChC,IAAI,IAAI,CAAC,EAAE;EACX,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;EAC7C,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;EAC9G,OAAO;EACP,KAAK,MAAM,IAAI,CAAC,EAAE;EAClB,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;EACzC,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;EACnG,OAAO;EACP,KAAK,MAAM;EACX,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;EACnC,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/E,OAAO;EACP,KAAK;EAEL,GAAG;EAEH,EAAE,OAAO,GAAG;EACZ,IAAI,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,EAAE;EACX,MAAM,OAAO,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EACnH,KAAK,MAAM,IAAI,CAAC,EAAE;EAClB,MAAM,OAAO,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAChH,KAAK,MAAM;EACX,MAAM,OAAO,IAAI,CAAC,KAAK,CAAC;EACxB,KAAK;EACL,GAAG;EACH,CAAC,AAEM,SAAS,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE;EACnC,EAAE,OAAO,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAChC,CAAC;;EC7CM,MAAM,OAAO,CAAC;EACrB,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,IAAI;EACV,MAAM,UAAU;EAChB,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,IAAI,GAAG,eAAe;EAC5B,KAAK,GAAG,QAAQ,CAAC;EACjB,IAAI,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;EACzE,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;EAC3E,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;EAC3B,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;EACjC,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;EAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EACvB,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;EACrB,GAAG;EAMH,EAAE,OAAO,GAAG;EACZ,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,mBAAmB,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACnE,GAAG;EAKH,EAAE,MAAM,GAAG;EACX,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACpD,GAAG;EACH,CAAC;;ECvBM,SAAS,mBAAmB,GAAG;EACtC,EAAE,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;EAC/B,EAAE,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;EAC/B,EAAE,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;EAC9B,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;EACpB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC;EACjC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC;EACjC,EAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;EACxC,CAAC,AAED,MAAM,iBAAiB,GAAG,mBAAmB,EAAE,CAAC;AAQhD,EAAO,SAAS,gBAAgB,GAAG;EACnC,EAAE,OAAO,iBAAiB,CAAC;EAC3B,CAAC,AAOM,SAAS,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE;EACvD,EAAE,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE;EACtB,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,EAAE;EACrC,MAAM,OAAO,gBAAgB,CAAC;EAC9B,KAAK;EACL,IAAI,OAAO,OAAO,CAAC;EACnB,GAAG;EAEH,EAAE,QAAQ,KAAK,CAAC,WAAW;EAC3B,IAAI,KAAK,OAAO;EAChB,MAAM,OAAO,SAAS,CAAC;EACvB,IAAI,KAAK,MAAM;EACf,MAAM,OAAO,cAAc,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC;EAC7E,IAAI,KAAK,OAAO;EAChB,MAAM,OAAO,KAAK,CAAC,IAAI,CAAC;EACxB,IAAI,KAAK,KAAK;EACd,MAAM,OAAO,OAAO,CAAC;EACrB,GAAG;EAEH,EAAE,QAAQ,KAAK,CAAC,QAAQ;EACxB,IAAI,KAAK,KAAK;EACd,MAAM,OAAO,WAAW,CAAC;EACzB,IAAI,KAAK,OAAO;EAChB,MAAM,OAAO,WAAW,CAAC;EACzB,GAAG;EAEH,EAAE,OAAO,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,GAAG,SAAS,CAAC;EAC/D,CAAC,AAMD,MAAMA,OAAK,GAAG;EACd,EAAE,gBAAgB;EAClB,EAAE,mBAAmB;EACrB,EAAE,UAAU;EACZ,EAAE,gBAAgB;EAClB,EAAE,yBAAyB;EAE3B,EAAE,yBAAyB,CAAC,OAAO,EAAE;EACrC,IAAI,OAAO,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;EACjF,GAAG;EAEH,EAAE,0BAA0B;EAO5B,EAAE,KAAK,CAAC,GAAG,EAAE;EACb,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,CAAC;EAEnG,IAAI,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;EAEnC,IAAI,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE;EACzB,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE;EAC1D,QAAQ,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC;EACjC,QAAQ,IAAI,CAAC,GAAG,CAAC,GAAGA,OAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC1C,QAAQ,OAAO,GAAG,CAAC,aAAa,CAAC;EACjC,OAAO;EACP,KAAK;EAEL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,OAAO;EACT,EAAE,eAAe;EAEjB,EAAE,oBAAoB,CAAC,QAAQ,EAAE,UAAU,EAAE;EAC7C,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC;EAC/B,IAAI,IAAI,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAEpD,IAAI,IAAI,QAAQ,CAAC,mBAAmB,IAAI,QAAQ,CAAC,SAAS,KAAK,QAAQ,EAAE;EACzE,MAAM,CAAC,GAAG,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;EACjD,KAAK;EAEL,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,UAAU,EAAE;EACvC,MAAM,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EACpC,KAAK;EACL,IAAI,OAAOA,OAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;EACrD,GAAG;EAOH,EAAE,uBAAuB,CAAC,MAAM,EAAE;EAClC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACnC,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC/B,IAAI,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;EAC/B,IAAI,OAAO,IAAI,GAAG,GAAG,GAAG,MAAM,EAAE;EAChC,MAAM,IAAI,EAAE,CAAC;EACb,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;EACrC,KAAK;EACL,IAAI,OAAO,IAAI,UAAU,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;EAC1D,GAAG;EAQH,EAAE,kCAAkC,CAAC,UAAU,EAAE,QAAQ,EAAE;EAC3D,IAAI,MAAM,SAAS,GAAGA,OAAK,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EAClI,IAAI,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;EAC5C,IAAI,OAAOA,OAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;EACrD,GAAG;EAQH,EAAE,mCAAmC,CAAC,UAAU,EAAE,QAAQ,EAAE;EAC5D,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC;EACjC,IAAI,MAAM,SAAS,GAAGA,OAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACvE,IAAI,MAAM,UAAU,GAAG,SAAS,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;EAClD,IAAI,OAAOA,OAAK,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;EACrD,GAAG;EAEH,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE;EAChB,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;EAC3C,GAAG;EAOH,EAAE,aAAa,CAAC,CAAC,EAAE,GAAG,EAAE;EACxB,IAAI,IAAI,GAAG,CAAC;EACZ,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE;EACpB,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC;EACrB,MAAM,IAAI,IAAI,GAAG,CAAC,CAAC;EACnB,MAAM,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE;EAC5B,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,QAAQ,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EACvB,OAAO;EACP,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;EAC1B,KAAK,MAAM,IAAI,CAAC,YAAY,OAAO,EAAE;EACrC,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC;EACrB,KAAK,MAAM,IAAI,CAAC,YAAY,KAAK,EAAE;EACnC,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC;EACnB,KAAK,MAAM;EACX,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;EACpD,KAAK;EAEL,IAAI,IAAI,GAAG,EAAE;EACb,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC5B,MAAM,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE;EAC7B,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACpB,OAAO;EACP,KAAK;EAEL,IAAI,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;EAC/B,GAAG;EAOH,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EACnC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EAChC,KAAK;EACL,GAAG;EAOH,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EACxC,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACrC,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,UAAU,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EAC1C,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE;EAC3B,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;EAC3B,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;EAChC,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;EACrC,UAAUA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAChD,SAAS,MAAM;EACf,UAAUA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAChD,SAAS;EACT,OAAO,MAAM;EACb,QAAQA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC9C,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EACxB,KAAK;EACL,GAAG;EAYH,EAAE,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE;EAC1B,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE;EACjD,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;EACvF,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,YAAY;EAEd,EAAE,eAAe,CAAC,GAAG,EAAE;EACvB,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;EAErB,IAAI,GAAG;EACP,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/D,KAAK,QAAQ,GAAG,GAAG,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;EAE/C,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAMH,EAAE,aAAa,CAAC,KAAK,EAAE;EACvB,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;EAC1B,MAAM,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;EACvC,KAAK,MAAM;EACX,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,GAAG;EAEH,EAAE,cAAc;EAChB,EAAE,mBAAmB;EAErB,EAAE,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;EAEpC,IAAI,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;EACtC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAElC,IAAI,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;EAClD,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EACnC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,EAAE,CAAC,EAAE;EACzC,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,WAAW,CAAC;EACxC,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;EAG1D,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;EAGpE,MAAM,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,GAAG,WAAW,CAAC,CAAC;EAG7E,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;EACrC,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EACtC,IAAI,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACpC,GAAG;EACH,EAAE,kBAAkB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAChD,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;EAC/B,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;EAClC,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,kBAAkB,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EACvD,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,MAAM,GAAG,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC;EACxD,QAAQ,MAAM,IAAI,GAAG,MAAM,GAAG,KAAK,CAAC;EACpC,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACnD,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,yBAAyB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EAC/C,IAAI,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACpC,GAAG;EACH,EAAE,2BAA2B;EAC7B,EAAE,2BAA2B;EAC7B,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EAChC,IAAI,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;EAC7C,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;EAC7B,MAAM,CAAC,IAAI,CAAC,CAAC;EACb,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAC1C,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;EAC/C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACtC,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;EAC/B,QAAQ,CAAC,IAAI,CAAC,CAAC;EACf,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EACjD,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;EACjD,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACxC,UAAU,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;EACjC,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,SAAS;EACT,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC/B,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EACjC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC7C,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAC3C,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACxC,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,CAAC;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;EAChB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC/C,QAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACnE,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EAClD,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EAC1C,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC;EACtE,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC;EAClB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EACjD,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACrE,SAAS;EACT,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC/B,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EACjC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC7C,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAC3C,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACxC,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,CAAC;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;EAChB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC/C,QAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACnE,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EAClD,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EAC1C,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC;EACtE,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC;EAClB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EACjD,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACrE,SAAS;EACT,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC/B,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK;EACjC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC7C,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK;EAC3C,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACrC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACxC,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,WAAW,CAAC;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;EAChB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EAC/C,QAAQ,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACnE,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,KAAK;EAClD,IAAI,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACpC,MAAM,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;EACvC,QAAQ,MAAM,QAAQ,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EAC1C,QAAQ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,CAAC,CAAC;EACtE,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC;EAClB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE;EACjD,UAAU,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACrE,SAAS;EACT,QAAQ,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC/B,OAAO;EACP,MAAM,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EAOH,EAAE,uBAAuB,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK;EACjD,IAAI,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC;EACjE,IAAI,IAAI,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;EACvC,IAAI,IAAI,CAAC,SAAS,EAAE;EACpB,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,GAAG,EAAE,CAAC;EAC1C,KAAK;EAEL,IAAI,MAAM,GAAG,GAAGC,WAAK,CAAC,MAAM,CAAC,CAAC;EAC9B,IAAI,MAAM,oBAAoB,GAAG,EAAE,CAAC;EAEpC,IAAI,SAAS,OAAO,CAAC,GAAG,EAAE;EAC1B,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,OAAO,GAAG,EAAE,CAAC;EAC3B,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC7C,UAAU,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACxC,SAAS;EACT,QAAQ,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAChC,OAAO;EACP,MAAM,QAAQ,GAAG,CAAC,IAAI;EACtB,QAAQ,KAAK,SAAS;EACtB,UAAU,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EACnC,QAAQ,KAAK,qBAAqB;EAClC,UAAU,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EACzG,QAAQ,KAAK,gBAAgB,EAAE;EAC/B,UAAU,MAAM,MAAM,GAAG,EAAE,CAAC;EAC5B,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,YAAY,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;EACrD,WAAW;EACX,UAAU,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,KAAK,qBAAqB;EAClC,UAAU,QAAQ,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI;EAC7C,YAAY,KAAK,eAAe,EAAE;EAClC,cAAc,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EAC/D,cAAc,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,IAAI,WAAW,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAChH,cAAc,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;EACvC,gBAAgB,MAAM,MAAM,GAAG,EAAE,CAAC;EAClC,gBAAgB,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAC3D,gBAAgB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACzD,kBAAkB,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAC5C,kBAAkB,IAAI,MAAM,KAAK,IAAI,EAAE,SAAS;EAChD,kBAAkB,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EACjD,kBAAkB,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;EAC5E,iBAAiB;EAEjB,gBAAgB,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EACvC,eAAe;EACf,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;EACjE,aAAa;EACb,YAAY,KAAK,cAAc;EAC/B,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3J,WAAW;EACX,UAAU,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;EACtF,YAAY,OAAO,EAAE,CAAC;EACtB,WAAW;EACX,UAAU,OAAO,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACrG,QAAQ,KAAK,gBAAgB,EAAE;EAC/B,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,EAAE;EACvD,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7I,WAAW;EACX,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;EACvF,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7I,WAAW;EACX,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAC3D,YAAY,oBAAoB,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EACxF,YAAY,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,WAAW,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;EAC7C,YAAY,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EACjG,YAAY,IAAI,WAAW,KAAK,IAAI,EAAE;EAEtC,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACvI,aAAa,MAAM;EACnB,cAAc,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAErD,cAAc,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC7G,aAAa;EACb,WAAW,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACpE,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACzI,WAAW,MAAM;EACjB,YAAY,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;EAClD,WAAW;EACX,SAAS;EACT,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EACnD,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9E,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE;EAC1B,YAAY,OAAO,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC9D,WAAW,MAAM;EACjB,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;EAC9D,WAAW;EACX,UAAU,KAAK,qBAAqB;EACpC,YAAY,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAClD,UAAU,KAAK,yBAAyB;EACxC,YAAY,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACrF,UAAU,KAAK,SAAS;EACxB,YAAY,OAAO,GAAG,CAAC,GAAG,CAAC;EAC3B,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,GAAG,CAAC,IAAI,CAAC;EAC5B,UAAU,KAAK,kBAAkB;EACjC,YAAY,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACtD,cAAc,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EACnD,aAAa;EACb,YAAY,IAAI,GAAG,CAAC,QAAQ,EAAE;EAC9B,cAAc,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;EACxE,aAAa;EACb,YAAY,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EACrE,UAAU,KAAK,gBAAgB;EAC/B,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,eAAe;EAC9B,YAAY,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1G,UAAU,KAAK,cAAc;EAC7B,YAAY,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACjH,UAAU,KAAK,sBAAsB;EACrC,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EAC9E,UAAU,KAAK,kBAAkB;EACjC,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;EAC7D,UAAU,KAAK,aAAa;EAC5B,YAAY,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC1E,UAAU,KAAK,gBAAgB;EAC/B,YAAY,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EACpD,UAAU,KAAK,eAAe;EAC9B,YAAY,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1D,UAAU,KAAK,cAAc;EAC7B,YAAY,OAAO,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxD,UAAU,KAAK,mBAAmB;EAClC,YAAY,OAAO,WAAW,CAAC;EAC/B,UAAU,KAAK,uBAAuB;EACtC,YAAY,OAAO,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EAC/F,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE;EACrC,cAAc,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;EACtC,aAAa;EACb,OAAO;EACP,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,sBAAsB,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC7D,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;EAChC,IAAI,IAAI,oBAAoB,CAAC,MAAM,GAAG,CAAC,EAAE;EACzC,MAAM,MAAM,6BAA6B,GAAG,EAAE,CAAC;EAC/C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,oBAAoB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5D,QAAQ,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;EAC3D,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE;EAC5C,UAAU,SAAS,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;EAC/C,SAAS;EACT,QAAQ,6BAA6B,CAAC,IAAI,CAACD,OAAK,CAAC,uBAAuB,CAAC,kBAAkB,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,CAAC;EAChH,OAAO;EACP,MAAM,OAAO,6BAA6B,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;EAC7D,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,CAAC,CAAC;;ECtqBK,MAAM,MAAM,CAAC;EAIpB,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACvE,GAAG;EAKH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oCAAoC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC1E,GAAG;EAMH,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACvE,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,OAAO,uBAAuB,GAAG;EACnC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oCAAoC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC1E,GAAG;EAEH,EAAE,OAAO,wBAAwB,GAAG;EACpC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,qCAAqC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC3E,GAAG;EAEH,EAAE,OAAO,cAAc,GAAG;EAC1B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACjE,GAAG;EAOH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EACpC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EACtC,QAAQ,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE;EACrC,QAAQ,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;EACxD,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;EACnC,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAMlC,IAAI,IAAI,CAAC,aAAa,GAAG,OAAO,MAAM,KAAK,QAAQ,GAAG,0BAA0B,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;EAChG,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAChC,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAOhC,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EAMzB,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EAMvB,IAAI,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;EAMvB,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;EAM3B,IAAI,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;EAM/B,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;EAM/B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EAMvB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EAMxB,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAM7B,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;EAMpB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAM1B,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAMhC,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAM/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAM3B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EAMzB,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;EAM3B,IAAI,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;EAO1B,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAO1B,IAAI,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;EAE7B,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EAExB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACzC,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;EACpC,IAAI,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;EAChC,IAAI,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC;EAC3C,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,GAAG;EAEH,EAAE,aAAa,CAAC,QAAQ,EAAE;EAC1B,IAAI,KAAK,IAAI,CAAC,IAAI,QAAQ,EAAE;EAC5B,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS;EAC3E,MAAM,QAAQ,CAAC;EACf,QAAQ,KAAK,QAAQ;EACrB,UAAU,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;EAC/C,YAAY,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;EAC5C,YAAY,SAAS;EACrB,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,WAAW;EACxB,UAAU,IAAI,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE;EAC3D,YAAY,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;EAC3F,YAAY,SAAS;EACrB,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,WAAW;EACxB,UAAU,IAAI,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE;EACpE,YAAY,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;EACxC,WAAW;EACX,UAAU,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EAChC,UAAU,SAAS;EACnB,OAAO;EACP,MAAM,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC5B,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;EACtD,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;EACzD,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;EACjE,GAAG;EAMH,EAAE,KAAK,GAAG;EACV,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACzE,GAAG;EAQH,EAAE,GAAG,GAAG;EACR,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;EACtE,GAAG;EAMH,EAAE,UAAU,GAAG;EACf,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,4BAA4B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC9E,GAAG;EAMH,EAAE,WAAW,GAAG;EAChB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC/E,GAAG;EAOH,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC/E,GAAG;EAQH,EAAE,cAAc,CAAC,IAAI,EAAE;EACvB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;EAC7B,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;EAC/B,QAAQ,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAChC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC9C,UAAU,MAAM,OAAO,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EACxE,UAAU,MAAM,IAAI,GAAG,OAAO,KAAK,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;EAClE,UAAU,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxC,UAAU,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EACpC,YAAY,IAAI;EAChB,WAAW,CAAC,CAAC;EACb,SAAS;EACT,OAAO;EACP,KAAK,MAAM;EACX,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1D,QAAQ,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EAClC,UAAU,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;EACrC,SAAS,CAAC,CAAC;EACX,OAAO;EACP,KAAK;EAGL,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAChD,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAEzD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,WAAW,KAAK,KAAK,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;EAC1E,MAAM,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;EACxD,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE;EACnD,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC;EACpD,KAAK;EACL,GAAG;EAKH,EAAE,cAAc,GAAG;EACnB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,kBAAkB,GAAG,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC;EACzD,IAAI,IAAI,kBAAkB,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC9B,KAAK;EACL,IAAI,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;EAChC,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,KAAK,IAAI,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACvC,QAAQ,IAAI,kBAAkB,EAAE;EAChC,UAAU,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAClF,UAAU,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;EAC1C,UAAU,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EACpC,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,WAAW,CAAC,CAAC;EACb,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EACpC,YAAY,IAAI;EAChB,YAAY,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;EAC1C,WAAW,CAAC,CAAC;EACb,SAAS;EACT,QAAQ,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;EAC9E,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,sBAAsB,CAAC,IAAI,EAAE;EAC/B,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;EACpC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;EACpC,MAAM,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;EACtC,QAAQ,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;EACxC,UAAU,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;EACvD,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;EAC7C,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EACjC,OAAO;EACP,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EAC3B,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,QAAQ,CAAC,IAAI,EAAE;EACjB,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;EACtB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,YAAY,CAAC,IAAI,EAAE;EACrB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;EAChC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,oBAAoB,CAAC,GAAG,EAAE;EAC5B,IAAI,IAAI,CAAC,iBAAiB,GAAG,GAAG,CAAC;EACjC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAKH,EAAE,YAAY,CAAC,SAAS,EAAE;EAC1B,IAAI,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;EAC/B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,gBAAgB,CAAC,aAAa,EAAE;EAClC,IAAI,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;EACvC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,YAAY,CAAC,SAAS,EAAE;EAC1B,IAAI,IAAI,OAAO,SAAS,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE;EAC5C,MAAM,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC;EAC5E,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;EACjC,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,kBAAkB,CAAC,eAAe,EAAE;EACtC,IAAI,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;EAC3C,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,iBAAiB,CAAC,cAAc,EAAE;EACpC,IAAI,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;EACzC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,WAAW,CAAC,IAAI,EAAE;EACpB,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACzB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,YAAY,CAAC,IAAI,EAAE;EACrB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,kBAAkB,CAAC,IAAI,EAAE;EAC3B,IAAI,cAAc,CAAC,QAAQ,EAAE,oBAAoB,EAAE,aAAa,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACzB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,YAAY,CAAC,IAAI,EAAE;EACrB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,iBAAiB,CAAC,IAAI,EAAE;EAC1B,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,oBAAoB,CAAC,IAAI,EAAE;EAC7B,IAAI,cAAc,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;EACrD,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;EAChC,IAAI,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;EACnC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,mBAAmB,CAAC,IAAI,EAAE;EAC5B,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,mBAAmB,CAAC,IAAI,EAAE;EAC5B,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,eAAe,CAAC,IAAI,EAAE;EACxB,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,SAAS,GAAG;EACd,IAAI,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;EAC1C,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC;EACvB,GAAG;EAMH,EAAE,QAAQ,GAAG;EACb,IAAI,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;EACzC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC;EACxB,GAAG;EAMH,EAAE,UAAU,CAAC,OAAO,EAAE;EACtB,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;EAC3B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,gBAAgB,CAAC,aAAa,EAAE;EAClC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;EACtC,MAAM,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC9B,MAAM,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE;EACrC,QAAQ,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EAC5D,QAAQ,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,CAAC,wBAAwB,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;EACpF,QAAQ,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;EAC7D,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,eAAe,CAAC,IAAI,EAAE;EACxB,IAAI,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE;EACjC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,mCAAmC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACvF,KAAK;EACL,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,OAAO,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;EACxC,GAAG;EAMH,EAAE,gBAAgB,GAAG;EACrB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,kCAAkC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACpF,GAAG;EAQH,EAAE,YAAY,CAAC,SAAS,EAAE;EAC1B,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EAClC,MAAM,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;EAC3B,KAAK;EACL,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;EAClF,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;EACnH,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;EAC9E,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACpC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,OAAO,CAAC,sBAAsB,EAAE;EAClC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACtE,GAAG;EAOH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EAErC,MAAM,OAAO,CAAC,CAAC;EACf,KAAK,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;EACxC,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EACxC,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,EAAE;EAC5C,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;EAC3C,KAAK;EACL,IAAI,QAAQ,KAAK,CAAC,WAAW;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,CAAC,CAAC;EACjB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,CAAC,CAAC;EACjB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,CAAC,CAAC;EACjB,KAAK;EACL,GAAG;EAKH,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,sBAAsB,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACxE,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;EAC7F,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;EAClG,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACvD,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,GAAG,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,2CAA2C,CAAC,CAAC,CAAC;EAC7J,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,QAAQ,GAAG;EACrB,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,MAAM,QAAQ,EAAE,IAAI,CAAC,QAAQ;EAC7B,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,cAAc,EAAE,IAAI,CAAC,aAAa;EACxC,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,MAAM,WAAW,EAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI;EAChF,MAAM,UAAU,EAAE,IAAI,CAAC,UAAU;EACjC,KAAK,CAAC;EACN,IAAI,OAAO;EACX,MAAM,QAAQ;EACd,KAAK,CAAC;EACN,GAAG;EACH,CAAC;;EC5tBM,MAAM,eAAe,CAAC;EAS7B,EAAE,OAAO,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE;EAC5D,IAAI,MAAM;EACV,MAAM,eAAe;EACrB,MAAM,eAAe;EACrB,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,MAAM,iBAAiB;EACvB,MAAM,SAAS;EACf,MAAM,iBAAiB;EACvB,MAAM,KAAK;EACX,MAAM,iBAAiB;EACvB,MAAM,eAAe;EACrB,MAAM,MAAM;EACZ,MAAM,mBAAmB;EACzB,MAAM,SAAS;EACf,MAAM,OAAO;EACb,MAAM,MAAM;EACZ,MAAM,UAAU;EAChB,MAAM,SAAS;EACf,MAAM,sBAAsB;EAC5B,MAAM,wBAAwB;EAC9B,MAAM,gBAAgB;EACtB,MAAM,aAAa;EACnB,MAAM,YAAY;EAClB,KAAK,GAAG,MAAM,CAAC;EAEf,IAAI,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;EAC5D,IAAI,MAAM,aAAa,GAAG,EAAE,CAAC;EAE7B,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,aAAa,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;EACjD,KAAK;EAEL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC,CAAC,EAAC;EAC/C,MAAM,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC;EAC/D,KAAK;EAEL,IAAI,MAAM,iBAAiB,GAAG,CAAC,YAAY,EAAE,KAAK,KAAK;EACvD,MAAM,OAAO,eAAe,CAAC,iBAAiB,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;EACpE,KAAK,CAAC;EAEN,IAAI,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,KAAK;EAC9D,MAAM,eAAe,CAAC,kBAAkB,CAAC,YAAY,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;EACpE,KAAK,CAAC;EAEN,IAAI,MAAM,gBAAgB,GAAG,CAAC,YAAY,EAAE,GAAG,EAAE,cAAc,KAAK;EACpE,MAAM,OAAO,eAAe,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;EACjF,KAAK,CAAC;EAEN,IAAI,MAAM,2BAA2B,GAAG,CAAC,YAAY,KAAK;EAC1D,MAAM,OAAO,eAAe,CAAC,2BAA2B,CAAC,YAAY,CAAC,CAAC;EACvE,KAAK,CAAC;EAEN,IAAI,MAAM,0BAA0B,GAAG,CAAC,YAAY,EAAE,aAAa,KAAK;EACxE,MAAM,OAAO,eAAe,CAAC,0BAA0B,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;EACrF,KAAK,CAAC;EAEN,IAAI,MAAM,8BAA8B,GAAG,CAAC,YAAY,EAAE,YAAY,KAAK;EAC3E,MAAM,OAAO,eAAe,CAAC,8BAA8B,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;EACxF,KAAK,CAAC;EAEN,IAAI,MAAM,wBAAwB,GAAG,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,KAAK;EACxF,MAAM,eAAe,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC;EACxF,KAAK,CAAC;EAEN,IAAI,MAAM,2BAA2B,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,aAAa,KAAK;EAC3G,MAAM,eAAe,CAAC,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,aAAa,CAAC,CAAC;EAC1G,KAAK,CAAC;EAEN,IAAI,MAAM,qBAAqB,GAAG,CAAC,kBAAkB,EAAE,YAAY,EAAE,YAAY,KAAK;EACtF,MAAM,OAAO,eAAe,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;EACnG,KAAK,CAAC;EAEN,IAAI,MAAM,cAAc,GAAG,CAAC,YAAY,EAAE,kBAAkB,EAAE,IAAI,KAAK;EACvE,MAAM,eAAe,CAAC,iBAAiB,CAAC,YAAY,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;EAChF,KAAK,CAAC;EAEN,IAAI,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK;EAClD,MAAM,MAAM,aAAa,GAAG,EAAE,CAAC;EAC/B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,MAAM,cAAc,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE;EACnF,QAAQ,UAAU,EAAE,IAAI;EACxB,QAAQ,GAAG;EACX,QAAQ,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI;EACzB,QAAQ,aAAa;EACrB,QAAQ,gBAAgB;EACxB,QAAQ,2BAA2B;EACnC,QAAQ,0BAA0B;EAClC,QAAQ,8BAA8B;EACtC,QAAQ,iBAAiB;EACzB,QAAQ,kBAAkB;EAC1B,QAAQ,wBAAwB;EAChC,QAAQ,2BAA2B;EACnC,QAAQ,qBAAqB;EAC7B,QAAQ,cAAc;EACtB,QAAQ,YAAY;EACpB,OAAO,CAAC,CAAC,CAAC;EACV,MAAM,cAAc,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;EAC3C,MAAM,eAAe,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;EACtD,KAAK,CAAC;EAEN,IAAI,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;EACtC,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,gBAAgB;EACtB,MAAM,gBAAgB;EACtB,MAAM,2BAA2B;EACjC,MAAM,0BAA0B;EAChC,MAAM,8BAA8B;EACpC,MAAM,iBAAiB;EACvB,MAAM,kBAAkB;EACxB,MAAM,wBAAwB;EAC9B,MAAM,2BAA2B;EACjC,MAAM,qBAAqB;EAC3B,MAAM,cAAc;EACpB,MAAM,mBAAmB;EACzB,MAAM,SAAS;EACf,MAAM,SAAS;EACf,MAAM,aAAa;EACnB,MAAM,iBAAiB;EACvB,MAAM,KAAK;EACX,MAAM,iBAAiB;EACvB,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,gBAAgB;EACtB,MAAM,aAAa;EACnB,KAAK,EAAE,gBAAgB,IAAI,EAAE,CAAC,CAAC;EAE/B,IAAI,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE;EAC3D,MAAM,YAAY,EAAE,IAAI;EACxB,MAAM,IAAI,EAAE,QAAQ;EACpB,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,MAAM,iBAAiB;EACvB,MAAM,sBAAsB;EAC5B,MAAM,wBAAwB;EAC9B,KAAK,CAAC,CAAC;EAEP,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,EAAE;EAC5D,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;EAChF,KAAK;EAEL,IAAI,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;EAE/D,IAAI,IAAI,aAAa,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,SAAS,EAAE;EACnB,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE;EACxE,QAAQ,UAAU,EAAE,EAAE,CAAC,UAAU;EACjC,QAAQ,aAAa,EAAE,EAAE,CAAC,aAAa;EACvC,QAAQ,MAAM;EACd,QAAQ,OAAO;EACf,QAAQ,SAAS;EACjB,QAAQ,aAAa;EACrB,QAAQ,iBAAiB;EACzB,QAAQ,mBAAmB;EAC3B,QAAQ,SAAS;EACjB,QAAQ,gBAAgB;EACxB,QAAQ,2BAA2B;EACnC,QAAQ,0BAA0B;EAClC,QAAQ,8BAA8B;EACtC,QAAQ,iBAAiB;EACzB,QAAQ,kBAAkB;EAC1B,QAAQ,wBAAwB;EAChC,QAAQ,2BAA2B;EACnC,QAAQ,qBAAqB;EAC7B,QAAQ,cAAc;EACtB,OAAO,CAAC,CAAC,CAAC;EACV,KAAK;EAEL,IAAI,IAAI,cAAc,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,UAAU,EAAE;EACpB,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK;EACrD,QAAQ,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;EAC3C,QAAQ,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE;EACvE,UAAU,IAAI;EACd,UAAU,WAAW,EAAE,IAAI;EAC3B,UAAU,YAAY,EAAE,KAAK;EAC7B,SAAS,CAAC,CAAC,CAAC;EACZ,OAAO,CAAC,CAAC;EACT,KAAK;EAEL,IAAI,MAAM,eAAe,GAAG,IAAI,eAAe,CAAC;EAChD,MAAM,MAAM;EACZ,MAAM,QAAQ;EACd,MAAM,aAAa;EACnB,MAAM,eAAe;EACrB,MAAM,cAAc;EACpB,KAAK,CAAC,CAAC;EAEP,IAAI,OAAO,eAAe,CAAC;EAC3B,GAAG;EAMH,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;EAClC,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;EACtC,IAAI,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,IAAI,EAAE,CAAC;EACtD,IAAI,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,cAAc,IAAI,EAAE,CAAC;EACxD,IAAI,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,eAAe,IAAI,EAAE,CAAC;EAC1D,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,mBAAmB,GAAG,EAAE,CAAC;EAClC,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC;EACvC,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAE5B,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE;EACvB,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACjD,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1D,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAC7E,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE;EAC7B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3D,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;EAC/E,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,eAAe,EAAE;EAC9B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5D,QAAQ,MAAM,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;EACvD,QAAQ,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC3D,OAAO;EACP,KAAK;EACL,GAAG;EAQH,EAAE,eAAe,CAAC,YAAY,EAAE;EAChC,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;EAC3E,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC;EACvD,IAAI,IAAI,YAAY,CAAC,YAAY,EAAE;EACnC,MAAM,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC;EACnC,KAAK;EACL,GAAG;EAaH,EAAE,kBAAkB,CAAC,YAAY,EAAE,OAAO,EAAE;EAC5C,IAAI,YAAY,GAAG,YAAY,IAAI,QAAQ,CAAC;EAC5C,IAAI,OAAO,GAAG,OAAO,IAAI,EAAE,CAAC;EAE5B,IAAI,IAAI,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE;EAC7D,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE;EAChD,QAAQ,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EACnC,OAAO;EACP,MAAM,OAAO,OAAO,CAAC;EACrB,KAAK;EAEL,IAAI,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EACxD,IAAI,IAAI,YAAY,EAAE;EAEtB,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;EAC1D,MAAM,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE;EAChC,QAAQ,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EACnC,QAAQ,YAAY,CAAC,QAAQ,EAAE,CAAC;EAChC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACtE,UAAU,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;EAC5E,SAAS;EACT,OAAO,MAAM;EAMb,QAAQ,MAAM,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,QAAQ,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EAC5C,OAAO;EACP,KAAK;EAEL,IAAI,OAAO,OAAO,CAAC;EACnB,GAAG;EAOH,EAAE,kBAAkB,CAAC,YAAY,EAAE;EACnC,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACvD,GAAG;EAOH,EAAE,aAAa,CAAC,YAAY,EAAE;EAC9B,IAAI,IAAI,IAAI,CAAC,QAAQ,EAAE;EACvB,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;EAC/B,KAAK;EACL,IAAI,IAAI,YAAY,EAAE;EACtB,MAAM,OAAO,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;EACtG,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,8BAA8B,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;EAC9E,GAAG;EAOH,EAAE,0BAA0B,CAAC,YAAY,EAAE;EAC3C,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EAClD,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;EACrD,MAAM,IAAI,IAAI,EAAE;EAChB,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;EAC/D,OAAO;EACP,KAAK;EACL,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,GAAG;EAOH,EAAE,8BAA8B,CAAC,YAAY,EAAE;EAC/C,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;EACnB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EAClD,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;EAC3E,MAAM,IAAI,aAAa,GAAG,CAAC,CAAC,EAAE;EAC9B,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;EAC7D,QAAQ,SAAS;EACjB,OAAO;EACP,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EAClD,MAAM,IAAI,IAAI,EAAE;EAChB,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;EAClC,OAAO;EACP,KAAK;EACL,IAAI,OAAO,GAAG,CAAC;EACf,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,IAAI,IAAI;EAC7E,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAC7D,MAAM,IAAI,WAAW,GAAG,CAAC,CAAC,EAAE;EAC5B,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,MAAM;EAC1D,SAAS,CAAC;EACV,OAAO,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;EACzC,QAAQ,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;EAC/C,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;EACxD,OAAO;EACP,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,QAAQ,CAAC,iBAAiB,EAAE,YAAY,EAAE;EAC5C,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;EAC1B,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC;EACpD,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,YAAY,CAAC,gBAAgB,CAAC,GAAG,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;EAC3H,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,SAAS,CAAC,YAAY,EAAE;EAC1B,IAAI,IAAI,YAAY,EAAE;EACtB,MAAM,OAAO,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;EAC9F,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;EAC1E,GAAG;EAEH,EAAE,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,cAAc,EAAE;EACtD,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACvC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,8CAA8C,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE;EAC9C,MAAM,OAAO,IAAI,CAAC,+BAA+B,CAAC,YAAY,CAAC,CAAC;EAChE,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE;EAC/C,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACnD,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE;EAC3B,QAAQ,OAAO,IAAI,CAAC,UAAU,CAAC;EAC/B,OAAO,MAAM;EACb,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAE1D,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE;EAG/C,YAAY,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;EAC7E,cAAc,MAAM,IAAI,GAAG,GAAG,CAAC,SAAS,CAAC;EACzC,cAAc,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,gBAAgB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;EACtC,kBAAkB,IAAI,EAAE,cAAc,CAAC,IAAI;EAC3C,kBAAkB,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;EAC9B,kBAAkB,cAAc;EAChC,iBAAiB,CAAC,CAAC;EACnB,gBAAgB,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACxE,gBAAgB,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;EACvC,eAAe;EACf,cAAc,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;EACrE,aAAa;EAEb,YAAY,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;EACzD,WAAW;EACX,SAAS;EAET,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;EAC9B,UAAU,IAAI,EAAE,cAAc,CAAC,IAAI;EACnC,UAAU,GAAG;EACb,UAAU,cAAc;EACxB,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;EACnD,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;EAC/B,QAAQ,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EACtC,OAAO;EACP,KAAK;EAGL,IAAI,OAAO,IAAI,CAAC;EAsDhB,GAAG;EAEH,EAAE,YAAY,CAAC,YAAY,EAAE;EAC7B,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,CAEpC;EACL,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EAC1C,GAAG;EAEH,EAAE,WAAW,CAAC,YAAY,EAAE;EAC5B,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;EACnD,GAAG;EAEH,EAAE,kBAAkB,CAAC,YAAY,EAAE;EACnC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1D,MAAM,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,OAAO,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;EACxF,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,iBAAiB,CAAC,YAAY,EAAE;EAClC,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC;EAC1D,GAAG;EAEH,EAAE,+BAA+B,CAAC,YAAY,EAAE;EAChD,IAAI,IAAI,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;EAC/D,IAAI,IAAI,cAAc,EAAE;EACxB,MAAM,OAAO,cAAc,CAAC,UAAU,CAAC;EACvC,KAAK;EACL,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,gBAAgB,GAAG,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;EACnE,GAAG;EAEH,EAAE,2BAA2B,CAAC,YAAY,EAAE;EAC5C,IAAI,IAAI,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,EAAE;EAC9C,MAAM,OAAO,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC;EACjE,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE;EAC/C,MAAM,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC;EAC3D,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,0BAA0B,CAAC,YAAY,EAAE,aAAa,EAAE;EAC1D,IAAI,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;EACxE,GAAG;EAEH,EAAE,8BAA8B,CAAC,YAAY,EAAE,YAAY,EAAE;EAC7D,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE;EACzC,MAAM,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;EAC5C,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE;EAC7C,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;EAClE,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;EACpB,QAAQ,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;EACxD,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACnD,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EACtE,MAAM,IAAI,CAAC,eAAe,EAAE;EAC5B,QAAQ,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;EACtD,OAAO;EACP,MAAM,OAAO,IAAI,CAAC,8BAA8B,CAAC,eAAe,CAAC,YAAY,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;EAC7G,KAAK;EACL,GAAG;EAEH,EAAE,iBAAiB,CAAC,YAAY,EAAE,CAAC,EAAE;EACrC,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO,KAAK,CAAC;EACtD,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACnD,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EACpC,GAAG;EAEH,EAAE,kBAAkB,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,cAAc,EAAE;EACpE,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO;EAChD,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACnD,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE;EAClC,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC;EAC7C,KAAK;EACL,GAAG;EAEH,EAAE,oBAAoB,CAAC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE;EACtF,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,EAAE,OAAO;EACtD,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE;EAC/B,MAAM,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAChC,KAAK;EACL,IAAI,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;EACjE,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,EAAE;EACnD,MAAM,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,GAAG,EAAE,CAAC;EACpD,KAAK;EACL,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG;EAC9C,MAAM,YAAY;EAClB,MAAM,YAAY;EAClB,MAAM,kBAAkB;EACxB,MAAM,kBAAkB;EACxB,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,qBAAqB,CAAC,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE;EACxE,IAAI,IAAI,kBAAkB,KAAK,YAAY,EAAE,OAAO,YAAY,CAAC;EACjE,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,OAAO,IAAI,CAAC;EACrD,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;EACjD,IAAI,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;EACvE,IAAI,IAAI,CAAC,eAAe,EAAE,OAAO,IAAI,CAAC;EACtC,IAAI,IAAI,eAAe,CAAC,kBAAkB,KAAK,YAAY,EAAE,OAAO,IAAI,CAAC;EACzE,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;EAC3B,IAAI,IAAI,kBAAkB,KAAK,YAAY,EAAE;EAC7C,MAAM,OAAO,IAAI,CAAC,qBAAqB,CAAC,kBAAkB,EAAE,eAAe,CAAC,YAAY,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;EACxH,KAAK;EACL,IAAI,OAAO,eAAe,CAAC,YAAY,CAAC;EACxC,GAAG;EAEH,EAAE,iBAAiB,CAAC,YAAY,EAAE,kBAAkB,EAAE,IAAI,EAAE;EAC5D,IAAI,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,EAAE;EACtD,MAAM,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;EAC9D,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;EAC5C,KAAK;EACL,IAAI,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;EACxE,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAChD,GAAG;EAEH,EAAE,mBAAmB,GAAG;EACxB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;EAChF,GAAG;EAEH,EAAE,sBAAsB,CAAC,KAAK,EAAE;EAChC,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;EACrD,IAAI,IAAI,MAAM,GAAG,KAAK,CAAC;EACvB,IAAI,KAAK,IAAI,iBAAiB,GAAG,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE;EACjH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC;EAC1E,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE;EAC/D,QAAQ,MAAM,GAAG,IAAI,CAAC;EACtB,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,EAAE;EACjB,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,UAAU,GAAG,aAAa,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC,CAAC;EAClF,KAAK;EACL,IAAI,OAAO,aAAa,CAAC,UAAU,IAAI,aAAa,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC;EACvF,GAAG;EAEH,EAAE,cAAc,GAAG;EACnB,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;EACpE,KAAK,CAAC;EACN,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EAC7D,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EACnC,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EAC1D,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;EACpE,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,CAAC;;ECvpBM,MAAM,cAAc,CAAC;EAC5B,EAAE,WAAW,CAAC,GAAG,EAAE;EACnB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;EACvB,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;EAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACnB,GAAG;EAEH,EAAE,IAAI,cAAc,GAAG;EACvB,IAAI,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;EAC1G,GAAG;EAEH,EAAE,UAAU,CAAC,GAAG,EAAE;EAClB,IAAI,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAC9D,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EACnC,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC1C,IAAI,GAAG,EAAE,CAAC;EACV,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,CAAC;EAC/B,GAAG;EAMH,EAAE,IAAI,CAAC,GAAG,EAAE;EACZ,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1B,OAAO;EACP,MAAM,OAAO;EACb,KAAK;EACL,IAAI,QAAQ,GAAG,CAAC,IAAI;EACpB,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM;EAC9B,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,sBAAsB,CAAC;EAClC,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC7B,QAAQ,MAAM;EACd,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC7B,QAAQ,MAAM;EACd,MAAM,KAAK,kBAAkB,CAAC;EAC9B,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM,KAAK,qBAAqB;EAChC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;EACpC,QAAQ,MAAM;EACd,MAAM,KAAK,oBAAoB;EAC/B,QAAQ,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;EACxC,QAAQ,MAAM,WAAW,GAAG;EAC5B,UAAU,GAAG,EAAE,GAAG;EAClB,UAAU,OAAO,EAAE,cAAc;EACjC,UAAU,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI;EAC3B,UAAU,MAAM,EAAE,aAAa;EAC/B,UAAU,YAAY,EAAE,IAAI,CAAC,UAAU;EACvC,UAAU,UAAU,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC;EACrF,SAAS,CAAC;EACV,QAAQ,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC;EAClD,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAC5C,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;EAC1B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,MAAM;EACd,MAAM,KAAK,oBAAoB,CAAC;EAChC,MAAM,KAAK,qBAAqB;EAChC,QAAQ,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;EAC/C,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACnC,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAClC,QAAQ,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;EACpD,QAAQ,MAAM;EACd,MAAM,KAAK,cAAc;EACzB,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM;EAC9B,UAAU,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EACjC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;EAClC,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;EAChC,UAAU,IAAI,CAAC,UAAU,CAAC,MAAM;EAChC,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAChC,WAAW,CAAC,CAAC;EACb,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,kBAAkB,CAAC;EAC9B,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM;EAC9B,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9B,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY;EACvB,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;EAC9B,UAAU,OAAO,EAAE,IAAI,CAAC,cAAc;EACtC,UAAU,GAAG;EACb,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACxC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;EAC9B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM,KAAK,qBAAqB;EAChC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAClC,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;EAChC,UAAU,OAAO,EAAE,IAAI,CAAC,cAAc;EACtC,UAAU,GAAG;EACb,SAAS,CAAC,CAAC;EACX,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;EACjC,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM,KAAK,uBAAuB;EAClC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;EACjC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAClC,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;EACpC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC7B,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY;EACvB,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAClC,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC7B,QAAQ,MAAM;EACd,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,mBAAmB,CAAC;EAC/B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACxD,KAAK;EACL,GAAG;EACH,CAAC;;ECpJM,MAAM,YAAY,CAAC;EAM1B,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE;EAClC,MAAM,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;EACrD,KAAK;EACL,IAAI,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,GAAG,QAAQ,CAAC,YAAY;EAClE,MAAM,QAAQ;EACd,OAAO,QAAQ,CAAC,IAAI,IAAI,yBAAyB,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;EAClE,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;EAChC,IAAI,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;EAC9B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;EACtB,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACzB,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;EACrB,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,2BAA2B,GAAG,IAAI,CAAC;EAC5C,IAAI,IAAI,CAAC,8BAA8B,GAAG,IAAI,CAAC;EAC/C,IAAI,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACzC,IAAI,IAAI,CAAC,4BAA4B,GAAG,IAAI,CAAC;EAC7C,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;EACpC,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,aAAa,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,GAAG,0BAA0B,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;EAC5G,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;EACrB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EACxB,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACzC,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;EACtC,IAAI,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC;EAC3C,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAE7B,IAAI,IAAI,QAAQ,EAAE;EAClB,MAAM,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE;EAChC,QAAQ,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS;EAClD,QAAQ,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS;EAC9C,QAAQ,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC9B,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;EAE3B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;EACpB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EACxB,IAAI,IAAI,CAAC,sBAAsB,GAAG,EAAE,CAAC;EACrC,GAAG;EAEH,EAAE,QAAQ,GAAG;EACb,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;EACtD,MAAM,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;EAClD,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;EACrD,MAAM,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;EAC3D,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;EACpB,MAAM,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;EACpD,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;EAClG,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;EACtH,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;EAChC,MAAM,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;EACvD,KAAK;EACL,GAAG;EAMH,EAAE,oBAAoB,CAAC,IAAI,EAAE;EAC7B,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,KAAK,CAAC;EACtC,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC/C,GAAG;EAEH,EAAE,OAAO,CAAC,YAAY,EAAE;EACxB,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,KAAK,OAAO,CAAC;EACpF,GAAG;EAEH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAC5B,GAAG;EAEH,EAAE,QAAQ,CAAC,KAAK,EAAE;EAClB,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE;EAC9B,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,gBAAgB,GAAG,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;EAC5E,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;EACtB,GAAG;EAEH,EAAE,OAAO,CAAC,KAAK,EAAE;EACjB,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC;EAChC,GAAG;EAEH,EAAE,IAAI,KAAK,GAAG;EACd,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EAC/C,GAAG;EAaH,EAAE,yBAAyB,CAAC,GAAG,EAAE;EACjC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE;EACnC,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC;EACtB,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAC9C,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACzC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE;EAEtC,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;EAC7E,UAAU,OAAO,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC9D,SAAS;EAET,QAAQ;EACR,UAAU,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC;EACpD,UAAU,GAAG;EACb,UAAU,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,QAAQ,CAAC;EACtD,UAAU;EACV,OAAO;EACP,KAAK;EAGL,IAAI,IAAI,GAAG,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE;EAC3C,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;EACjD,MAAM,IAAI,eAAe,CAAC,IAAI,KAAK,SAAS,IAAI,eAAe,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;EAC7G,QAAQ,OAAO,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;EAClE,OAAO;EACP,KAAK;EAGL,IAAI,MAAM,IAAI,CAAC,cAAc,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;EACxE,GAAG;EAUH,EAAE,QAAQ,CAAC,QAAQ,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE;EAClB,MAAM,OAAO,IAAI,CAAC,GAAG,CAAC;EACtB,KAAK;EACL,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE;EACzC,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACzC,MAAM,OAAO,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;EACpC,KAAK;EAEL,IAAI,MAAM,MAAM,GAAG,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,GAAGC,YAAK;EACxF,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE;EAC3B,MAAM,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;EAClD,KAAK;EAEL,IAAI,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;EACxF,MAAM,SAAS,EAAE,IAAI;EACrB,KAAK,CAAC,CAAC,CAAC;EAER,IAAI,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;EACzD,IAAI,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;EAEvC,IAAI,IAAI,CAAC,GAAG,EAAE;EACd,MAAM,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;EACjD,KAAK;EAEL,IAAI,OAAO,IAAI,CAAC,GAAG,GAAG,WAAW,CAAC;EAClC,GAAG;EAEH,EAAE,gBAAgB,CAAC,GAAG,EAAE;EACxB,IAAI,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;EACtG,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;EAC7B,IAAI,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;EACnC,IAAI,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;EACvC,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;EAC3B,IAAI,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;EAC/B,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC;EACnF,MAAM,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;EAC3B,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EACtD,MAAM,IAAI,SAAS,GAAG,IAAI,CAAC;EAE3B,MAAM,IAAI,YAAY,EAAE;EACxB,QAAQ,SAAS,GAAG,SAAS,CAAC;EAC9B,OAAO,MAAM;EACb,QAAQ,IAAI,IAAI,EAAE;EAClB,UAAU,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAC9C,UAAU,QAAQ,QAAQ;EAC1B,YAAY,KAAK,SAAS,CAAC;EAC3B,YAAY,KAAK,OAAO,CAAC;EACzB,YAAY,KAAK,QAAQ;EACzB,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACpD,gBAAgB,SAAS,GAAG,QAAQ,CAAC;EACrC,eAAe,MAAM;EACrB,gBAAgB,SAAS,GAAG,QAAQ,CAAC;EACrC,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,gBAAgB;EACjC,cAAc,SAAS,GAAG,QAAQ,CAAC;EACnC,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,SAAS,GAAG,QAAQ,CAAC;EACnC,WAAW;EACX,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;EAC7B,QAAQ,SAAS;EACjB,QAAQ,YAAY;EACpB,QAAQ,MAAM,EAAE,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC;EACrD,QAAQ,GAAG;EACX,QAAQ,IAAI;EACZ,QAAQ,OAAO;EACf,QAAQ,MAAM;EACd,QAAQ,UAAU;EAClB,OAAO,CAAC,CAAC;EACT,KAAK;EAEL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC/C,MAAM,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1C,KAAK;EACL,GAAG;EAEH,EAAE,cAAc,CAAC,GAAG,EAAE;EACtB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;EAC7C,MAAM,IAAI,GAAG,KAAK,UAAU,CAAC,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;EACjF,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3D,UAAU,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;EACnD,UAAU,IAAI,WAAW,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;EAC/G,YAAY,OAAO,WAAW,CAAC;EAC/B,WAAW;EACX,SAAS;EACT,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,eAAe,CAAC,GAAG,EAAE;EACvB,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE;EACnC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EAC7D,KAAK;EACL,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;EACpB,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC/D,IAAI,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE;EAC9B,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;EACnD,MAAM,IAAI,WAAW,EAAE;EACvB,QAAQ,OAAO,WAAW,CAAC,SAAS,CAAC;EACrC,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;EAC7D,MAAM,IAAI,YAAY,EAAE;EACxB,QAAQ,IAAI,GAAG,YAAY,CAAC;EAC5B,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,oBAAoB,EAAE;EAC5C,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;EAC1D,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,aAAa,CAAC,IAAI,EAAE;EACtB,IAAI,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAC7C,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,sBAAsB,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EACzD,KAAK;EACL,IAAI,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;EAC/B,GAAG;EAEH,EAAE,eAAe,CAAC,YAAY,EAAE;EAChC,IAAI,IAAI,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE;EAC1C,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;EACpD,MAAM,IAAI,IAAI,KAAK,OAAO,EAAE;EAC5B,QAAQ,OAAO,QAAQ,CAAC;EACxB,OAAO,MAAM;EACb,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,KAAK;EACL,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,mBAAmB,GAAG,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;EAC1E,GAAG;EAEH,EAAE,QAAQ,GAAG;EACb,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,CAAC,OAAO,CAAC;EAC1C,IAAI,OAAO,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;EAC/E,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,QAAQ,GAAG;EACrB,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI;EACrB,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,YAAY,EAAE,IAAI,CAAC,YAAY;EACrC,MAAM,WAAW,EAAE,IAAI,CAAC,WAAW;EACnC,MAAM,KAAK,EAAE,IAAI,CAAC,KAAK;EACvB,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;EAC/C,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,aAAa,EAAE,IAAI,CAAC,aAAa;EACvC,MAAM,UAAU,EAAE,IAAI,CAAC,UAAU;EACjC,MAAM,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;EACzD,MAAM,wBAAwB,EAAE,IAAI,CAAC,wBAAwB;EAC7D,KAAK,CAAC;EAEN,IAAI,OAAO;EACX,MAAM,GAAG,EAAE,IAAI,CAAC,GAAG;EACnB,MAAM,QAAQ;EACd,KAAK,CAAC;EACN,GAAG;EAOH,EAAE,OAAO,CAAC,GAAG,EAAE;EACf,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC5B,MAAM,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,QAAQ,GAAG,CAAC,IAAI;EACpB,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EACtC,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;EACjD,MAAM,KAAK,SAAS;EACpB,QAAQ,MAAM,UAAU,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EACrD,QAAQ,IAAI,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE;EAC3C,UAAU,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;EAC/C,SAAS;EACT,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;EACzC,UAAU,OAAO,gBAAgB,CAAC;EAClC,SAAS,MAAM,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,GAAG,CAAC,KAAK,KAAK,KAAK,EAAE;EAC9D,UAAU,OAAO,SAAS,CAAC;EAC3B,SAAS,MAAM;EACf,UAAU,OAAO,QAAQ,CAAC;EAC1B,SAAS;EACT,QAAQ,KAAK,sBAAsB;EACnC,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EACxC,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;EAC3C,YAAY,OAAO,QAAQ,CAAC;EAC5B,WAAW;EACX,UAAU,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;EAC/C,YAAY,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,oBAAoB,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE;EACrI,cAAc,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;EAC3G,cAAc,IAAI,CAAC,0BAA0B,CAAC,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;EAC3E,cAAc,OAAO,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;EACpE,aAAa;EACb,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;EACtE,WAAW;EACX,UAAU,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;EAC7C,YAAY,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;EACjD,YAAY,IAAI,CAAC,0BAA0B,CAAC,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;EACzE,YAAY,OAAO,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;EAClE,WAAW;EACX,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wBAAwB,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EACnF,QAAQ,KAAK,kBAAkB;EAE/B,UAAU,QAAQ,GAAG,CAAC,QAAQ;EAC9B,YAAY,KAAK,GAAG,CAAC;EACrB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,0BAA0B,EAAE;EACnD,gBAAgB,OAAO,QAAQ,CAAC;EAChC,eAAe,MAAM;EACrB,gBAAgB,MAAM;EACtB,eAAe;EACf,cAAc,KAAK,GAAG,CAAC;EACvB,cAAc,KAAK,GAAG;EACtB,gBAAgB,OAAO,SAAS,CAAC;EACjC,cAAc,KAAK,GAAG,CAAC;EACvB,cAAc,KAAK,GAAG,CAAC;EACvB,cAAc,KAAK,GAAG,CAAC;EACvB,cAAc,KAAK,IAAI,CAAC;EACxB,cAAc,KAAK,IAAI,CAAC;EACxB,cAAc,KAAK,KAAK;EACxB,gBAAgB,OAAO,SAAS,CAAC;EACjC,WAAW;EACX,UAAU,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC9C,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,OAAO,IAAI,CAAC;EACnE,UAAU,IAAI,IAAI,KAAK,gBAAgB,EAAE;EACzC,YAAY,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EACtD,YAAY,IAAI,SAAS,KAAK,gBAAgB,EAAE;EAChD,cAAc,IAAI,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE;EAC5C,gBAAgB,OAAO,SAAS,CAAC;EACjC,eAAe,MAAM;EACrB,gBAAgB,OAAO,OAAO,CAAC;EAC/B,eAAe;EACf,aAAa;EACb,YAAY,OAAO,SAAS,CAAC;EAC7B,WAAW;EACX,UAAU,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;EAC7C,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC5C,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE;EACpC,YAAY,OAAO,SAAS,CAAC;EAC7B,WAAW;EACX,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC5C,QAAQ,KAAK,qBAAqB,EAAE;EACpC,UAAU,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;EAChD,UAAU,IAAI,QAAQ,CAAC;EACvB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACxD,YAAY,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAChD,YAAY,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;EACjD,WAAW;EACX,UAAU,IAAI,CAAC,QAAQ,EAAE;EACzB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,mCAAmC,CAAC,EAAE,GAAG,CAAC,CAAC;EAClF,WAAW;EACX,UAAU,OAAO,QAAQ,CAAC;EAC1B,SAAS;EACT,QAAQ,KAAK,oBAAoB;EACjC,UAAU,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;EAC1D,UAAU,IAAI,CAAC,WAAW,EAAE;EAC5B,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,yBAAyB,CAAC,EAAE,GAAG,CAAC,CAAC;EACxE,WAAW;EAEX,UAAU,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE;EACtC,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,mCAAmC,CAAC,EAAE,GAAG,CAAC,CAAC;EAClF,WAAW;EAEX,UAAU,OAAO,WAAW,CAAC,SAAS,CAAC;EACvC,QAAQ,KAAK,YAAY;EACzB,UAAU,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,EAAE;EACvC,YAAY,OAAO,QAAQ,CAAC;EAC5B,WAAW;EACX,UAAU,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;EACvC,YAAY,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;EAC7D,YAAY,IAAI,SAAS,KAAK,OAAO,EAAE;EACvC,cAAc,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;EACrD,cAAc,IAAI,CAAC,IAAI,EAAE;EACzB,gBAAgB,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,mCAAmC,CAAC,EAAE,GAAG,CAAC,CAAC;EACtF,eAAe;EACf,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,WAAW;EACX,UAAU,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;EACxD,UAAU,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE;EACrC,YAAY,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;EAC7C,WAAW;EACX,UAAU,OAAO,IAAI,CAAC;EACtB,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC5C,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;EAC3C,YAAY,QAAQ,GAAG,CAAC,QAAQ,CAAC,IAAI;EACrC,cAAc,KAAK,MAAM;EACzB,gBAAgB,OAAO,SAAS,CAAC;EACjC,cAAc,KAAK,OAAO;EAC1B,gBAAgB,OAAO,SAAS,CAAC;EACjC,cAAc,KAAK,OAAO;EAC1B,gBAAgB,OAAO,SAAS,CAAC;EACjC,aAAa;EACb,YAAY,OAAO,QAAQ,CAAC;EAC5B,WAAW;EACX,UAAU,IAAI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;EACvC,YAAY,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;EACrE,YAAY,QAAQ,iBAAiB;EACrC,cAAc,KAAK,SAAS;EAC5B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAC5E,cAAc,KAAK,WAAW;EAC9B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;EACnF,cAAc,KAAK,aAAa;EAChC,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;EAC1F,cAAc,KAAK,eAAe;EAClC,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;EACjG,cAAc,KAAK,oBAAoB,CAAC;EACxC,cAAc,KAAK,mBAAmB;EACtC,gBAAgB,OAAO,SAAS,CAAC;EACjC,cAAc,KAAK,mBAAmB;EACtC,gBAAgB,OAAO,IAAI,CAAC,aAAa,GAAG,SAAS,GAAG,gBAAgB,CAAC;EACzE,cAAc,KAAK,sBAAsB;EACzC,gBAAgB,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EAC/D,cAAc,KAAK,wBAAwB;EAC3C,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1F,cAAc,KAAK,0BAA0B;EAC7C,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EACjG,cAAc,KAAK,4BAA4B;EAC/C,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EACxG,cAAc,KAAK,8BAA8B;EACjD,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EAC/G,cAAc,KAAK,QAAQ;EAC3B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EACpE,cAAc,KAAK,UAAU;EAC7B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EACpE,cAAc,KAAK,YAAY;EAC/B,gBAAgB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EACpE,cAAc,KAAK,aAAa;EAChC,gBAAgB,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;EACjD,kBAAkB,OAAO,QAAQ,CAAC;EAClC,iBAAiB;EACjB,gBAAgB,QAAQ,GAAG,CAAC,QAAQ,CAAC,IAAI;EACzC,kBAAkB,KAAK,GAAG;EAC1B,oBAAoB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAChF,kBAAkB,KAAK,GAAG;EAC1B,oBAAoB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAChF,kBAAkB,KAAK,GAAG;EAC1B,oBAAoB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAChF,kBAAkB,KAAK,GAAG;EAC1B,oBAAoB,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;EAChF,iBAAiB;EACjB,gBAAgB,KAAK,MAAM;EAC3B,kBAAkB,OAAO,QAAQ,CAAC;EAClC,aAAa;EACb,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;EACjF,WAAW;EACX,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;EAC/E,QAAQ,KAAK,uBAAuB;EACpC,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAC9C,QAAQ,KAAK,qBAAqB,CAAC;EACnC,QAAQ,KAAK,oBAAoB;EACjC,UAAU,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC3D,UAAU,IAAI,UAAU,EAAE;EAC1B,YAAY,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;EAC5C,WAAW;EACX,UAAU,OAAO,IAAI,CAAC;EACtB,QAAQ,KAAK,aAAa;EAC1B,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;EAC9C,QAAQ;EACR,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wBAAwB,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EACnF,KAAK;EACL,GAAG;EAEH,EAAE,0BAA0B,CAAC,YAAY,EAAE,IAAI,EAAE;EAEjD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,SAAS;EAC7D,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,IAAI,EAAE;EACjB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5E,OAAO;EACP,MAAM,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;EACrD,KAAK;EACL,GAAG;EAEH,EAAE,iBAAiB,CAAC,GAAG,EAAE;EACzB,IAAI,MAAM,cAAc,GAAG;EAC3B,MAAM,GAAG;EACT,MAAM,IAAI;EACV,MAAM,OAAO;EACb,MAAM,SAAS;EACf,MAAM,KAAK;EACX,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,QAAQ;EACd,KAAK,CAAC;EACN,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,kBAAkB;EAC1C,MAAM,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY;EACpD,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM;EAChC,MAAM,GAAG,CAAC,QAAQ;EAClB,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;EACxC,MAAM,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;EACrD,GAAG;EAEH,EAAE,iBAAiB,CAAC,GAAG,EAAE;EACzB,IAAI,MAAM,aAAa,GAAG;EAC1B,MAAM,KAAK;EACX,MAAM,MAAM;EACZ,MAAM,MAAM;EACZ,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,MAAM,KAAK;EACX,MAAM,OAAO;EACb,MAAM,KAAK;EACX,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,MAAM,KAAK;EACX,MAAM,KAAK;EACX,MAAM,QAAQ;EACd,MAAM,OAAO;EACb,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,MAAM,MAAM;EACZ,MAAM,KAAK;EACX,KAAK,CAAC;EACN,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,gBAAgB;EACxC,MAAM,GAAG,CAAC,MAAM;EAChB,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB;EAC5C,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM;EACvB,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,YAAY;EAC7C,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM;EACvC,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ;EACzB,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;EAC/C,MAAM,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;EAC3D,GAAG;EAEH,EAAE,aAAa,CAAC,GAAG,EAAE;EACrB,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,CAAC;EACxE,GAAG;EAEH,EAAE,MAAM,CAAC,GAAG,EAAE;EACd,IAAI,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;EAC9D,GAAG;EAEH,EAAE,kBAAkB,CAAC,YAAY,EAAE;EACnC,IAAI,OAAO,YAAY,IAAI,YAAY,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;EAC3G,GAAG;EASH,EAAE,eAAe,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE;EAChD,IAAI,IAAI,CAAC,YAAY,EAAE;EACvB,MAAM,YAAY,GAAG,EAAE,CAAC;EACxB,KAAK;EACL,IAAI,IAAI,CAAC,GAAG,EAAE,OAAO,IAAI,CAAC;EAC1B,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC9D,OAAO;EACP,MAAM,OAAO,YAAY,CAAC;EAC1B,KAAK;EACL,IAAI,QAAQ,GAAG,CAAC,IAAI;EACpB,MAAM,KAAK,sBAAsB;EACjC,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAChE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACjE,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,uBAAuB;EAClC,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAChE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACrE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACtE,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,SAAS;EACpB,QAAQ,YAAY,CAAC,IAAI,CAAC;EAC1B,UAAU,MAAM,EAAE,SAAS;EAC3B,UAAU,KAAK,EAAE,GAAG,CAAC,KAAK;EAC1B,UAAU,MAAM,EAAE,SAAS,KAAK,IAAI,GAAG,KAAK,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,KAAK,GAAG,QAAQ,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;EACjH,SAAS,CAAC,CAAC;EACX,QAAQ,MAAM;EACd,MAAM,KAAK,oBAAoB;EAC/B,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACvE,MAAM,KAAK,YAAY;EACvB,QAAQ,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;EACrD,QAAQ,IAAI,WAAW,EAAE;EACzB,UAAU,YAAY,CAAC,IAAI,CAAC;EAC5B,YAAY,IAAI,EAAE,GAAG,CAAC,IAAI;EAC1B,YAAY,MAAM,EAAE,aAAa;EACjC,YAAY,MAAM,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,YAAY,CAAC;EACzF,WAAW,CAAC,CAAC;EACb,SAAS,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;EAC9D,UAAU,YAAY,CAAC,IAAI,CAAC;EAC5B,YAAY,IAAI,EAAE,GAAG,CAAC,IAAI;EAC1B,YAAY,MAAM,EAAE,UAAU;EAC9B,YAAY,MAAM,EAAE,KAAK;EACzB,WAAW,CAAC,CAAC;EACb,SAAS,MAAM,IAAI,IAAI,CAAC,oBAAoB,EAAE;EAC9C,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,+BAA+B,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACzE,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,qBAAqB;EAChC,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACtG,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;EAChE,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,SAAS,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC;EACnE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAChE,QAAQ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACjE,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC3E,MAAM,KAAK,qBAAqB;EAChC,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC/E,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,YAAY,CAAC,IAAI,CAAC;EAC1B,UAAU,MAAM,EAAE,aAAa;EAC/B,UAAU,MAAM,EAAE,IAAI;EACtB,SAAS,CAAC,CAAC;EACX,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,YAAY,CAAC,IAAI,CAAC;EAC1B,UAAU,MAAM,EAAE,UAAU;EAC5B,UAAU,MAAM,EAAE,IAAI;EACtB,SAAS,CAAC,CAAC;EACX,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,MAAM,OAAO,GAAG,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC;EAC7D,QAAQ,QAAQ,OAAO,CAAC,SAAS;EACjC,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACtE,YAAY,MAAM;EAClB,UAAU,KAAK,WAAW;EAC1B,YAAY,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC7E,YAAY,MAAM;EAClB,UAAU,KAAK,aAAa;EAC5B,YAAY,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EACpF,YAAY,MAAM;EAClB,UAAU,KAAK,mBAAmB;EAClC,YAAY,IAAI,IAAI,CAAC,aAAa,EAAE;EACpC,cAAc,YAAY,CAAC,IAAI,CAAC;EAChC,gBAAgB,IAAI,EAAE,OAAO,CAAC,IAAI;EAClC,gBAAgB,MAAM,EAAE,QAAQ;EAChC,gBAAgB,MAAM,EAAE,KAAK;EAC7B,eAAe,CAAC,CAAC;EACjB,aAAa;EACb,YAAY,MAAM;EAClB,SAAS;EACT,QAAQ,IAAI,OAAO,EAAE;EACrB,UAAU,IAAI,OAAO,CAAC,QAAQ,EAAE;EAChC,YAAY,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC5E,WAAW;EACX,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE;EACjC,YAAY,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC7E,WAAW;EACX,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE;EACjC,YAAY,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC7E,WAAW;EACX,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE;EACjC,YAAY,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;EAC7E,WAAW;EACX,UAAU,OAAO,YAAY,CAAC;EAC9B,SAAS;EACT,QAAQ;EACR,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,eAAe,GAAG,GAAG,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,GAAG,CAAC,CAAC;EAC5F,KAAK;EACL,IAAI,OAAO,YAAY,CAAC;EACxB,GAAG;EAEH,EAAE,oBAAoB,CAAC,GAAG,EAAE;EAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE;EAClC,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,GAAG,GAAG,CAAC,IAAI,EAAE,6BAA6B,CAAC,CAAC,CAAC;EACjF,KAAK;EACL,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE;EACnC,MAAM,OAAO,OAAO,CAAC;EACrB,KAAK;EACL,IAAI,MAAM,SAAS,GAAG,EAAE,CAAC;EACzB,IAAI,OAAO,IAAI,EAAE;EACjB,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM;EACtB,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE;EACxB,QAAQ,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC7B,OAAO,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAChD,QAAQ,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;EAClC,OAAO,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE;EACpD,QAAQ;EACR,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG;EACnC,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG;EACnC,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG;EACnC,UAAU;EACV,UAAU,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACtC,SAAS,MAAM;EACf,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,WAAW;EAC3C,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ;EACxC,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ;EACxC,UAAU;EACV,UAAU,SAAS,CAAC,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;EACrD,SAAS,MAAM;EACf,UAAU,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACtC,SAAS;EACT,OAAO,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE;EAC3B,QAAQ,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;EACnC,OAAO,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;EAChD,QAAQ,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;EAClC,OAAO,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE;EAC/B,QAAQ,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAChC,OAAO,MAAM;EACb,QAAQ,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;EACrC,OAAO;EACP,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;EACvB,KAAK;EAEL,IAAI,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC/C,IAAI,MAAM,kBAAkB,GAAG;EAC/B,MAAM,OAAO;EACb,MAAM,SAAS;EACf,MAAM,WAAW;EACjB,MAAM,aAAa;EACnB,MAAM,eAAe;EACrB,MAAM,aAAa;EACnB,MAAM,oBAAoB;EAC1B,MAAM,mBAAmB;EACzB,MAAM,mBAAmB;EACzB,MAAM,sBAAsB;EAC5B,MAAM,wBAAwB;EAC9B,MAAM,0BAA0B;EAChC,MAAM,4BAA4B;EAClC,MAAM,8BAA8B;EACpC,MAAM,QAAQ;EACd,MAAM,UAAU;EAChB,MAAM,YAAY;EAClB,MAAM,MAAM;EACZ,KAAK,CAAC;EACN,IAAI,IAAI,kBAAkB,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE;EAC1D,MAAM,OAAO,eAAe,CAAC;EAC7B,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,KAAK,GAAG;EACV,IAAI,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;EACtC,GAAG;EAQH,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE;EAC1B,IAAI,IAAI,GAAG,KAAK,IAAI,EAAE;EACtB,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;EAC9B,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC7C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC;EACtB,OAAO;EAEP,MAAM,QAAQ,GAAG,CAAC,IAAI;EACtB,QAAQ,KAAK,qBAAqB;EAClC,UAAU,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC1D,QAAQ,KAAK,oBAAoB;EACjC,UAAU,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzD,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,KAAK,SAAS;EACtB,UAAU,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACvD,QAAQ,KAAK,YAAY;EACzB,UAAU,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC3D,QAAQ,KAAK,sBAAsB;EACnC,UAAU,OAAO,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC3D,QAAQ,KAAK,qBAAqB;EAClC,UAAU,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC1D,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,aAAa;EAC1B,UAAU,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,mBAAmB;EAChC,UAAU,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACxD,QAAQ,KAAK,cAAc;EAC3B,UAAU,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACnD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACvD,QAAQ,KAAK,qBAAqB;EAClC,UAAU,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC1D,QAAQ,KAAK,oBAAoB;EACjC,UAAU,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,oBAAoB;EACjC,UAAU,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzD,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACvD,QAAQ,KAAK,mBAAmB;EAChC,UAAU,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACxD,QAAQ,KAAK,kBAAkB;EAC/B,UAAU,OAAO,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACvD,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,KAAK,mBAAmB;EAChC,UAAU,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACxD,QAAQ,KAAK,uBAAuB;EACpC,UAAU,OAAO,IAAI,CAAC,wBAAwB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC5D,OAAO;EAEP,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,qBAAqB,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;EACvE,KAAK;EACL,GAAG;EAMH,EAAE,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE;EAC7B,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE;EACzC,MAAM,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EAC9B,KAAK;EAEL,IAAI,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;EACvD,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EACxD,IAAI,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;EACjD,IAAI,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACrF,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAAC,MAAM,EAAE,IAAI,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC;EACrH,GAAG;EAEH,EAAE,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE;EACxC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE;EACxC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,uBAAuB,EAAE;EAC9C,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAC;EACrE,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACtC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE;EAC3B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC/E,GAAG;EAQH,EAAE,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE;EACtC,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE;EACnC,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzC,GAAG;EACH,EAAE,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE;EACrC,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE;EACnC,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACzC,GAAG;EACH,EAAE,eAAe,CAAC,GAAG,EAAE;EACvB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;EACrC,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,KAAK;EACL,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EACH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE;EAC1B,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;EAC5D,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE;EACvC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE;EACvC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE;EACzC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EAC/C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE;EAC9B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE;EACpC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC1B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE;EACvC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EAC/B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE;EAC/B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE;EAC7C,IAAI,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;EACjD,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;EACpE,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAC;EACrE,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,gBAAgB,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC7C,IAAI,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC;EACvC,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACjF,IAAI,IAAI,IAAI,KAAK,gBAAgB,EAAE;EAEnC,MAAM,IAAI,GAAG,QAAQ,CAAC;EACtB,KAAK;EACL,IAAI,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;EACrC,IAAI,IAAI,CAAC,UAAU,EAAE;EACrB,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,YAAY,GAAG,UAAU,EAAE,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC;EACvF,KAAK;EACL,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;EACnE,IAAI,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;EAChE,MAAM,IAAI;EACV,MAAM,YAAY;EAClB,MAAM,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,IAAI,MAAM,UAAU,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACrE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;EACtC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EAGrC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;EACvD,MAAM,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;EACnC,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;EAC7D,QAAQ,IAAI;EACZ,QAAQ,YAAY;EACpB,QAAQ,MAAM,EAAE,KAAK;EACrB,OAAO,CAAC,CAAC;EACT,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;EAC3C,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;EAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE;EAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,IAAI,WAAW,CAAC,IAAI,KAAK,IAAI,EAAE;EACnC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAChD,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE;EACvC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE;EACpC,IAAI,MAAM,WAAW,GAAG,IAAI,CAAC,6BAA6B,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC1E,IAAI,IAAI,WAAW,EAAE;EACrB,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE;EACtB,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EAClC,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,6BAA6B,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;EAQjD,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE;EACrC,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE;EACtB,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;EAClC,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE;EACxC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,0BAA0B,CAAC,GAAG,EAAE;EAClC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACzC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,IAAI,EAAE,uBAAuB,CAAC,EAAE,GAAG,CAAC,CAAC;EACxF,KAAK;EACL,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;EACpB,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;EACpB,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;EAC7D,IAAI,QAAQ,iBAAiB;EAC7B,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,IAAI,CAAC;EACpB,MAAM,KAAK,oBAAoB,CAAC;EAChC,MAAM,KAAK,mBAAmB,CAAC;EAC/B,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,OAAO;EACf,UAAU,SAAS,EAAE,iBAAiB;EACtC,YAAY,IAAI,EAAE,SAAS;EAC3B,YAAY,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;EACjD,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;EAC/B,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,MAAM;EACxB,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC;EAClD,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,WAAW;EACtB,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;EACxD,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;EACtC,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,MAAM;EACxB,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;EACzD,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;EAC/D,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;EAC7C,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,MAAM;EACxB,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;EAChE,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ;EACjD,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,eAAe;EAC1B,QAAQ,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE;EACtE,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;EACpD,QAAQ,OAAO;EACf,UAAU,IAAI;EACd,UAAU,MAAM,EAAE,MAAM;EACxB,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;EACvE,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ;EACjD,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,SAAS,CAAC;EACV,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EACnD,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE;EACzC,UAAU,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;EACnC,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,MAAM;EAC1B,YAAY,IAAI,EAAE,QAAQ;EAC1B,YAAY,SAAS,EAAE,iBAAiB;EACxC,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,QAAQ,GAAG,CAAC,QAAQ,CAAC,IAAI;EACjC,UAAU,KAAK,GAAG,CAAC;EACnB,UAAU,KAAK,GAAG,CAAC;EACnB,UAAU,KAAK,GAAG,CAAC;EACnB,UAAU,KAAK,GAAG;EAClB,YAAY,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;EACnC,YAAY,OAAO;EACnB,cAAc,IAAI;EAClB,cAAc,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,IAAI;EACzC,gBAAgB,MAAM,EAAE,MAAM;EAC9B,gBAAgB,SAAS,EAAE,iBAAiB;EAC5C,gBAAgB,IAAI,EAAE,QAAQ;EAC9B,aAAa,CAAC;EACd,UAAU;EACV,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,SAAS;EACT,QAAQ,KAAK,sBAAsB;EACnC,UAAU,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EACrD,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;EACnC,UAAU,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,IAAI,EAAE;EACrB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;EACnE,WAAW;EACX,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,WAAW;EAC/B,cAAc,SAAS,EAAE,iBAAiB;EAC1C,WAAW,CAAC;EACZ,QAAQ,KAAK,wBAAwB;EACrC,UAAU,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EAC5D,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;EAC1C,UAAU,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,IAAI,EAAE;EACrB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;EACnE,WAAW;EACX,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,WAAW;EAC/B,cAAc,SAAS,EAAE,iBAAiB;EAC1C,cAAc,SAAS,EAAE,GAAG,CAAC,QAAQ;EACrC,WAAW,CAAC;EACZ,QAAQ,KAAK,0BAA0B,EAAE;EACzC,UAAU,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EACnE,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;EACjD,UAAU,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,IAAI,EAAE;EACrB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;EACnE,WAAW;EACX,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,WAAW;EAC/B,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,KAAK,4BAA4B,EAAE;EAC3C,UAAU,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE;EAC1E,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;EACxD,UAAU,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,IAAI,EAAE;EACrB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,GAAG,CAAC,CAAC;EACnE,WAAW;EACX,UAAU,OAAO;EACjB,YAAY,IAAI;EAChB,YAAY,IAAI;EAChB,YAAY,MAAM,EAAE,WAAW;EAC/B,YAAY,SAAS,EAAE,iBAAiB;EACxC,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ;EACjD,YAAY,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,QAAQ;EAC1C,YAAY,SAAS,EAAE,GAAG,CAAC,QAAQ;EACnC,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,MAAM;EACnB,UAAU,OAAO;EACjB,YAAY,SAAS,EAAE,iBAAiB;EACxC,cAAc,QAAQ,EAAE,GAAG,CAAC,QAAQ;EACpC,WAAW,CAAC;EACZ,QAAQ;EACR,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,KAAK;EACL,GAAG;EAEH,EAAE,oBAAoB,CAAC,SAAS,EAAE;EAClC,IAAI,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAE7B,IAAI,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;EAC7B,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;EAC9B,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,oBAAoB,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE;EACpH,QAAQ,OAAO,MAAM,CAAC;EACtB,OAAO;EACP,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;EACpB,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE;EAC3B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;EACpC,OAAO,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE;EAC9B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;EAChC,OAAO,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE;EACtC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;EACxC,OAAO,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;EACxC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,UAAU,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAChC,SAAS;EACT,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,cAAc,CAAC,GAAG,EAAE;EACtB,IAAI,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EAEpC,IAAI,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;EAC7B,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;EACjC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE;EAC7C,QAAQ,OAAO,MAAM,CAAC;EACtB,OAAO;EACP,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,qBAAqB,EAAE;EACjD,QAAQ,SAAS;EACjB,OAAO;EACP,MAAM,IAAI,MAAM,CAAC,QAAQ,EAAE;EAC3B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;EACpC,OAAO,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE;EAC9B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;EAChC,OAAO,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE;EACtC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;EACxC,OAAO,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;EACxC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,UAAU,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAChC,SAAS;EACT,OAAO,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE;EACpC,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;EACtC,OAAO,MAAM,IAAI,MAAM,CAAC,KAAK,EAAE;EAC/B,QAAQ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;EACjC,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,uBAAuB,CAAC,IAAI,EAAE;EAChC,IAAI,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAC3D,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC5C,KAAK;EACL,IAAI,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,EAAE,CAAC;EACxC,IAAI,IAAI,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;EACjD,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,IAAI,OAAO,IAAI,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;EACpD,GAAG;EAEH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAO,CAAC,IAAI,CAAC,iKAAiK,CAAC,CAAC;EACpL,GAAG;EACH,CAAC;EAED,MAAM,aAAa,GAAG;EACtB,EAAE,QAAQ,EAAE,QAAQ;EACpB,EAAE,OAAO,EAAE,OAAO;EAClB,EAAE,SAAS,EAAE,SAAS;EACtB,EAAE,OAAO,EAAE,QAAQ;EACnB,EAAE,UAAU,EAAE,QAAQ;EACtB,EAAE,UAAU,EAAE,QAAQ;EACtB,EAAE,UAAU,EAAE,QAAQ;EACtB,EAAE,SAAS,EAAE,QAAQ;EACrB,EAAE,SAAS,EAAE,QAAQ;EACrB,EAAE,OAAO,EAAE,QAAQ;EACnB,EAAE,WAAW,EAAE,UAAU;EACzB,EAAE,WAAW,EAAE,UAAU;EACzB,EAAE,gBAAgB,EAAE,UAAU;EAC9B,EAAE,eAAe,EAAE,QAAQ;EAC3B,EAAE,8BAA8B,EAAE,QAAQ;EAC1C,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,YAAY,EAAE,UAAU;EAC1B,EAAE,iBAAiB,EAAE,QAAQ;EAC7B,EAAE,iBAAiB,EAAE,UAAU;EAC/B,EAAE,iBAAiB,EAAE,UAAU;EAC/B,EAAE,iBAAiB,EAAE,UAAU;EAC/B,CAAC,CAAC;;EC99CK,MAAM,eAAe,SAAS,YAAY,CAAC;EAOlD,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE;EAG3B,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;EAC5B,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC9B,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC7B,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAGvB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EAC1D,QAAQ,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAEnD,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE;EACnB,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC5B,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC7B,QAAQ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAClC,OAAO;EAGP,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,KAAK;EAGL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACnD,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAChD,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxB,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;EAE5B,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAE/D,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC1B,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC7B,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;EAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;EAC/C,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;EACjD,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACjC,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE;EACjC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EACvD,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5D,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC7B,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE;EAG1B,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;EAC1B,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,sCAAsC,GAAG,GAAG,CAAC,KAAK;EAC1D,QAAQ,GAAG;EACX,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAE3B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACtC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;EACvC,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,0CAA0C;EAClD,QAAQ,OAAO;EACf,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,QAAQ,OAAO,CAAC,IAAI;EACxB,MAAM,KAAK,UAAU;EACrB,QAAQ,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAChC,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;EAC3E,UAAU,MAAM,CAAC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;EACnD,SAAS,MAAM;EACf,UAAU,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;EAC9C,SAAS;EACT,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE;EACzC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;EAClE,KAAK;EAEL,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,SAAS,GAAG,EAAE,CAAC;EACzB,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC;EAEtB,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC/C,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;EAC7D,UAAU,MAAM,GAAG,KAAK,CAAC;EACzB,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACxC,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE;EACxB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;EACjC,KAAK;EAGL,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE;EACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACtE,KAAK;EAEL,IAAI,IAAI,MAAM,EAAE;EAChB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5F,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK,MAAM;EACX,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EAClE,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;EAC7C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;EAClG,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;EAC1D,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE;EACvC,IAAI,IAAI,SAAS,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAC7C,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,yBAAyB;EACjC,QAAQ,SAAS;EACjB,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;EACxD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC5B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACvB,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAEvB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,WAAW,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACjD,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,yBAAyB;EACjC,QAAQ,WAAW;EACnB,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;EACxD,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC5B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACvB,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAEvB,IAAI,OAAO,MAAM,CAAC;EAElB,GAAG;EAQH,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAC3C,IAAI,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAC1D,IAAI,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE;EAChD,MAAM,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC,CAAC;EACrG,KAAK;EACL,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;EACnC,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;EACnC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;EAClC,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE;EAC7C,IAAI,IAAI,UAAU,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE;EACxD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;EACrB,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACvC,IAAI,MAAM,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,KAAK;EACL,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EAC3C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE;EACjC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACzC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACrD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACjD,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,KAAK;EAEL,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE;EAC1B,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACtD,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC7B,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAElB,GAAG;EAEH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;EACxC,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC3C,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE;EAClC,QAAQ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAClC,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACnE,UAAU,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAClC,SAAS;EACT,QAAQ,SAAS;EACjB,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC7C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACjE,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EAChC,OAAO;EACP,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACvB,GAAG;EAQH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE;EACrC,IAAI,MAAM;EACV,MAAM,SAAS;EACf,MAAM,IAAI;EACV,MAAM,QAAQ;EACd,MAAM,SAAS;EACf,MAAM,SAAS;EACf,MAAM,SAAS;EACf,MAAM,IAAI;EACV,MAAM,MAAM;EACZ,KAAK,GAAG,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;EAC/C,IAAI,QAAQ,SAAS;EACrB,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EAC9C,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,QAAQ,IAAI;EACpB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACnC,YAAY,MAAM;EAClB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACnC,YAAY,MAAM;EAClB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACnC,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EACtE,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,OAAO;EAClB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EAClE,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,aAAa,CAAC;EACzB,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE;EAC/B,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAClC,UAAU,OAAO,MAAM,CAAC;EACxB,SAAS;EACT,QAAQ,QAAQ,QAAQ;EACxB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7C,YAAY,OAAO,MAAM,CAAC;EAC1B,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,sBAAsB,CAAC;EAClC,MAAM,KAAK,wBAAwB,CAAC;EACpC,MAAM,KAAK,0BAA0B,CAAC;EACtC,MAAM,KAAK,4BAA4B;EACvC,QAAQ,MAAM;EACd,MAAM,KAAK,QAAQ;EACnB,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM;EACN,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EAClE,KAAK;EAEL,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;EAEzB,MAAM,QAAQ,IAAI;EAClB,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,SAAS,CAAC;EACvB,QAAQ,KAAK,OAAO,CAAC;EACrB,QAAQ,KAAK,SAAS;EACtB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3C,UAAU,OAAO,MAAM,CAAC;EACxB,OAAO;EACP,KAAK;EAIL,IAAI,MAAM,UAAU,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;EAE3C,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC;EACjB,QAAQ,IAAI,OAAO,CAAC;EACpB,QAAQ,IAAI,MAAM,KAAK,WAAW,EAAE;EACpC,UAAU,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;EAChD,UAAU,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC;EACzD,UAAU,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;EAChD,SAAS,MAAM;EACf,UAAU,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACvC,UAAU,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;EACvF,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC;EACvC,QAAQ,IAAI,SAAS,IAAI,SAAS,EAAE;EACpC,UAAU,IAAI,OAAO,EAAE;EACvB,YAAY,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC9B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,GAAG,qBAAqB,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;EACtG,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;EAC/E,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,WAAW,MAAM;EACjB,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,WAAW;EACX,SAAS,MAAM,IAAI,SAAS,EAAE;EAC9B,UAAU,IAAI,OAAO,EAAE;EACvB,YAAY,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC9B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;EAC/E,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,WAAW,MAAM;EACjB,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,WAAW;EACX,SAAS,MAAM,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE;EACrD,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,SAAS;EACT,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAEvC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;EAC/D,KAAK;EAEL,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;EAGlE,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;EACxD,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;EAGvD,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE;EAC7B,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;EAClE,KAAK;EAGL,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAG9B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,WAAW,GAAG,IAAI,CAAC,2BAA2B,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;EAE7E,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACnD,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EAGxC,MAAM,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EAChD,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;EAC3B,QAAQ,IAAI,CAAC,wBAAwB,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;EAC3E,OAAO;EAEP,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACxC,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE;EACtC,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;EAE3C,IAAI,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,EAAE;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,OAAO;EACP,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAC;EACtC,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAEtB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE;EACxC,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7B,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,CAAC;;ECloBD,SAAS,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE;EAC7C,EAAE,MAAM,OAAO,GAAG,EAAE,CAAC;EACrB,EAAE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;EAC5B,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,SAAS;EAC9C,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;EAC7B,IAAI,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;EACrC,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC5C,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1G,QAAQ,MAAM;EACd,KAAK;EACL,GAAG;EACH,EAAE,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;EACnC,CAAC;AAED,EAAO,SAAS,eAAe,CAAC,SAAS,EAAE,IAAI,EAAE;EACjD,EAAE,MAAM,MAAM,GAAG,EAAE,CAAC;EACpB,EAAE,MAAM,cAAc,GAAG,EAAE,CAAC;EAC5B,EAAE,MAAM,YAAY,GAAG,EAAE,CAAC;EAE1B,EAAE,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;EAE3E,EAAE,MAAM,CAAC,IAAI;EACb,IAAI,uEAAuE;EAC3E,IAAI,CAAC,gCAAgC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;EACvF,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAC1E,IAAI,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAC9F,GAAG,CAAC;EAEJ,EAAE,cAAc,CAAC,IAAI;EACrB,IAAI,4BAA4B;EAChC,IAAI,cAAc;EAClB,IAAI,aAAa;EACjB,IAAI,iCAAiC;EACrC,GAAG,CAAC;EAEJ,EAAE,IAAI,SAAS,CAAC,SAAS,EAAE;EAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,6CAA6C,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACjH,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,2CAA2C,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;EAEpH,IAAI,MAAM,OAAO,GAAGD,OAAK,CAAC,uBAAuB,CAAC,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE;EACxH,MAAM,UAAU,EAAE,CAAC,YAAY,KAAK;EACpC,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,YAAY,CAAC;EAChC,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,YAAY,CAAC;EAChC,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,QAAQ,CAAC;EAC5B,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,aAAa,CAAC;EACjC,SAAS;EACT,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;EACvD,OAAO;EACP,MAAM,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACxC,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,KAAK,CAAC,CAAC;EAEP,IAAI,MAAM,WAAW,GAAGA,OAAK,CAAC,uBAAuB,CAAC,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE;EAChI,MAAM,UAAU,EAAE,CAAC,YAAY,KAAK;EACpC,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,YAAY,CAAC;EAChC,UAAU,KAAK,YAAY;EAC3B,YAAY,OAAO,YAAY,CAAC;EAChC,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,QAAQ,CAAC;EAC5B,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,aAAa,CAAC;EACjC,SAAS;EACT,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;EACvD,OAAO;EACP,MAAM,cAAc,EAAE,MAAM;EAC5B,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,KAAK,CAAC,CAAC;EAEP,IAAI,cAAc,CAAC,IAAI;EACvB,MAAM,iBAAiB;EACvB,MAAM,iBAAiB;EACvB,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;EAC9B,KAAK,CAAC;EAEN,IAAI,YAAY,CAAC,IAAI;EACrB,MAAM,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAC,CAAC;EAC5C,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,MAAM,aAAa,GAAG,EAAE,CAAC;EAC3B,EAAE,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;EAC5D,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,IAAI,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;EAC9D,GAAG;EACH,EAAE,IAAI,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE;EAClH,IAAI,MAAM,uBAAuB,GAAGA,OAAK,CAAC,uBAAuB,CAAC,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE;EAClJ,MAAM,WAAW,EAAE,CAAC,QAAQ,CAAC;EAC7B,MAAM,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACxC,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE;EAC/B,UAAU,OAAO,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;EACtF,SAAS;EACT,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,MAAM,UAAU,EAAE,CAAC,YAAY,KAAK;EACpC,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO;EACnB,UAAU,KAAK,SAAS;EACxB,YAAY,OAAO,SAAS,CAAC;EAC7B,SAAS;EACT,OAAO;EACP,KAAK,CAAC,CAAC;EACP,IAAI,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;EAC/C,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAChD,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAChD,GAAG,MAAM,IAAI,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE;EAC/G,IAAI,MAAM,uBAAuB,GAAGA,OAAK,CAAC,uBAAuB,CAAC,CAAC,kBAAkB,GAAG,WAAW,GAAG,EAAE,IAAI,SAAS,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE;EAClJ,MAAM,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACxC,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,MAAM,UAAU,EAAE,CAAC,YAAY,KAAK;EACpC,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,QAAQ;EACvB,YAAY,OAAO,iBAAiB,CAAC;EACrC,UAAU,KAAK,SAAS;EACxB,YAAY,OAAO,kBAAkB,CAAC;EACtC,SAAS;EACT,QAAQ,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;EAChD,OAAO;EACP,KAAK,CAAC,CAAC;EACP,IAAI,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;EAC/C,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAChD,GAAG;EAEH,EAAE,OAAO,CAAC;AACV,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;AAuBtB,EAAE,SAAS,CAAC,aAAa,CAAC;;aAEb,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACvC,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;;CAE7B,CAAC,CAAC;EACH,CAAC;;ECpKM,MAAM,SAAS,SAAS,MAAM,CAAC;EACtC,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC;EACzB,GAAG;EACH,EAAE,WAAW,QAAQ,GAAG;EACxB,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC;EACzB,MAAM,SAAS,EAAE,IAAI;EACrB,MAAM,yBAAyB,EAAE,IAAI;EACrC,KAAK,CAAC,CAAC;EACP,GAAG;EACH,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAIH,EAAE,WAAW,IAAI,GAAG;EACpB,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAEH,EAAE,OAAO,uBAAuB,GAAG;EACnC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,OAAO,wBAAwB,GAAG;EACpC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,cAAc,EAAE;EACxC,IAAI,OAAO,cAAc,CAAC;EAC1B,GAAG;EAEH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;EAEpD,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG;EAClB,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,KAAK,CAAC;EACN,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAClC,GAAG;EAEH,EAAE,UAAU,GAAG;EACf,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACzC,MAAM,OAAO,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EAC9C,KAAK,MAAM,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE;EACvD,MAAM,OAAO,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACvC,KAAK;EACL,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC;EAClC,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,OAAO,EAAE,CAAC;EACd,GAAG;EAMH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAClD,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;EAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;EACtF,OAAO;EAEP,MAAM,MAAM,OAAO,GAAGA,OAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAC1E,MAAM,IAAI,OAAO,KAAK,OAAO,EAAE;EAC/B,QAAQ,IAAI,CAAC,MAAM,GAAGA,OAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;EACnD,OAAO,MAAM,IAAI,OAAO,KAAK,eAAe,IAAI,OAAO,KAAK,iBAAiB,EAAE;EAC/E,QAAQ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACrC,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,OAAO,CAAC,CAAC;EAChF,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EACpC,QAAQ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;EAC3E,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;EACvB,GAAG;EAEH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,eAAe,GAAG,cAAc,CAAC;EAC5F,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;EACzB,MAAM,MAAM,wBAAwB,GAAG,GAAE;EACzC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,QAAQ,MAAM;EACd,UAAU,IAAI;EACd,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC/B,QAAQ,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,EAAE,sBAAsB,GAAG,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,EAAE,sBAAsB,GAAG,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;EAC7K,OAAO;EACP,MAAM,IAAI,CAAC,wBAAwB,GAAG,wBAAwB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EACxE,KAAK;EACL,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;EAC9E,IAAI,IAAI,CAAC,iBAAiB,GAAG,eAAe,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EACrE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC7C,MAAM,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,mBAAmB,EAAE,CAAC;EAC9D,KAAK;EACL,GAAG;EASH,EAAE,KAAK,GAAG;EACV,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;EACnC,IAAI,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;EACrC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;EAE3B,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,QAAQ,MAAM;EACd,OAAO,GAAG,IAAI,CAAC;EACf,MAAM,IAAI,CAAC,MAAM,EAAE;EACnB,QAAQ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;EAC1E,OAAO;EACP,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;EAC9B,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;EAC3B,MAAM,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;EAC7B,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACpE,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,iBAAiB,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EAClE,KAAK;EAEL,IAAI,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;EAChD,IAAI,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;EAErC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;EACpB,MAAM,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;EACtC,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;EAChC,KAAK;EAEL,IAAI,IAAI;EACR,MAAM,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;EAC7D,KAAK,CAAC,OAAO,CAAC,EAAE;EAChB,MAAM,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,CAAC,CAAC,CAAC;EACvE,KAAK;EACL,GAAG;EAEH,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;EACpB,IAAI,IAAI,OAAO,CAAC,KAAK,WAAW,EAAE;EAClC,MAAM,CAAC,GAAG,CAAC,CAAC;EACZ,KAAK;EAEL,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;EAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;EAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;EAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;EAE5B,IAAI,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EACjC,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EAElC,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;EAC5B,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;EAEzC,IAAI,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;EAEhC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;EACvC,GAAG;EAYH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC,aAAa,CAAC;EAE/D,IAAI,IAAI,kBAAkB,GAAG,IAAI,CAAC;EAClC,IAAI,IAAI;EACR,MAAM,iBAAiB;EACvB,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE;EACtC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,MAAM,CAAC,EAAE,IAAI;EACzD,QAAQ,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;EAC5C,QAAQ,kBAAkB,GAAG,EAAE,CAAC;EAChC,QAAQ,OAAO,KAAK,CAAC;EACrB,OAAO,EAAC;EACR,KAAK,MAAM;EACX,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,KAAK,EAAE,CAAC;EACrD,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,aAAa,GAAG,CAAC,mBAAmB,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE;EAC/E,GAAG,IAAI,CAAC,cAAc,IAAI,EAAE,EAAE;;EAE9B,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE;UACrB,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;IACpF,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE;IAC7B,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,EAAE;IAChH,GAAG,iBAAiB,CAAC,MAAM,GAAG,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE;IACrE,CAAC,CAAC;EACN,GAAG;EAKH,EAAE,QAAQ,GAAG;EACb,IAAI,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC;EACjC,GAAG;EAMH,EAAE,iBAAiB,GAAG;EACtB,IAAI;EACJ,MAAM,IAAI,CAAC,iBAAiB;EAC5B,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;EAC/C,MAAM,QAAQ;EACd,MAAM;EACN,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC;EAEnC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;EAClC,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EACzC,MAAM,QAAQ,IAAI;EAClB,QAAQ,KAAK,WAAW,CAAC;EACzB,QAAQ,KAAK,WAAW;EACxB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,uCAAuC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EACjG,UAAU,MAAM;EAChB,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,uCAAuC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EACjG,UAAU,MAAM;EAChB,QAAQ,KAAK,OAAO;EACpB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;EACjF,UAAU,MAAM;EAChB,QAAQ;EACR,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EAC3E,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACxD,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3D,MAAM,QAAQ,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;EACnC,QAAQ,KAAK,WAAW,CAAC;EACzB,QAAQ,KAAK,WAAW;EACxB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,wBAAwB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;EACxF,UAAU,MAAM;EAChB,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,wBAAwB,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;EACxF,UAAU,MAAM;EAChB,QAAQ,KAAK,OAAO;EACpB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC;EACxE,UAAU,MAAM;EAChB,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,eAAe,CAAC;EAC7B,QAAQ,KAAK,8BAA8B;EAC3C,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC;QACf,EAAE,YAAY,CAAC;;;;;sDAK+B,EAAE,YAAY,CAAC;;QAE7D,EAAE,YAAY,CAAC;;gCAES,EAAE,YAAY,CAAC;QACvC,EAAE,YAAY,CAAC,GAAG,EAAE,YAAY,CAAC;8BACX,EAAE,YAAY,CAAC;;KAExC,CAAC,CAAC,CAAC;EACR,UAAU,MAAM;EAChB,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EAEH,EAAE,eAAe,CAAC,KAAK,EAAE;EACzB,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;EAC/B,IAAI,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC;EACnE,IAAI,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC;EACvE,IAAI,IAAI,MAAM,CAAC,KAAK,GAAG,KAAK,EAAE;EAC9B,MAAM,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;EAC3B,KAAK;EACL,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE;EAChC,MAAM,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;EAC7B,KAAK;EACL,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC;EAC7B,IAAI,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC;EAClE,IAAI,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;EACzC,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC;EAClB,IAAI,KAAK,IAAI,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;EACnD,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;EACtC,QAAQ,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,QAAQ,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;EAC7C,QAAQ,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;EAC7C,QAAQ,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;EAC7C,QAAQ,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;EAC7C,QAAQ,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;EACvB,OAAO;EACP,KAAK;EACL,IAAI,OAAO,UAAU,CAAC;EACtB,GAAG;EAEH,EAAE,SAAS,CAAC,IAAI,EAAE;EAClB,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;EAExC,IAAI,OAAO,IAAI,GAAGA,OAAK,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EACxG,GAAG;EAEH,EAAE,eAAe,CAAC,MAAM,EAAE;EAC1B,IAAI,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;EACjD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5C,MAAM,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACvD,KAAK;EACL,IAAI,OAAO,WAAW,CAAC;EACvB,GAAG;EAEH,EAAE,iBAAiB,CAAC,YAAY,EAAE;EAClC,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM;EAC9B,MAAM,KAAK,CAAC;EACZ,QAAQ,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;EAC7E,MAAM,KAAK,CAAC;EACZ,QAAQ,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;EAC7E,MAAM,KAAK,CAAC;EACZ,QAAQ,OAAO,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;EAC7E,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;EACnD,KAAK;EACL,GAAG;EAEH,EAAE,oBAAoB,CAAC,kBAAkB,EAAE;EAC3C,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM;EAC9B,MAAM,KAAK,CAAC;EACZ,QAAQ,OAAO,IAAI,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;EACzF,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;EACnD,KAAK;EACL,GAAG;EAEH,EAAE,gBAAgB,GAAG;EACrB,IAAI,OAAO,CAAC;;;WAGD,CAAC;EACZ,GAAG;EAEH,EAAE,qCAAqC,GAAG;EAC1C,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,cAAc,CAAC;EAC9B,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,OAAO,CAAC;EACvB,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;EAC5B,UAAU,OAAO,cAAc,CAAC;EAChC,SAAS;EACT,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;EACrE,KAAK;EACL,GAAG;EAEH,EAAE,mBAAmB,CAAC,YAAY,EAAE;AACpC,EAGA,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,qCAAqC,EAAE,CAAC;EAC3E,IAAI,OAAO,CAAC;uBACW,EAAE,iBAAiB,CAAC;IACvC,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC7H,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;;;;;MAK9F,GAAG,YAAY,EAAE;KAClB,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,mBAAmB,CAAC,YAAY,EAAE;AACpC,EAGA,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,qCAAqC,EAAE,CAAC;EAC3E,IAAI,OAAO,CAAC;;;IAGR,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC9G,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;;;;sCAI9D,EAAE,iBAAiB,CAAC;MACpD,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;;;QAGtJ,GAAG,YAAY,EAAE;;KAEpB,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,sBAAsB,CAAC,YAAY,EAAE;AACvC,EAGA,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,qCAAqC,EAAE,CAAC;EAC3E,IAAI,OAAO,CAAC;;IAER,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC9G,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;;;;MAI9F,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE;;;QAGtJ,GAAG,YAAY,EAAE;;KAEpB,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,mBAAmB,CAAC,YAAY,EAAE;AACpC,EAGA,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,qCAAqC,EAAE,CAAC;EAC3E,IAAI,OAAO,CAAC;;;;IAIR,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;IAC9G,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;;;;MAI9F,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;;;yCAG5G,EAAE,iBAAiB,CAAC;QACrD,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;;;UAG/J,GAAG,YAAY,EAAE;;;KAGtB,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,aAAa,GAAG;EAClB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC1B,MAAM,OAAO,sBAAsB,CAAC;EACpC,KAAK;EACL,IAAI,OAAO,CAAC;;MAEN,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;MAC9G,CAAC,CAAC;EACR,GAAG;EAEH,EAAE,cAAc,CAAC,EAAE,EAAE;EACrB,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,IAAI,GAAG,CAAC,EAAE,CAAC;EAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;EAC9B,GAAG;EAIH,EAAE,OAAO,CAAC,qBAAqB,EAAE;EACjC,IAAI,IAAI,qBAAqB,EAAE;EAC/B,MAAM,OAAO,IAAI,CAAC,MAAM,CAAC;EACzB,KAAK;EACL,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE,EAAE;EAEnC,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;EAChC,IAAI,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC;EACpF,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;EAC5B,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;EACxC,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACpE,MAAM,IAAI,CAAC,UAAU,GAAG,IAAI,iBAAiB,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EAClE,KAAK;EACL,GAAG;EACH,CAAC;;EChhBM,MAAM,cAAc,SAAS,OAAO,CAAC;EAC5C,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,MAAM,WAAW,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;EAC/C,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,oBAAoB;EAC3B,MAAM,EAAE,CAAC,WAAW;EACpB,MAAM,EAAE,CAAC,iBAAiB;EAC1B,MAAM,EAAE,CAAC,UAAU;EACnB,MAAM,IAAI,CAAC,OAAO;EAClB,MAAM,CAAC;EACP,KAAK,CAAC;EACN,IAAI,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACrE,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC/E,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,YAAY,GAAG;EACjB,IAAI,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACjE,GAAG;EACH,CAAC;;EC1BM,MAAM,oBAAoB,SAAS,cAAc,CAAC;EACzD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClF,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpG,GAAG;EACH,CAAC;;ECRM,MAAM,oBAAoB,SAAS,cAAc,CAAC;EACzD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClE,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpG,GAAG;EACH,CAAC;;ECRM,MAAM,oBAAoB,SAAS,cAAc,CAAC;EACzD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClE,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,GAAG;EACH,CAAC;;ECRM,MAAM,sBAAsB,SAAS,cAAc,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACpG,GAAG;EACH,CAAC;;ECRM,MAAM,gBAAgB,SAAS,cAAc,CAAC;EACrD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACnF,GAAG;EACH,CAAC;;ECRM,MAAM,gBAAgB,SAAS,cAAc,CAAC;EACrD,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACnG,GAAG;EACH,CAAC;;ECRM,MAAM,wBAAwB,SAAS,cAAc,CAAC;EAC7D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;EAC/C,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,yBAAyB,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAChF,GAAG;EACH,CAAC;;ECRM,MAAM,0BAA0B,SAAS,cAAc,CAAC;EAC/D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;EAC/C,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClG,GAAG;EACH,CAAC;;ECRM,MAAM,0BAA0B,SAAS,cAAc,CAAC;EAC/D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;EAC/C,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAClH,GAAG;EACH,CAAC;;ECRM,MAAM,iBAAiB,SAAS,OAAO,CAAC;EAC/C,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;EAChC,GAAG;EACH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,MAAM,WAAW,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;EAC/C,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,oBAAoB;EAC3B,MAAM,EAAE,CAAC,WAAW;EACpB,MAAM,EAAE,CAAC,iBAAiB;EAC1B,MAAM,EAAE,CAAC,UAAU;EACnB,MAAM,IAAI,CAAC,OAAO;EAClB,MAAM,CAAC;EACP,KAAK,CAAC;EACN,IAAI,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACnE,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;EACvF,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,EAAE,YAAY,GAAG;EACjB,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC,CAAC;EAC3D,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACvE,GAAG;EACH,CAAC;;EC1BM,MAAM,mBAAmB,SAAS,iBAAiB,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;EAChC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACzF,GAAG;EACH,CAAC;;ECRM,MAAM,mBAAmB,SAAS,iBAAiB,CAAC;EAC3D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;EAChC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAOA,OAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACzG,GAAG;EACH,CAAC;;ECTM,MAAM,kBAAkB,SAAS,iBAAiB,CAAC;EAC1D,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;EACpB,IAAI,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;EAClC,GAAG;EACH,EAAE,OAAO,GAAG;EACZ,IAAI,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;EAC/B,GAAG;EACH,CAAC;;ECgBM,MAAM,QAAQ,SAAS,MAAM,CAAC;EACrC,EAAE,WAAW,IAAI,GAAG;EACpB,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAEH,EAAE,OAAO,cAAc,GAAG;EAC1B,IAAI,MAAM,YAAY,GAAG,CAAC;;KAErB,CAAC,CAAC;EACP,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,YAAY,EAAE;EAC1C,MAAM,OAAO,EAAE,IAAI,CAAC,WAAW;EAC/B,MAAM,MAAM,EAAE,IAAI,CAAC,UAAU;EAC7B,MAAM,QAAQ,EAAE,KAAK;EACrB,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC;EACjB,MAAM,SAAS,EAAE,QAAQ;EACzB,MAAM,UAAU,EAAE,QAAQ;EAC1B,MAAM,MAAM,EAAE,OAAO;EACrB,KAAK,CAAC,CAAC;EACP,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;EACnB,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;EACjB,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;EACzC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACzB,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;EAC3B,GAAG;EAEH,EAAE,OAAO,4BAA4B,GAAG;EACxC,IAAI,SAAS,cAAc,CAAC,EAAE,EAAE,EAAE,EAAE;EACpC,MAAM,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EACnD,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE;EACvD,MAAM,OAAO,EAAE,IAAI,CAAC,WAAW;EAC/B,MAAM,MAAM,EAAE,IAAI,CAAC,UAAU;EAC7B,MAAM,QAAQ,EAAE,KAAK;EACrB,MAAM,MAAM,EAAE,CAAC,CAAC,CAAC;EACjB,MAAM,UAAU,EAAE,QAAQ;EAC1B,MAAM,SAAS,EAAE,UAAU;EAC3B,MAAM,MAAM,EAAE,OAAO;EACrB,KAAK,CAAC,CAAC;EACP,IAAI,MAAM,IAAI,GAAG;EACjB,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC;EAClB,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC;EACf,KAAK,CAAC;EACN,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACrC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACnC,IAAI,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;EACzC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAGzB,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;EACjD,GAAG;EAKH,EAAE,WAAW,UAAU,GAAG;EAC1B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,4BAA4B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAClE,GAAG;EAKH,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EACnE,GAAG;EAKH,EAAE,WAAW,QAAQ,GAAG;EACxB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAChE,GAAG;EAKH,EAAE,OAAO,kBAAkB,GAAG;EAC9B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oCAAoC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC1E,GAAG;EAMH,EAAE,6BAA6B,CAAC,GAAG,EAAE;EACrC,IAAI,IAAI,CAAC,0BAA0B,GAAG,GAAG,CAAC;EAC1C,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAMH,EAAE,YAAY,CAAC,IAAI,EAAE;EACrB,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAIA,OAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,kBAAkB,EAAE,wBAAwB,CAAC,CAAC;EACjF,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,OAAO,uBAAuB,CAAC,MAAM,EAAE;EACzC,IAAI,MAAM,aAAa,GAAG,EAAE,CAAC;EAC7B,IAAI,MAAM,aAAa,GAAG,EAAE,CAAC;EAC7B,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,sBAAsB,GAAG,YAAY,CAAC;EAChD,IAAI,MAAM,cAAc,GAAG,cAAc,CAAC;EAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC;EAC5B,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE;EAC9B,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;EAC7B,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACrC,MAAM,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC;EAGzE,MAAM,IAAI,KAAK,KAAK,oBAAoB,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,EAAE;EAC9E,QAAQ,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAC1C,QAAQ,CAAC,IAAI,CAAC,CAAC;EACf,QAAQ,SAAS;EACjB,OAAO,MAAM,IAAI,KAAK,KAAK,oBAAoB,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,EAAE;EACrF,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC;EACrB,QAAQ,CAAC,IAAI,CAAC,CAAC;EACf,QAAQ,SAAS;EACjB,OAAO;EAIP,WAAW,IAAI,KAAK,KAAK,oBAAoB,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,EAAE;EACnF,QAAQ,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC/B,QAAQ,CAAC,IAAI,CAAC,CAAC;EACf,QAAQ,SAAS;EACjB,OAAO,MAAM,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,EAAE;EACvD,QAAQ,MAAM,CAAC,GAAG,EAAE,CAAC;EACrB,QAAQ,CAAC,EAAE,CAAC;EACZ,QAAQ,SAAS;EACjB,OAAO;EAIP,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,EAAE;EAC/C,QAAQ,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAC1C,QAAQ,CAAC,EAAE,CAAC;EACZ,QAAQ,SAAS;EACjB,OAAO,MAAM,IAAI,KAAK,KAAK,oBAAoB,EAAE;EACjD,QAAQ,IAAI,IAAI,KAAK,GAAG,EAAE;EAC1B,UAAU,MAAM,CAAC,GAAG,EAAE,CAAC;EACvB,UAAU,MAAM;EAChB,SAAS;EACT,QAAQ,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EAClJ,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,OAAO,CAAC;EACjC,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EACvG,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,KAAK,CAAC;EAC/B,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EAChI,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,MAAM,CAAC;EAChC,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EAChI,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,MAAM,CAAC;EAChC,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS,MAAM,IAAI,IAAI,KAAK,GAAG,IAAI,QAAQ,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;EAChI,UAAU,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;EAC1C,UAAU,YAAY,GAAG,MAAM,CAAC;EAChC,UAAU,YAAY,GAAG,EAAE,CAAC;EAC5B,UAAU,CAAC,IAAI,CAAC,CAAC;EACjB,UAAU,SAAS;EACnB,SAAS;EACT,OAAO;EAIP,WAAW,IAAI,KAAK,KAAK,kBAAkB,EAAE;EAC7C,QAAQ,IAAI,YAAY,KAAK,EAAE,EAAE;EACjC,UAAU,IAAI,IAAI,KAAK,GAAG,EAAE;EAC5B,YAAY,CAAC,EAAE,CAAC;EAChB,YAAY,SAAS;EACrB,WAAW;EACX,UAAU,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;EAClD,YAAY,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;EACpE,WAAW;EACX,SAAS;EACT,QAAQ,YAAY,IAAI,IAAI,CAAC;EAC7B,QAAQ,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;EAC5C,UAAU,MAAM,CAAC,GAAG,EAAE,CAAC;EACvB,UAAU,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC3C,UAAU,aAAa,CAAC,IAAI,CAACE,SAAO,CAAC,YAAY,CAAC,CAAC,CAAC;EACpD,SAAS;EACT,OAAO;EAIP,MAAM,CAAC,EAAE,CAAC;EACV,KAAK;EACL,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;EAC3B,MAAM,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;EACxD,KAAK;EACL,IAAI,OAAO;EACX,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,OAAO,wBAAwB,CAAC,MAAM,EAAE;EAC1C,IAAI,OAAOA,SAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1D,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,cAAc,EAAE,UAAU,EAAE;EACpD,IAAI,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;EAC1C,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,OAAO;EACb,MAAM,SAAS;EACf,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC;EAC3B,IAAI,IAAI,MAAM,CAAC;EACf,IAAI,IAAI,UAAU,CAAC,SAAS,KAAK,QAAQ,EAAE;EAC3C,MAAM,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAC3B,MAAM,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EAC1C,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC9E,KAAK,MAAM;EACX,MAAM,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EAChE,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;EACnG,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EAE5E,IAAI,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EACxC,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAC/C,MAAM,OAAOF,OAAK,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5D,KAAK,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAC/C,MAAM,MAAM,IAAI,GAAGA,OAAK,CAAC,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACzF,MAAM,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;EAClC,QAAQ,OAAOA,OAAK,CAAC,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EACzD,OAAO,CAAC,CAAC;EACT,KAAK;EACL,GAAG;EAEH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAChC,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EACxB,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;EACrC,GAAG;EAEH,EAAE,gBAAgB,GAAG;EACrB,IAAI,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;EAC1C,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,cAAc,EAAE;EAChG,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,qDAAqD,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;EACxL,KAAK;EACL,GAAG;EAEH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACjF,GAAG;EAOH,EAAE,kBAAkB,CAAC,IAAI,EAAE;EAC3B,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,4BAA4B,CAAC;EAC/D,MAAM,IAAI,CAAC,cAAc,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC;EAC/C,MAAM,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;EACnD,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE;EACvC,MAAM,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,4BAA4B,CAAC;EAC/D,MAAM,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,8BAA8B,CAAC;EAChE,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC;EAC/C,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EACtC,UAAU,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC;EAC5D,SAAS;EACT,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;EAC5D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;EAC5D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;EAC1D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU;EACzB,YAAY,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC9C,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EACtC,UAAU,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC;EAC1D,SAAS;EACT,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;EAClD,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;EAC5D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,kBAAkB,CAAC;EAC3D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,mBAAmB,CAAC;EAC5D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,kBAAkB,CAAC;EAC3D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC;EAC1D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,gBAAgB,CAAC;EACzD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EAEb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU;EACzB,YAAY,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC9C,SAAS;EACT,OAAO;EACP,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EAC5C,MAAM,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,6BAA6B,CAAC;EAChE,MAAM,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,6BAA6B,CAAC;EAC/D,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,YAAY,CAAC;EAC1D,QAAQ,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC;EAC/C,QAAQ,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EACtC,UAAU,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC;EAC5D,SAAS;EACT,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,mBAAmB,EAAE;EAC1C,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACtC,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,0BAA0B,CAAC;EACrE,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC7C,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,0BAA0B,CAAC;EACrE,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe,MAAM;EACrB,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,wBAAwB,CAAC;EACnE,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe;EACf,aAAa,MAAM;EACnB,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACtC,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC;EAC3D,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC7C,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC;EAC3D,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe,MAAM;EACrB,gBAAgB,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC;EACzD,gBAAgB,OAAO,IAAI,CAAC;EAC5B,eAAe;EACf,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;EAC5C,MAAM,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EACpC,QAAQ,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC;EACxD,OAAO;EACP,MAAM,IAAI,IAAI,CAAC,mBAAmB,EAAE;EACpC,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,0BAA0B,CAAC;EACnE,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,iDAAiD,CAAC;EACrG,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,2BAA2B,CAAC;EACpE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,0BAA0B,CAAC;EACnE,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,iDAAiD,CAAC;EACrG,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,2BAA2B,CAAC;EACpE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,wBAAwB,CAAC;EACjE,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,+CAA+C,CAAC;EACnG,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,yBAAyB,CAAC;EAClE,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC;EACzD,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,mBAAmB,CAAC;EACvE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,YAAY,CAAC;EACrD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC;EACzD,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,mBAAmB,CAAC;EACvE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,YAAY,CAAC;EACrD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,cAAc,CAAC;EACvD,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,iBAAiB,CAAC;EACrE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,UAAU,CAAC;EACnD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EACpC,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAC3C,cAAc,IAAI,CAAC,kBAAkB,GAAG,sBAAsB,CAAC;EAC/D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,oBAAoB,CAAC;EACxE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,aAAa,CAAC;EACtD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa,MAAM;EACnB,cAAc,IAAI,CAAC,kBAAkB,GAAG,oBAAoB,CAAC;EAC7D,cAAc,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC,kBAAkB,CAAC;EACtE,cAAc,IAAI,CAAC,YAAY,GAAGA,OAAK,CAAC,WAAW,CAAC;EACpD,cAAc,OAAO,IAAI,CAAC;EAC1B,aAAa;EACb,SAAS;EACT,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,wBAAwB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EACpE,KAAK;EAEL,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAClE,GAAG;EAMH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAEH,EAAE,oBAAoB,GAAG;EACzB,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,QAAQ;EACnB,QAAQ,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC;EACjD,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC;EACjD,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC;EACjD,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,IAAI,CAAC,0BAA0B,EAAE,CAAC;EACjD,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;EAC1E,KAAK;EACL,GAAG;EAMH,EAAE,gCAAgC,GAAG;EACrC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,gCAAgC,GAAG;EACrC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,gCAAgC,GAAG;EACrC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,gCAAgC,GAAG;EACrC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,sBAAsB,GAAG;EAC3B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAKH,EAAE,yBAAyB,GAAG;EAC9B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;EAC5C,GAAG;EAEH,EAAE,mBAAmB,GAAG;EACxB,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,OAAO,IAAI,CAAC,sBAAsB,EAAE,CAAC;EAC3C,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EAC5C,MAAM,IAAI,IAAI,CAAC,mBAAmB,EAAE;EACpC,QAAQ,OAAO,IAAI,CAAC,kCAAkC,EAAE,CAAC;EACzD,OAAO;EACP,MAAM,OAAO,IAAI,CAAC,oBAAoB,EAAE,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,OAAO,IAAI,CAAC,yBAAyB,EAAE,CAAC;EAC9C,KAAK;EACL,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;EACvE,MAAMA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC;EACtE,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;EACvE,MAAMA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC;EACtE,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;EACvE,MAAMA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC;EACtE,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,gCAAgC,EAAE,CAAC;EACvE,MAAMA,OAAK,CAAC,aAAa,CAAC,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC;EACtE,GAAG;EAMH,EAAE,yBAAyB,GAAG;EAC9B,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,yBAAyB,CAAC;EACzC,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,0BAA0B,CAAC;EAC1C,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,4BAA4B,CAAC;EAC5C,KAAK;EACL,GAAG;EAMH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,uBAAuB,CAAC;EACvC,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,wBAAwB,CAAC;EACxC,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,0BAA0B,CAAC;EAC1C,KAAK;EACL,GAAG;EAMH,EAAE,6BAA6B,GAAG;EAClC,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,6BAA6B,CAAC;EAC7C,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,8BAA8B,CAAC;EAC9C,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,gCAAgC,CAAC;EAChD,KAAK;EACL,GAAG;EAEH,EAAE,kCAAkC,GAAG;EACvC,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,kCAAkC,CAAC;EAClD,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,mCAAmC,CAAC;EACnD,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,qCAAqC,CAAC;EACrD,KAAK;EACL,GAAG;EAEH,EAAE,aAAa,GAAG;EAClB,IAAI,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC;EACvC,MAAM,OAAO,EAAE,IAAI,CAAC,aAAa;EACjC,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO;EACxB,MAAM,UAAU,EAAE,IAAI,CAAC,SAAS;EAChC,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,OAAO,EAAE,IAAI,CAAC,OAAO;EAC3B,KAAK,CAAC,CAAC;EACP,GAAG;EACH,EAAE,4BAA4B,GAAG;EACjC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,UAAU,EAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;EACnG,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,OAAO,EAAE,EAAE;EACjB,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;EACnF,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,8BAA8B,GAAG;EACnC,IAAI,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,4BAA4B,EAAE,CAAC,MAAM,CAAC,CAAC;EACxE,GAAG;EAEH,EAAE,6BAA6B,GAAG;EAClC,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;EAC/F,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,OAAO,EAAE,EAAE;EACjB,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACzB,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACzB,IAAI,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACzD,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,4CAA4C,GAAG;EACjD,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;EAC/F,IAAI,MAAM;EACV,MAAM,OAAO;EACb,MAAM,OAAO,EAAE,EAAE;EACjB,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACzB,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACzB,IAAI,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACzD,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAOH,EAAE,SAAS,CAAC,IAAI,EAAE;EAClB,IAAI,MAAM;EACV,MAAM,OAAO,EAAE,EAAE;EACjB,MAAM,MAAM;EACZ,KAAK,GAAG,IAAI,CAAC;EACb,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;EACnC,IAAI,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC;EACtD,IAAI,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;EAE1E,IAAI,OAAO,IAAI,iBAAiB,CAAC,CAAC,IAAI,GAAG,MAAM,GAAGA,OAAK,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;EACnG,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE;EACjC,KAAK,CAAC;EACN,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC;EACxE,QAAQ,OAAO,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;EAChD,QAAQ,IAAI,EAAE,IAAI,CAAC,OAAO;EAC1B,QAAQ,UAAU,EAAE,IAAI,CAAC,SAAS;EAClC,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAM;EAC3B,QAAQ,OAAO,EAAE,IAAI,CAAC,OAAO;EAC7B,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;EACnB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE;EACjC,KAAK,CAAC;EACN,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,kBAAkB,CAAC;EACxE,QAAQ,OAAO,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;EAChD,QAAQ,IAAI,EAAE,IAAI,CAAC,OAAO;EAC1B,QAAQ,UAAU,EAAE,IAAI,CAAC,SAAS;EAClC,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAM;EAC3B,QAAQ,OAAO,EAAE,IAAI,CAAC,OAAO;EAC7B,OAAO,CAAC,CAAC;EACT,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,SAAS,CAAC,MAAM,EAAE;EACpB,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;EAC5B,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAClF,MAAM,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,oBAAoB,CAAC;EAChD,QAAQ,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACrD,QAAQ,SAAS,EAAE,IAAI,CAAC,SAAS;EACjC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACtB,MAAM,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACnC,MAAM,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC3D,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC9B,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EAC/C,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EAChD,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC7C,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC9C,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACjC,MAAM,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACzD,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;EACvC,OAAO;EACP,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,EAAE,YAAY,GAAG;EACjB,IAAI,OAAO,IAAI,CAAC,YAAY;EAC5B,MAAM,IAAI,CAAC,cAAc,EAAE;EAC3B,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;EACpB,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;EACpB,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;EACpB,KAAK,CAAC;EACN,GAAG;EACH,CAAC;AAED,EAAO,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;EAC5C,EAAE,uBAAuB,EAAE,MAAM,CAAC,yBAAyB,CAAC;EAC5D,EAAE,kBAAkB,EAAE,MAAM,CAAC,oBAAoB,CAAC;EAClD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,aAAa,EAAE,MAAM,CAAC,eAAe,CAAC;EACxC,EAAE,wBAAwB,EAAE,MAAM,CAAC,0BAA0B,CAAC;EAC9D,EAAE,iBAAiB,EAAE,MAAM,CAAC,mBAAmB,CAAC;EAChD,EAAE,mBAAmB,EAAE,MAAM,CAAC,qBAAqB,CAAC;EACpD,EAAE,mBAAmB,EAAE,MAAM,CAAC,qBAAqB,CAAC;EACpD,EAAE,kBAAkB,EAAE,MAAM,CAAC,oBAAoB,CAAC;EAClD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,kBAAkB,EAAE,MAAM,CAAC,oBAAoB,CAAC;EAClD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,kBAAkB,EAAE,MAAM,CAAC,oBAAoB,CAAC;EAClD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,CAAC;EACtD,EAAE,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC;EACtC,EAAE,+CAA+C,EAAE,MAAM,CAAC,kCAAkC,CAAC;EAC7F,EAAE,iDAAiD,EAAE,MAAM,CAAC,oCAAoC,CAAC;EACjG,EAAE,iDAAiD,EAAE,MAAM,CAAC,oCAAoC,CAAC;EACjG,CAAC,CAAC,CAAC;EAEH,MAAME,SAAO,GAAG;EAChB,EAAE,GAAG,EAAE,SAAS;EAChB,EAAE,KAAK,EAAE,QAAQ;EACjB,EAAE,IAAI,EAAE,UAAU;EAClB,EAAE,IAAI,EAAE,UAAU;EAClB,EAAE,IAAI,EAAE,UAAU;EAClB,CAAC,CAAC;;ECt9BK,MAAM,iBAAiB,SAAS,YAAY,CAAC;EACpD,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC5B,IAAI,IAAI,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,4BAA4B,CAAC,EAAE;EAC3E,MAAM,IAAI,CAAC,0BAA0B,GAAG,QAAQ,CAAC,0BAA0B,CAAC;EAC5E,KAAK;EACL,GAAG;EAQH,EAAE,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE;EAE3B,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;EAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,KAAK,MAAM;AAEX,EACA,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC5B,QAAQ,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;EACjD,QAAQ,IAAI,UAAU,EAAE;EACxB,UAAU,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EACnD,UAAU,IAAI,IAAI,CAAC,UAAU,KAAK,gBAAgB,EAAE;EACpD,YAAY,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;EACvC,WAAW;EACX,SAAS;EACT,OAAO;EAEP,MAAM,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,EAAE;EACvB,QAAQ,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC5B,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,GAAGA,SAAO,CAAC,UAAU,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,IAAI,EAAE;EACnB,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;EACxD,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,OAAO;EACP,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC3B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;EAE5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EAC1D,QAAQ,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAEnD,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE;EACnB,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC5B,SAAS;EACT,QAAQ,IAAI,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;EAExF,QAAQ,IAAI,CAAC,YAAY,EAAE;EAC3B,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,iBAAiB,EAAE,YAAY,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;EAClF,SAAS;EACT,QAAQ,IAAI,YAAY,KAAK,gBAAgB,EAAE;EAC/C,UAAU,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY,GAAG,QAAQ,CAAC;EAC1D,SAAS;EACT,QAAQ,MAAM,IAAI,GAAGA,SAAO,CAAC,YAAY,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,IAAI,EAAE;EACnB,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;EAClE,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC7B,QAAQ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAClC,OAAO;EACP,KAAK;EAGL,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAGzB,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACnD,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAChD,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxB,KAAK;EAGL,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACvB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;EACrF,IAAI,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;EAC9C,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC;EAE7C,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EAEtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC1B,MAAM,IAAI,IAAI,KAAK,gBAAgB,IAAI,IAAI,KAAK,SAAS,EAAE;EAC3D,QAAQ,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;EACnC,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC/B,OAAO;EACP,KAAK;EAEL,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,QAAQ,IAAI;EACpB,UAAU,KAAK,SAAS;EACxB,YAAY,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAClC,YAAY,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAClD,YAAY,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC7B,YAAY,MAAM;EAClB,UAAU,KAAK,gBAAgB;EAC/B,YAAY,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAI1D,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;EACjD,cAAc,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACvC,cAAc,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC/B,aAAa;EACb,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAClD,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,SAAS;EACpB,QAAQ,QAAQ,IAAI;EACpB,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,QAAQ;EACvB,YAAY,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC1D,YAAY,MAAM;EAClB,UAAU,KAAK,gBAAgB;EAC/B,YAAY,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC5D,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAClD,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,sBAAsB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EACnF,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;EAC3B,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EAC1D,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC7B,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE;EACjC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5E,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5D,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EAClD,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAUH,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE;EAE1B,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;EAC1B,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,sCAAsC,GAAG,GAAG,CAAC,KAAK;EAC1D,QAAQ,GAAG;EACX,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC1C,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;EACrC,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACtH,QAAQ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;EAC3C,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EACpC,OAAO,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE;EACrF,QAAQ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;EACtC,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;EACtC,OAAO;EACP,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACvF,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;EACzC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;EACxC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;EAClC,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,IAAI,CAAC,yBAAyB,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE;EACrD,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,0BAA0B,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,EAAE;EACjE,MAAM,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EACvC,MAAM,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;EACpC,QAAQ,KAAK,SAAS;EACtB,UAAU,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAClD,UAAU,MAAM;EAChB,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,UAAU,MAAM;EAChB,QAAQ;EACR,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACxB,MAAM,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;EACrC,QAAQ,KAAK,SAAS;EACtB,UAAU,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACnD,UAAU,MAAM;EAChB,QAAQ,KAAK,gBAAgB;EAC7B,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,UAAU,MAAM;EAChB,QAAQ;EACR,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EACtC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC;EACxD,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC;EAC1D,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,SAAS,EAAE;EACjC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,2BAA2B,CAAC,EAAE,GAAG,CAAC,CAAC;EACpE,KAAK;EACL,IAAI,MAAM,GAAG,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;EAC7C,IAAI,QAAQ,GAAG;EACf,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,eAAe,CAAC;EAC3B,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EACxC,QAAQ,MAAM;EACd,MAAM,KAAK,iCAAiC;EAC5C,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACpF,UAAU,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC5C,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EAC3C,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,UAAU,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,MAAM;EAEd,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;EAE1F,UAAU,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;EAClD,YAAY,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EAC7C,YAAY,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,YAAY,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACnE,YAAY,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC/C,YAAY,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EAC5C,YAAY,MAAM;EAClB,WAAW;EACX,SAAS;EACT,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;EAC7C,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE;EAC1C,UAAU,MAAM,aAAa,GAAG,EAAE,CAAC;EACnC,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;EACpD,UAAU,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EACtD,UAAU,IAAI,WAAW,KAAK,SAAS,EAAE;EACzC,YAAY,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EAChD,WAAW,MAAM;EACjB,YAAY,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wCAAwC,CAAC,EAAE,GAAG,CAAC,CAAC;EACvF,WAAW;EACX,SAAS,MAAM;EACf,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,SAAS;EACT,QAAQ,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;EAC5C,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EACd,MAAM,KAAK,0BAA0B;EACrC,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EAEd,MAAM,KAAK,kBAAkB;EAC7B,QAAQ,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACjD,QAAQ,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EACxC,QAAQ,MAAM;EACd,MAAM,KAAK,wBAAwB,CAAC;EACpC,MAAM,KAAK,yBAAyB;EACpC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EAC9C,UAAU,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC7C,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvD,UAAU,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC5C,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EAC3C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,UAAU,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,wBAAwB,CAAC;EACpC,MAAM,KAAK,yBAAyB;EACpC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;EACxH,UAAU,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACtD,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,UAAU,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC5C,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EAC3C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EACjE,UAAU,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,UAAU,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC5C,UAAU,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EAC1C,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,0BAA0B;EACrC,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EAEd,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EAC1C,QAAQ,MAAM;EAEd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,QAAQ,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACjD,QAAQ,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;EACxC,QAAQ,MAAM;EAEd,MAAM;EACN,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,yBAAyB,CAAC,GAAG,EAAE,MAAM,EAAE;EACzC,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,iCAAiC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EAC9E,IAAI,IAAI,aAAa,EAAE;EACvB,MAAM,OAAO,aAAa,CAAC;EAC3B,KAAK;EACL,IAAI,MAAM,sBAAsB,GAAG;EACnC,MAAM,GAAG,EAAE,KAAK;EAChB,MAAM,IAAI,EAAE,KAAK;EACjB,KAAK,CAAC;EACN,IAAI,MAAM,aAAa,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC;EACpC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;EAClC,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAChD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;EACnC,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACjD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACnD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,iCAAiC,CAAC,GAAG,EAAE,MAAM,EAAE;EACjD,IAAI,MAAM,sBAAsB,GAAG;EACnC,MAAM,GAAG,EAAE,YAAY;EACvB,MAAM,GAAG,EAAE,WAAW;EACtB,MAAM,GAAG,EAAE,YAAY;EACvB,MAAM,IAAI,EAAE,0BAA0B;EACtC,MAAM,IAAI,EAAE,yBAAyB;EACrC,MAAM,KAAK,EAAE,2BAA2B;EACxC,KAAK,CAAC;EACN,IAAI,MAAM,aAAa,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC;EACpC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;EAC5C,IAAI,QAAQ,QAAQ;EACpB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACpD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC1C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;EAC9C,IAAI,QAAQ,SAAS;EACrB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACnD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACrD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC3C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,6BAA6B,CAAC,GAAG,EAAE,MAAM,EAAE;EAC7C,IAAI,MAAM,sBAAsB,GAAG;EACnC,MAAM,GAAG,EAAE,YAAY;EACvB,KAAK,CAAC;EACN,IAAI,MAAM,aAAa,GAAG,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC;EACpC,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;EACtC,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACxD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE;EACpC,IAAI,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;EACzC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;EACxC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACtC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;EACzC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACjC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;EACxC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE;EAChC,IAAI,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACvC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC1B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;EACjC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACtC,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;EACvC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,0CAA0C,EAAE,OAAO,CAAC,CAAC;EACrF,KAAK;EAEL,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;EAEvC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE;EAErC,MAAM,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EACrC,KAAK,MAAM,IAAI,IAAI,KAAK,SAAS,EAAE;EACnC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;EACzD,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC5C,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC1C,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,cAAc,EAAE;EACzC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;EAClE,KAAK;EAEL,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,SAAS,GAAG,EAAE,CAAC;EACzB,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC;EAEtB,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;EAC5C,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE;EAC7E,UAAU,MAAM,GAAG,KAAK,CAAC;EACzB,SAAS;EACT,OAAO;EACP,MAAM,IAAI,MAAM,EAAE;EAClB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,UAAU,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;EAC/D,YAAY,MAAM,GAAG,KAAK,CAAC;EAC3B,WAAW;EACX,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACxC,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;EACxC,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE;EACxB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,MAAM,GAAG,KAAK,CAAC;EACrB,KAAK;EAEL,IAAI,IAAI,OAAO,CAAC,IAAI,EAAE;EACtB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;EAClC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;EACjC,KAAK;EAGL,IAAI,IAAI,MAAM,KAAK,IAAI,EAAE;EACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACtE,KAAK;EAEL,IAAI,IAAI,MAAM,EAAE;EAChB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5F,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK,MAAM;EACX,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EAClE,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;EAC7C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;EAClG,MAAM,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;EAC1D,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACpC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9C,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE;EACvC,IAAI,IAAI,SAAS,CAAC,IAAI,KAAK,gBAAgB,EAAE;EAC7C,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;EACtE,KAAK;EAEL,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EAChE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;EAChG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9B,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAEvB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,WAAW,CAAC,IAAI,KAAK,kBAAkB,EAAE;EACjD,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,yBAAyB,EAAE,WAAW,CAAC,CAAC;EACxE,KAAK;EAEL,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EAChE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAEvB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EASH,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAE3C,IAAI,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE;EACnC,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK,MAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,EAAE;EAC3C,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC7C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK,MAAM;EACX,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EAClD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;EACpD,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACpC,MAAM,IAAI,QAAQ,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE;EAC7D,QAAQ,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC9B,QAAQ,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC/C,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,OAAO,MAAM;EACb,QAAQ,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EACL,GAAG;EAQH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;EACnC,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;EACnC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;EAClC,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;EAC/C,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE;EAC7C,IAAI,IAAI,UAAU,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE;EACxD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;EACrB,KAAK;EACL,IAAI,MAAM,YAAY,GAAG,UAAU,CAAC,YAAY,CAAC;EACjD,IAAI,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;EACpE,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAC;EACrE,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,QAAQ,GAAG,IAAI,CAAC;EACxB,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;EAC3D,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC;EACpC,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;EACvD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;EACvC,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;EACxD,MAAM,IAAI,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;EAC3C,MAAM,IAAI,IAAI,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;EACxD,MAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE;EAErC,QAAQ,IAAI,GAAG,QAAQ,CAAC;EACxB,OAAO;EACP,MAAM,MAAM,UAAU,GAAGA,SAAO,CAAC,IAAI,CAAC,CAAC;EACvC,MAAM,IAAI,CAAC,UAAU,EAAE;EACvB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,YAAY,GAAG,UAAU,EAAE,YAAY,CAAC,EAAE,UAAU,CAAC,CAAC;EACzF,OAAO;EACP,MAAM,MAAM,iBAAiB,GAAG,EAAE,CAAC;EACnC,MAAM,IAAI,UAAU,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,aAAa,EAAE;EAE5E,QAAQ,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;EAClC,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAE;EAC1C,UAAU,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC3C,SAAS,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE;EACtC,UAAU,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;EACnD,SAAS,MAAM;EACf,UAAU,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACtC,SAAS;EACT,QAAQ,QAAQ,GAAG,IAAI,CAAC;EACxB,QAAQ,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,QAAQ,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;EACjD,QAAQ,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACpC,OAAO,MAAM;EAEb,QAAQ,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC9B,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAE;EAC1C,UAAU,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EACnD,SAAS,MAAM,IAAI,IAAI,KAAK,QAAQ,EAAE;EACtC,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,iBAAiB,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EACnD,SAAS,MAAM;EACf,UAAU,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACtC,SAAS;EACT,QAAQ,QAAQ,GAAG,IAAI,CAAC;EACxB,QAAQ,iBAAiB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,QAAQ,IAAI,UAAU,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE;EAC3D,UAAU,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE;EACzD,YAAY,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;EACrD,WAAW,MAAM;EACjB,YAAY,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3C,YAAY,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;EACrD,YAAY,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACxC,WAAW;EACX,SAAS,MAAM;EACf,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;EACnD,SAAS;EACT,OAAO;EACP,MAAM,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,aAAa,EAAE;EACxB,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE;EACjC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EACzC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACrB,IAAI,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACrD,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC1B,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACjD,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,KAAK;EAEL,IAAI,IAAI,MAAM,CAAC,SAAS,EAAE;EAC1B,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC3B,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,gBAAgB,EAAE;EACtD,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC5B,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC7B,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE;EAClC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,iBAAiB,EAAE;EACxC,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;EACjE,KAAK;EACL,IAAI,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;EACxC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;EAC5C,IAAI,MAAM,OAAO,GAAG,CAAC,kBAAkB,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAChE,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,QAAQ;EACnB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;EAC3C,QAAQ,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAC3B,QAAQ,MAAM;EACd,MAAM,KAAK,SAAS;EACpB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;EACzC,QAAQ,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EAC3B,QAAQ,MAAM;EACd,KAAK;EAEL,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;EAC9C,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACnD,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAGL,IAAI,IAAI,cAAc,GAAG,KAAK,CAAC;EAC/B,IAAI,IAAI,aAAa,GAAG,EAAE,CAAC;EAC3B,IAAI,IAAI,kBAAkB,GAAG,KAAK,CAAC;EACnC,IAAI,IAAI,WAAW,GAAG,KAAK,CAAC;EAC5B,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAE3C,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;EAC1B,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE;EAClC,UAAU,kBAAkB,GAAG,IAAI,CAAC;EACpC,UAAU,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;EAC9D,UAAU,SAAS;EACnB,SAAS,MAAM;EACf,UAAU,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EACnC,SAAS;EACT,OAAO,MAAM;EAEb,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE;EACrC,UAAU,WAAW,GAAG,IAAI,CAAC;EAC7B,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5C,SAAS,MAAM;EACf,UAAU,IAAI,cAAc,EAAE;EAC9B,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1C,YAAY,cAAc,GAAG,KAAK,CAAC;EACnC,WAAW,MAAM;EACjB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;EACpD,WAAW;EACX,SAAS;EACT,QAAQ,IAAI,IAAI,KAAK,SAAS,EAAE;EAChC,UAAU,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACvD,UAAU,QAAQ,QAAQ;EAC1B,YAAY,KAAK,QAAQ,CAAC;EAC1B,YAAY,KAAK,OAAO;EACxB,cAAc,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC7D,cAAc,MAAM;EACpB,YAAY,KAAK,gBAAgB;EACjC,cAAc,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC/D,cAAc,MAAM;EACpB,WAAW;EACX,SAAS,MAAM,IAAI,IAAI,KAAK,OAAO,EAAE;EACrC,UAAU,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACvD,UAAU,QAAQ,QAAQ;EAC1B,YAAY,KAAK,gBAAgB;EACjC,cAAc,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC7D,cAAc,MAAM;EACpB,YAAY,KAAK,SAAS;EAC1B,cAAc,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;EAC3D,cAAc,MAAM;EACpB,WAAW;EACX,SAAS,MAAM;EACf,UAAU,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC;EACvC,SAAS;EACT,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE;EACtE,UAAU,cAAc,GAAG,IAAI,CAAC;EAChC,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,UAAU,SAAS;EACnB,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;EAC7B,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;EACnD,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,IAAI,kBAAkB,EAAE;EAC5B,MAAM,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC7B,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;EAC1C,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACvB,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE;EACnC,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACxB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE;EACrC,IAAI,MAAM;EACV,MAAM,QAAQ;EACd,MAAM,IAAI;EACV,MAAM,SAAS;EACf,MAAM,MAAM;EACZ,MAAM,IAAI;EACV,MAAM,SAAS;EACf,MAAM,SAAS;EACf,MAAM,SAAS;EACf,KAAK,GAAG,IAAI,CAAC,0BAA0B,CAAC,KAAK,CAAC,CAAC;EAC/C,IAAI,QAAQ,SAAS;EACrB,MAAM,KAAK,oBAAoB,CAAC;EAChC,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE;EAC1D,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,sFAAsF,EAAE,KAAK,CAAC,CAAC;EACnI,SAAS;EACT,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;EACxC,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,mBAAmB;EAC9B,QAAQ,IAAI,IAAI,CAAC,aAAa,EAAE;EAChC,UAAU,QAAQ,IAAI;EACtB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACpD,gBAAgB,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EACnD,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC5C,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACpD,gBAAgB,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EACnD,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC5C,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;EACpD,gBAAgB,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;EACnD,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC5C,eAAe;EACf,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EACxE,WAAW;EACX,SAAS,MAAM;EACf,UAAU,QAAQ,IAAI;EACtB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;EACtD,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5C,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAClD,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;EACtD,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5C,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAClD,eAAe;EACf,cAAc,MAAM;EACpB,YAAY,KAAK,GAAG;EACpB,cAAc,IAAI,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,EAAE;EACtD,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5C,eAAe,MAAM;EACrB,gBAAgB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAClD,eAAe;EACf,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EACxE,WAAW;EACX,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,OAAO;EAClB,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EAClE,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,aAAa,CAAC;EACzB,MAAM,KAAK,eAAe,CAAC;EAC3B,MAAM,KAAK,aAAa;EACxB,QAAQ,IAAI,MAAM,KAAK,MAAM,EAAE;EAC/B,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAClC,UAAU,OAAO,MAAM,CAAC;EACxB,SAAS;EACT,QAAQ,QAAQ,QAAQ;EACxB,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;EAC5C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;EAC5C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;EAC5C,YAAY,OAAO,MAAM,CAAC;EAC1B,UAAU,KAAK,GAAG;EAClB,YAAY,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;EAC5C,YAAY,OAAO,MAAM,CAAC;EAC1B,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,sBAAsB;EACjC,QAAQ,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE;EAC9C,UAAU,QAAQ,IAAI;EACtB,YAAY,KAAK,UAAU,CAAC;EAC5B,YAAY,KAAK,UAAU,CAAC;EAC5B,YAAY,KAAK,UAAU;EAC3B,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EACjD,cAAc,OAAO,MAAM,CAAC;EAC5B,WAAW;EACX,SAAS;EACT,QAAQ,KAAK,wBAAwB,CAAC;EACtC,QAAQ,KAAK,0BAA0B,CAAC;EACxC,QAAQ,KAAK,4BAA4B,CAAC;EAC1C,QAAQ,KAAK,8BAA8B;EAC3C,UAAU,MAAM;EAChB,QAAQ,KAAK,QAAQ;EACrB,UAAU,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EACvD,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC,CAAC;EACrE,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,OAAO,MAAM,CAAC;EACxB,QAAQ,KAAK,MAAM;EACnB,UAAU,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EACxD,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,QAAQ,CAAC,CAAC,CAAC;EACrE,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,UAAU,OAAO,MAAM,CAAC;EACxB,QAAQ;EACR,UAAU,MAAM,IAAI,CAAC,cAAc,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;EACpE,KAAK;EAEL,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,EAAE;EAElC,MAAM,QAAQ,IAAI;EAClB,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,SAAS,CAAC;EACvB,QAAQ,KAAK,OAAO,CAAC;EACrB,QAAQ,KAAK,SAAS;EACtB,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3C,UAAU,OAAO,MAAM,CAAC;EACxB,OAAO;EACP,KAAK;EAIL,IAAI,MAAM,UAAU,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;EAE3C,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU;EAErB,QAAQ,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EAC9C,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,SAAS,CAAC,CAAC,CAAC;EACpE,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EAC7F,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,sBAAsB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACxG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY;EACvB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACzG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACvG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY;EACvB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACzG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACvG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY;EACvB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAuB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACzG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,WAAW;EACtB,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACvG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM,KAAK,eAAe,CAAC;EAC3B,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS;EACpB,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EAGzC,UAAU,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;EACnG,UAAU,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC5E,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,SAAS,MAAM;EACf,UAAU,MAAM,QAAQ,IAAI,MAAM,KAAK,MAAM;EAC7C,YAAY,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC;EAChE,YAAY,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;EACxC,WAAW,CAAC;EACZ,UAAU,QAAQ,QAAQ;EAC1B,YAAY,KAAK,CAAC;EAClB,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;EACvF,cAAc,MAAM;EACpB,YAAY,KAAK,CAAC;EAClB,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;EACxF,cAAc,MAAM;EACpB,YAAY,KAAK,CAAC,CAAC;EACnB,YAAY,KAAK,CAAC;EAClB,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;EACxF,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,MAAM,IAAI,KAAK,CAAC,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;EACpE,WAAW;EACX,UAAU,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC5E,UAAU,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC3B,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,8BAA8B;EACzC,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,qBAAqB,GAAG,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;EACvG,QAAQ,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;EAC1E,QAAQ,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EACzB,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;EACnE,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE;EACjC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;EACrB,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;EAC/D,KAAK;EAEL,IAAI,IAAI,YAAY,GAAG,IAAI,CAAC;EAC5B,IAAI,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;EAGvD,IAAI,IAAI,cAAc,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,gBAAgB,CAAC,EAAE;EAC9F,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;EAC9C,KAAK;EAEL,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,oBAAoB,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE;EAChJ,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;EAC7D,KAAK,MAAM;EACX,MAAM,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;EACrC,KAAK;EAEL,IAAI,IAAI,CAAC,YAAY,EAAE;EACvB,MAAM,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,sCAAsC,CAAC,EAAE,GAAG,CAAC,CAAC;EAC/E,KAAK;EAGL,IAAI,IAAI,YAAY,KAAK,OAAO,EAAE;EAClC,MAAM,YAAY,GAAG,MAAM,CAAC;EAC5B,KAAK;EAGL,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE;EACxD,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,YAAY,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EAC9E,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EACvC,QAAQ,IAAI,MAAM,CAAC,aAAa,KAAK,eAAe,IAAI,MAAM,CAAC,eAAe,EAAE;EAChF,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;EAC9C,UAAU,OAAO,MAAM,CAAC;EACxB,SAAS;EACT,OAAO;EACP,KAAK;EAGL,IAAI,IAAI,IAAI,CAAC,cAAc,EAAE;EAC7B,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;EAClE,KAAK;EAGL,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAG9B,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAGrB,IAAI,IAAI,cAAc,EAAE;EACxB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,QAAQ,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EAC1C,QAAQ,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACpD,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE;EACnB,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC5B,SAAS;EAET,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACpD,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC9C,YAAY,MAAM;EAClB,SAAS;EACT,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,2BAA2B,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;EAC/E,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,QAAQ,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EAC1C,QAAQ,IAAI,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;EACxC,QAAQ,IAAI,CAAC,GAAG,CAAC,EAAE;EACnB,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC5B,SAAS;EACT,QAAQ,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACpD,QAAQ,IAAI,CAAC,UAAU,EAAE;EACzB,UAAU,IAAI,CAAC,wBAAwB,CAAC,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;EAC7E,UAAU,UAAU,GAAG,YAAY,CAAC;EACpC,SAAS;EACT,QAAQ,QAAQ,YAAY;EAC5B,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,OAAO;EACtB,YAAY,IAAI,UAAU,KAAK,SAAS,EAAE;EAC1C,cAAc,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAClC,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC/B,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,OAAO,EAAE;EAC1E,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,gBAAgB,EAAE;EACxD,cAAc,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACxD,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,OAAO,EAAE;EACnE,cAAc,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;EACpC,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAC/B,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,SAAS,EAAE;EACjD,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,gBAAgB;EAC/B,YAAY,IAAI,UAAU,KAAK,SAAS,EAAE;EAC1C,cAAc,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC1D,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,OAAO,EAAE;EAC1E,cAAc,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACxD,cAAc,SAAS;EACvB,aAAa,MAAM,IAAI,UAAU,KAAK,gBAAgB,EAAE;EACxD,cAAc,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAChD,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU;EACzB,YAAY,IAAI,UAAU,KAAK,YAAY,EAAE;EAC7C,cAAc,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wBAAwB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;EAC/H,cAAc,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;EAC3F,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACnD,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,WAAW,CAAC;EAC3B,UAAU,KAAK,gBAAgB,CAAC;EAChC,UAAU,KAAK,WAAW,CAAC;EAC3B,UAAU,KAAK,iBAAiB,CAAC;EACjC,UAAU,KAAK,iBAAiB,CAAC;EACjC,UAAU,KAAK,iBAAiB,CAAC;EACjC,UAAU,KAAK,iBAAiB,CAAC;EACjC,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,OAAO;EACtB,YAAY,IAAI,UAAU,KAAK,YAAY,EAAE;EAC7C,cAAc,IAAI,QAAQ,CAAC,IAAI,KAAK,YAAY,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,wBAAwB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;EAC/H,cAAc,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;EAC3F,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;EACtG,cAAc,SAAS;EACvB,aAAa;EACb,YAAY,MAAM;EAClB,SAAS;EACT,QAAQ,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,kCAAkC,GAAG,YAAY,EAAE,KAAK,GAAG,UAAU,EAAE,qBAAqB,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;EAC1J,OAAO;EACP,KAAK;EAEL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAQH,EAAE,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE;EACtC,IAAI,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;EAE3C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,MAAM,GAAG,GAAG,CAAC,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,EAAE,CAAC,EAAE;EACrC,MAAM,IAAI,CAAC,GAAG,CAAC,EAAE;EACjB,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC1B,OAAO;EACP,MAAM,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,EAAC;EACtC,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAErB,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE;EACvC,IAAI,IAAI,CAAC,EAAE;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAChE,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,IAAI,CAAC,EAAE;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;EAChE,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;EACzB,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC;EACxD,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,8BAA8B,CAAC,QAAQ,EAAE;EAC3C,IAAI,IAAI,CAAC,QAAQ,EAAE;EACnB,MAAM,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;EAC1C,KAAK;EACL,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,QAAQ,IAAI;EAChB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO;EAClB,QAAQ,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAClD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EACpD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;EAC1C,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EACH,CAAC;EAED,MAAMA,SAAO,GAAG;EAChB,EAAE,OAAO,EAAE,WAAW;EACtB,EAAE,UAAU,EAAE,MAAM;EACpB,EAAE,UAAU,EAAE,MAAM;EACpB,EAAE,UAAU,EAAE,MAAM;EACpB,EAAE,SAAS,EAAE,WAAW;EACxB,EAAE,SAAS,EAAE,WAAW;EACxB,EAAE,SAAS,EAAE,MAAM;EACnB,EAAE,OAAO,EAAE,OAAO;EAClB,EAAE,OAAO,EAAE,WAAW;EACtB,EAAE,SAAS,EAAE,KAAK;EAClB,EAAE,QAAQ,EAAE,OAAO;EACnB,EAAE,gBAAgB,EAAE,OAAO;EAC3B,EAAE,eAAe,EAAE,WAAW;EAC9B,EAAE,8BAA8B,EAAE,WAAW;EAC7C,EAAE,iBAAiB,EAAE,WAAW;EAChC,EAAE,iBAAiB,EAAE,WAAW;EAChC,EAAE,iBAAiB,EAAE,WAAW;EAChC,EAAE,iBAAiB,EAAE,WAAW;EAChC,EAAE,WAAW,EAAE,WAAW;EAC1B,EAAE,WAAW,EAAE,WAAW;EAC1B,EAAE,gBAAgB,EAAE,gBAAgB;EACpC,CAAC,CAAC;EAEF,MAAM,WAAW,GAAG;EACpB,EAAE,KAAK,EAAE,IAAI;EACb,EAAE,KAAK,EAAE,IAAI;EACb,CAAC,CAAC;;ECz/CF,MAAM,MAAM,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Bf,CAAC,CAAC;EAEH,MAAMC,MAAI,GAAG,sBAAsB,CAAC;EAEpC,MAAM,aAAa,GAAG,eAAe,CAAC;EAEtC,MAAM,eAAe,GAAG,mBAAmB,CAAC;EAE5C,MAAM,kBAAkB,GAAG,QAAQ,CAAC;EAEpC,MAAM,WAAW,GAAG,CAAC,MAAM,KAAK;EAChC,EAAE,MAAM,CAAC,YAAY,CAAC,qBAAqB,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;EAC5D,CAAC,CAAC;AAKF,sBAAe;EACf,QAAEA,MAAI;EACN,EAAE,WAAW;EACb,EAAE,aAAa;EACf,EAAE,eAAe;EACjB,EAAE,kBAAkB;EACpB,EAAE,MAAM;EACR,CAAC,CAAC;;EClDK,MAAM,cAAc,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiZ9B,CAAC,CAAC;;ECjZI,MAAM,YAAY,GAAG,CAAC;;;;;;;;;;;;;CAa5B,CAAC,CAAC;;;;;;;ECRH,SAAS,SAAS,CAAC,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE;IACnC,MAAM;MACJ,WAAW,GAAG,IAAI;MAClB,aAAa;MACb,sBAAsB;MACtB,cAAc;MACd,SAAS,GAAG,EAAE;MACd,SAAS,GAAG,EAAE;MACd,YAAY;MACZ,4BAA4B;KAC7B,GAAG,OAAO,CAAC;IACZ,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7C,MAAM,gBAAgB,GAAG,EAAE,CAAC;IAC5B,MAAM,WAAW,GAAG,EAAE,CAAC;IACvB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,sBAAsB,CAAC;IAC3B,OAAO,KAAK,CAAC;IACb,SAAS,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE;MAC7B,QAAQ,QAAQ;QACd,KAAK,YAAY,EAAE,OAAO,UAAU,CAAC;QACrC,KAAK,iBAAiB,EAAE,OAAO,eAAe,CAAC;QAC/C,KAAK,2BAA2B,EAAE,OAAO,sBAAsB,CAAC;QAChE,KAAK,gBAAgB,EAAE,OAAO,cAAc,CAAC;QAC7C,KAAK,OAAO,EAAE,OAAO,KAAK,CAAC;QAC3B,KAAK,WAAW,EAAE,OAAO,SAAS,CAAC;QACnC,KAAK,UAAU,EAAE,OAAO,QAAQ,CAAC;QACjC,KAAK,wBAAwB,EAAE,OAAO,sBAAsB,CAAC;OAC9D;MACD,IAAI,OAAO,EAAE,CAAC,QAAQ,CAAC,KAAK,UAAU,EAAE;QACtC,OAAO,WAAW;UAChB,QAAQ,QAAQ;YACd,KAAK,UAAU;cACb,IAAI,aAAa,EAAE;gBACjB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,gBAAgB,EAAE,WAAW,CAAC,gCAAgC,CAAC,CAAC,CAAC;eAC7G,MAAM;gBACL,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC;eACvD;cACD,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC;YACvB,KAAK,cAAc,EAAE;cACnB,MAAM,YAAY,GAAG,CAAC,EAAE,WAAW,CAAC,SAAS,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;cACzE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;cACnG,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;cAChD,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE;gBAC9C,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,EAAE;kBACpD,SAAS;kBACT,sBAAsB;kBACtB,SAAS;kBACT,WAAW,EAAE,YAAY;kBACzB,gBAAgB;kBAChB,SAAS;kBACT,MAAM;kBACN,4BAA4B;iBAC7B,CAAC,CAAC;gBACH,gBAAgB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;gBACvC,OAAO,eAAe,CAAC;eACxB,MAAM;gBACL,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;eAC7B;cACD,OAAO,SAAS,CAAC;aAClB;YACD,KAAK,YAAY;cACf,MAAM,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;cACjD,IAAI,kBAAkB,CAAC;cACvB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;gBACZ,MAAM,YAAY,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnD,IAAI,YAAY,EAAE;kBAChB,kBAAkB,GAAG,YAAY,CAAC;kBAClC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;iBAC5C,MAAM;kBACL,kBAAkB,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;kBACxE,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;kBACpC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;iBACxH;eACF,MAAM;gBACL,kBAAkB,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;eACnD;cACD,sBAAsB,GAAG,kBAAkB,CAAC;cAC5C,MAAM,iBAAiB,GAAG;gBACxB,SAAS,CAAC,CAAC,CAAC;gBACZ,SAAS,CAAC,CAAC,CAAC;gBACZ,SAAS,CAAC,CAAC,CAAC;gBACZ,SAAS,CAAC,CAAC,CAAC;gBACZ,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBACvB,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;gBACvB,kBAAkB;eACnB,CAAC;cACF,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,YAAY,EAAE,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;cACvF,IAAI,cAAc,EAAE;gBAClB,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;eACtC;cACD,IAAI,YAAY,EAAE;gBAChB,YAAY,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC;eACrD;cACD,OAAO,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;YAC5C,KAAK,aAAa;cAChB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,cAAc,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,4BAA4B,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;cAClM,OAAO,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;WACvC;UACD,IAAI,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;UAC/C,QAAQ,OAAO,MAAM;YACnB,KAAK,WAAW;cACd,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;cACvE,OAAO;YACT,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS;cACZ,IAAI,sBAAsB,IAAI,gBAAgB,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;gBACzF,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChI,gBAAgB,CAAC,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC3D,MAAM;eACP;YACH;cACE,IAAI,MAAM,KAAK,IAAI,EAAE;gBACnB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;eAC/D,MAAM;gBACL,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;eACjI;cAED,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;WACjC;UACD,OAAO,MAAM,CAAC;SACf;OACF;MACD,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC;MACrC,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;KACrB;IACD,SAAS,QAAQ,GAAG;MAClB,OAAO,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KAC7B;IACD,SAAS,KAAK,GAAG;MACf,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;QAC3B,SAAS,CAAC,GAAG,EAAE,CAAC;OACjB;KACF;IACD,SAAS,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE;MACnC,SAAS,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;KACzB;IACD,SAAS,SAAS,CAAC,KAAK,EAAE;MACxB,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;MAChC,IAAI,IAAI,EAAE;QACR,OAAO,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC;OACjC;MACD,OAAO,KAAK,CAAC;KACd;IACD,SAAS,SAAS,CAAC,MAAM,EAAE;MACzB,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KAC7B;IACD,SAAS,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;MAClC,MAAM,YAAY,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;MACxE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC9D,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;MAC7B,OAAO,YAAY,CAAC;KACrB;IACD,SAAS,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE;MAC/B,MAAM,cAAc,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;MAC1E,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;MAChD,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,YAAY,EAAE,cAAc,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;MACvI,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,oBAAoB,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC,CAAC;MAClF,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,aAAa,CAAC,IAAI,EAAE,cAAc,CAAC,YAAY,EAAE,cAAc,CAAC,gBAAgB,EAAE,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC;MAC/I,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC7B,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,qCAAqC,CAAC,CAAC,CAAC;MACjE,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,iCAAiC,EAAE,cAAc,CAAC,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;MACvG,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC7B,UAAU,EAAE,CAAC;KACd;IACD,SAAS,UAAU,CAAC,KAAK,EAAE;MACzB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;KACxC;IACD,SAAS,eAAe,GAAG;MACzB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC;AAC7B,EAAE,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC;AACrC,EAAE,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC;AACrC,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC;AAC/B,EAAE,MAAM,CAAC,uBAAuB,EAAE,WAAW,CAAC;AAC9C,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC;AACT,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;KACd;IACD,SAAS,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE;MACxC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,iBAAiB,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACnK;IAED,SAAS,eAAe,CAAC,KAAK,EAAE;MAC9B,IAAI,SAAS,EAAE;QACb,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE;UAC5B,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;YAC7B,OAAO,IAAI,CAAC;WACb;SACF;OACF;MACD,OAAO,IAAI,CAAC;KACb;IAED,SAAS,sBAAsB,CAAC,KAAK,EAAE;MACrC,MAAM,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;MAC1C,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;QACZ,OAAO,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;OACrC;MACD,OAAO,IAAI,CAAC;KACb;GACF;EAQD,SAAS,kBAAkB,CAAC,SAAS,EAAE,OAAO,EAAE;IAC9C,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;IACpD,MAAM,oBAAoB,GAAG,EAAE,CAAC;IAChC,MAAM;MACJ,WAAW;MACX,gBAAgB;MAChB,SAAS;MACT,sBAAsB;MACtB,SAAS;MACT,SAAS;MACT,MAAM;MACN,4BAA4B;KAC7B,GAAG,OAAO,CAAC;IACZ,OAAO,KAAK,CAAC;IACb,SAAS,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE;MAC7B,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,UAAU,EAAE;QACvC,OAAO,WAAW;UAChB,QAAQ,QAAQ;YACd,KAAK,kBAAkB;cACrB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;cAC1N,OAAO,SAAS,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;WACnD;UACD,IAAI,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;UAC7D,QAAQ,OAAO,MAAM;YACnB,KAAK,WAAW;cACd,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;cACvE,OAAO;YACT,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS;cACZ,IAAI,sBAAsB,IAAI,gBAAgB,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;gBACzF,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChI,gBAAgB,CAAC,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;eAC5D,MAAM;gBACL,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAChI,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;eAC/B;cACD,MAAM;YACR;cACE,IAAI,MAAM,KAAK,IAAI,EAAE;gBACnB,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;eAC/D,MAAM;gBACL,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;eACjI;cACD,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;WACjC;UACD,OAAO,MAAM,CAAC;SACf,CAAC;OACH;MACD,oBAAoB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC;MACrD,OAAO,SAAS,CAAC,QAAQ,CAAC,CAAC;KAC5B;IAED,SAAS,kBAAkB,CAAC,KAAK,EAAE;MACjC,IAAI,oBAAoB,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE;QAC9C,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;OACxD;MACD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC;KACzB;IAED,SAAS,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE;MACxC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,iBAAiB,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,kBAAkB,EAAE,WAAW,EAAE,SAAS,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACvL;IAED,SAAS,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE;MAClC,MAAM,YAAY,GAAG,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;MACxE,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;MAC7B,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;MAC9D,OAAO,YAAY,CAAC;KACrB;GACF;EAED,SAAS,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE;IACxC,MAAM,EAAE,SAAS,EAAE,4BAA4B,EAAE,GAAG,OAAO,CAAC;IAC5D,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK;MACpC,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;MAC1C,IAAI,YAAY,EAAE;QAChB,OAAO,YAAY,CAAC;OACrB;MACD,OAAO,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;KACvC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;IAEf,SAAS,eAAe,CAAC,KAAK,EAAE;MAC9B,IAAI,SAAS,EAAE;QACb,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE;UAC5B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,SAAS;UAC9C,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;YAC7B,OAAO,IAAI,CAAC;WACb;SACF;OACF;MACD,IAAI,4BAA4B,EAAE;QAChC,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAC;OAC5C;MACD,OAAO,IAAI,CAAC;KACb;GACF;EAED,SAAS,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE;IACtC,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,WAAW,EAAE,4BAA4B,EAAE,GAAG,OAAO,CAAC;IACxG,IAAI,OAAO,GAAG,KAAK,WAAW,EAAE;MAC9B,OAAO,WAAW,CAAC;KACpB;IACD,IAAI,GAAG,KAAK,IAAI,EAAE;MAChB,OAAO,MAAM,CAAC;KACf;IACD,MAAM,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;MACV,OAAO,CAAC,EAAE,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;KACrC;IACD,QAAQ,GAAG,CAAC,WAAW,CAAC,IAAI;MAC1B,KAAK,QAAQ;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,eAAe,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,eAAe,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,QAAQ,EAAE;UACZ,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;SACxB,MAAM,IAAI,eAAe,IAAI,CAAC,eAAe,EAAE;UAC9C,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;SACxB,MAAM,IAAI,CAAC,eAAe,IAAI,eAAe,EAAE;UAC9C,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;SACxB,MAAM;UACL,OAAO,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;SAC1B;MACH,KAAK,QAAQ,EAAE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;MACrC,KAAK,SAAS,EAAE,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;MACtC,KAAK,OAAO;QACV,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;MACzF,KAAK,cAAc,CAAC;MACpB,KAAK,YAAY,CAAC;MAClB,KAAK,aAAa,CAAC;MACnB,KAAK,YAAY;QACf,OAAO,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;MAC7F;QACE,IAAI,4BAA4B,EAAE;UAChC,MAAM,mBAAmB,GAAG,4BAA4B,CAAC,GAAG,CAAC,CAAC;UAC9D,IAAI,mBAAmB,EAAE;YACvB,OAAO,mBAAmB,CAAC;WAC5B;SACF;QACD,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,EAAE,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACzE;GACF;EAED,SAAS,kBAAkB,CAAC,KAAK,EAAE;IAEjC,OAAO,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;GACrC;AAED,EAAmC;IACjC,cAAc,GAAG,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;GACpD;EAED,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;IACjC,SAAS,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAClD,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;GAC9B;;;;;EClXD,SAAS,oBAAoB,CAAC,EAAE,EAAE;EAClC,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE;EACtB,KAAK,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;EACtB,KAAK,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;EAC9B,KAAK,OAAO,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;EACxC,CAAC;AAWD,EAAO,SAAS,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE;EACrG,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI;EAC5C,IAAI,QAAQ,OAAO,GAAG;EACtB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;EAChC,MAAM,KAAK,QAAQ;EACnB,QAAQ,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;EAC/B,MAAM;EACN,QAAQ,OAAO,GAAG,CAAC;EACnB,KAAK;EACL,GAAG,CAAC,GAAG,IAAI,CAAC;AACZ,EACA,EAAE,MAAM,UAAU,GAAG,EAAE,CAAC;EACxB,EAAE,MAAM,OAAO,GAAGC,WAAS,CAAC,YAAY,CAAC,OAAO,EAAE;EAClD,IAAI,sBAAsB,EAAE,IAAI;EAChC,IAAI,YAAY,EAAE,CAAC,UAAU,KAAK;EAClC,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE;EAC7B,QAAQ,IAAI,CAAC,6BAA6B,EAAE;EAC5C,UAAU,UAAU,CAAC,IAAI,CAAC,CAAC,6BAA6B,EAAE,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACpG,UAAU,6BAA6B,GAAG,IAAI,CAAC;EAC/C,SAAS,MAAM;EACf,UAAU,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,qBAAqB,EAAE,CAAC,CAAC,QAAQ,CAAC;EAC/E,UAAU,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,GAAG,GAAG,QAAQ,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACvI,SAAS;EACT,QAAQ,IAAI,qBAAqB,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE;EAChE,UAAU,UAAU,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAChD,SAAS;EACT,QAAQ,OAAO;EACf,OAAO;EACP,MAAM,IAAI,UAAU,EAAE;EACtB,QAAQ,UAAU,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9E,OAAO,MAAM;EACb,QAAQ,UAAU,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;EAC5C,OAAO;EACP,KAAK;EACL,IAAI,4BAA4B,EAAE,CAAC,QAAQ,KAAK;EAChD,MAAM,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,eAAe,EAAE,EAAE,EAAE,OAAO,AAAgB,CAAC,CAAC;EAC1G,MAAM,IAAI,YAAY,EAAE;EACxB,QAAQ,OAAO,YAAY,CAAC;EAC5B,OAAO;EACP,MAAM,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,EAAE,MAAM,CAAC,eAAe,EAAE,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,AAAgB,CAAC,CAAC;EAC1K,MAAM,IAAI,YAAY,EAAE;EACxB,QAAQ,OAAO,YAAY,CAAC;EAC5B,OAAO;EACP,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,GAAG,CAAC,CAAC;EACL,EAAE,IAAI,6BAA6B,GAAG,KAAK,CAAC;EAC5C,EAAE,IAAI,qBAAqB,GAAG,CAAC,CAAC;EAChC,EAAE,MAAM;EACR,IAAI,MAAM;EACV,IAAI,MAAM;EACV,IAAI,MAAM;EACV,IAAI,QAAQ;EACZ,IAAI,SAAS;EACb,IAAI,iBAAiB;EACrB,IAAI,SAAS;EACb,IAAI,mBAAmB;EACvB,IAAI,SAAS;EACb,IAAI,0BAA0B;EAC9B,IAAI,SAAS;EACb,IAAI,eAAe;EACnB,IAAI,UAAU;EACd,IAAI,SAAS;EACb,IAAI,aAAa;EACjB,IAAI,aAAa;EACjB,IAAI,eAAe;EACnB,IAAI,eAAe;EACnB,GAAG,GAAG,YAAY,CAAC;EACnB,EAAE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE;EACpC,IAAI,MAAM;EACV,IAAI,OAAO;EACX,IAAI,YAAY,EAAE,KAAK;EACvB,IAAI,MAAM;EACV,IAAI,QAAQ;EACZ,IAAI,SAAS;EACb,IAAI,iBAAiB;EACrB,IAAI,SAAS;EACb,IAAI,mBAAmB;EACvB,IAAI,SAAS;EACb,IAAI,0BAA0B;EAC9B,IAAI,SAAS;EACb,IAAI,eAAe;EACnB,IAAI,UAAU;EACd,IAAI,SAAS;EACb,IAAI,aAAa;EACjB,IAAI,aAAa;EACjB,GAAG,CAAC,CAAC;EACL,EAAE,IAAI,MAAM,GAAG,EAAE,CAAC;EAClB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EACvB,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACnC,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;EAClC,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;EAElB,EAAE,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,cAAc,EAAE,CAAC,KAAK;EACxD,IAAI,QAAQ,cAAc,CAAC,IAAI;EAE/B,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO,CAAC;EAEnB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,WAAW;EACtB,QAAQ,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;EACjG,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB;EAC3B,QAAQ,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE;EAC5E,UAAU,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EAC9B,UAAU,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;EACvG,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC,CAAC;EACjG,QAAQ,MAAM;EACd,MAAM,KAAK,8BAA8B,CAAC;EAC1C,MAAM,KAAK,eAAe,CAAC;EAC3B,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,iBAAiB;EAC5B,QAAQ,OAAO,CAAC,cAAc,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;EACtF,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,6DAA6D,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK;EACL,GAAG,CAAC,CAAC;EACL,EAAE,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;EACrD,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACJ,OAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EACnE,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACA,OAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACA,OAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACA,OAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;EAC1E,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,oBAAoB,CAACA,OAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EACjE,EAAE,IAAI,MAAM,CAAC,YAAY,KAAK,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,YAAY,EAAE;EAC3E,IAAI,MAAM,CAAC,IAAI;EACf,MAAM,CAAC,gCAAgC,EAAE,oBAAoB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;EACrF,KAAK,CAAC;EACN,GAAG;EACH,EAAE,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;EACnD,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,gCAAgC,EAAE,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,cAAc,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;EACvI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;EACvB,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;EACjC,EAAE,IAAI,MAAM,CAAC,aAAa,EAAE;EAC5B,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;EAC3B,GAAG,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE;EAClC,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;EAC1B,GAAG;EACH,EAAE,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;EACnE,EAAE,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,cAAc,IAAI;EACnD,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EAC5F,GAAG,CAAC,CAAC;EACL,EAAE,MAAM,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;EACjE,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;EAClC,EAAE,IAAI,MAAM,CAAC,YAAY,KAAK,MAAM,CAAC,aAAa,EAAE;EACpD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;EACpB,IAAI,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;EAC3C,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC,sBAAsB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;EAC7E,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;;iBAEA,GAAG,WAAW,EAAE;eAClB,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE;iBACtB,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE;QAC3D,CAAC,CAAC,CAAC;EACX,IAAI,MAAM,EAAE,UAAU,EAAE,uBAAuB,EAAE,GAAG,MAAM,CAAC;EAC3D,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,MAAM,MAAM,OAAO,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC;EACjD,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EACtC,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;EAC1D,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;EAC3E,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;MACb,EAAE,SAAS,CAAC,QAAQ,CAAC;iBACV,GAAG,oBAAoB,EAAE;eAC3B,GAAG,eAAe,CAAC,IAAI,EAAE;iBACvB,GAAG,gBAAgB,CAAC,eAAe,EAAE,oBAAoB,CAAC,EAAE;QACrE,CAAC,CAAC,CAAC;EACX,KAAK;EACL,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;EAC1B,GAAG;EACH,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,oBAAoB,GAAG,IAAI,GAAG,oBAAoB,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;EACxF,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EACrC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACtB,EAAE,IAAI,MAAM,CAAC,SAAS,EAAE;EACxB,IAAI,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC;EACxD,GAAG;EACH,EAAE,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;EAEvC,EAAE,IAAI,eAAe,GAAG,EAAE,CAAC;EAC3B,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,cAAc,KAAK;EAC9C,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,cAAc,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC,CAAC;EACxE,GAAG,CAAC,CAAC;EACL,EAAE,OAAO,CAAC;;EAER,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,EAAE,kBAAkB,GAAG,kBAAkB,GAAG,EAAE,CAAC;AACjD,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;CACnB,CAAC,CAAC;EACH,CAAC;EAED,SAAS,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE;EAC7C,EAAE,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,KAAK,QAAQ,GAAG,UAAU,GAAG,CAAC,iBAAiB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;EAC9G,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;EACxB,IAAI,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,GAAG;EACH,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;EACxB,IAAI,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtF,GAAG;EAEH,EAAE,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,CAAC;EAED,SAAS,kBAAkB,CAAC,MAAM,EAAE;EACpC,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;EAChD,EAAE,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAC1D,EAAE,OAAOA,OAAK,CAAC,uBAAuB,CAAC,CAAC,EAAE,kBAAkB,GAAG,WAAW,GAAG,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE;EACjG,IAAI,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACtC,MAAM,IAAI,MAAM,KAAK,OAAO,EAAE;EAC9B,QAAQ,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAEA,OAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5D,OAAO;EACP,MAAM,OAAO,IAAI,CAAC;EAClB,KAAK;EACL,IAAI,UAAU,EAAE,CAAC,QAAQ,KAAK;EAC9B,MAAM,IAAI,QAAQ,KAAK,SAAS,EAAE;EAClC,QAAQ,OAAO,IAAI,CAAC;EACpB,OAAO;EACP,MAAM,IAAI,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;EAC3C,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;EAChD,OAAO;EACP,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;EAC5D,KAAK;EACL,GAAG,CAAC,CAAC;EACL,CAAC;EAED,SAAS,gBAAgB,CAAC,YAAY,EAAE,WAAW,EAAE;EACrD,EAAE,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;EAClD,EAAE,MAAM,kBAAkB,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACxD,EAAE,MAAM,kBAAkB,GAAGA,OAAK,CAAC,uBAAuB,CAAC,CAAC,EAAE,kBAAkB,GAAG,WAAW,GAAG,EAAE,CAAC,GAAG,OAAO,EAAE,CAAC,EAAE;EACnH,IAAI,cAAc,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK;EACtC,MAAM,IAAI,MAAM,KAAK,OAAO,EAAE;EAC9B,QAAQ,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,EAAEA,OAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;EAC5D,OAAO,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE;EACpC,QAAQ,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW,GAAG,EAAE,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;EAC1F,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;EAChD,OAAO;EACP,KAAK;EACL,IAAI,UAAU,EAAE,CAAC,QAAQ,KAAK;EAC9B,MAAM,IAAI,QAAQ,KAAK,SAAS,EAAE;EAClC,QAAQ,OAAO,WAAW,CAAC;EAC3B,OAAO;EACP,MAAM,IAAI,YAAY,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;EACjD,QAAQ,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;EACtD,OAAO;EACP,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;EAC5D,KAAK;EACL,GAAG,CAAC,CAAC;EACL,EAAE,OAAO,CAAC;EACR,EAAE,kBAAkB,CAAC;;GAEpB,CAAC,CAAC;EACL,CAAC;EAWD,SAAS,eAAe,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE;EAClF,EAAE,IAAI,QAAQ,KAAK,IAAI,EAAE,OAAO,IAAI,CAAC;EACrC,EAAE,QAAQ,OAAO,QAAQ;EACzB,IAAI,KAAK,SAAS,CAAC;EACnB,IAAI,KAAK,QAAQ;EACjB,MAAM,OAAO,IAAI,CAAC;EAClB,GAAG;EACH,EAAE;EACF,IAAI,OAAO,gBAAgB,KAAK,WAAW;EAC3C,IAAI,QAAQ,YAAY,gBAAgB;EACxC,IAAI;EACJ,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,MAAM,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EAC1C,MAAM,IAAI,WAAW,CAAC,IAAI,KAAK,gBAAgB,EAAE,SAAS;EAC1D,MAAM,IAAI,WAAW,CAAC,WAAW,KAAK,QAAQ,EAAE,SAAS;EAEzD,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;EACxD,MAAM,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,SAAS;EACzC,MAAM,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;EAC/E,MAAM,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;EACrD,MAAM,OAAO,YAAY,CAAC;EAC1B,KAAK;EACL,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChD,IAAI,MAAM,WAAW,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;EACxC,IAAI,IAAI,QAAQ,KAAK,WAAW,CAAC,WAAW,EAAE,SAAS;EACvD,IAAI,MAAM,QAAQ,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;EACvD,IAAI,OAAO,CAAC,cAAc,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;EAClD,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EACH,EAAE,OAAO,IAAI,CAAC;EACd,CAAC;;EC7UM,MAAM,WAAW,CAAC;EAMzB,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,MAAM;EACV,MAAM,IAAI;EACV,MAAM,MAAM;EACZ,MAAM,OAAO;EACb,MAAM,YAAY;EAClB,MAAM,sBAAsB;EAC5B,MAAM,qBAAqB;EAC3B,MAAM,MAAM;EACZ,MAAM,cAAc;EACpB,MAAM,IAAI;EACV,MAAM,MAAM;EACZ,KAAK,GAAG,QAAQ,CAAC;EACjB,IAAI,IAAI,CAAC,IAAI,EAAE;EACf,MAAM,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;EACtC,KAAK;EACL,IAAI,IAAI,CAAC,IAAI,EAAE;EACf,MAAM,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;EACtC,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,EAAE;EACjB,MAAM,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;EACxC,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,EAAE;EACjB,MAAM,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;EACxC,KAAK;EACL,IAAI,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,WAAW,EAAE;EACrD,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,+CAA+C,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,IAAI,CAAC,sBAAsB,EAAE;EACjC,MAAM,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;EAC3D,KAAK;EACL,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;EACrB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,OAAO,GAAG,MAAM,KAAK,WAAW,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;EACvE,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,IAAI,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;EAEzC,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;EACnC,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC;EACnC,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;EACtB,IAAI,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;EAC3B,IAAI,IAAI,CAAC,YAAY,GAAG,YAAY,KAAK,IAAI,IAAI,YAAY,KAAK,SAAS,GAAG,YAAY,GAAG,IAAI,CAAC;EAClG,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,sBAAsB,GAAG,sBAAsB,CAAC;EACzD,IAAI,IAAI,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;EACvD,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC7E,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,6BAA6B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;EAC/E,GAAG;EACH,CAAC;;EC9DM,MAAM,gBAAgB,SAAS,WAAW,CAAC;EAKlD,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;EAC7B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EACvB,IAAI,IAAI,CAAC,uBAAuB,GAAG,KAAK,CAAC,WAAW,CAAC;EACrD,IAAI,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC;EACtD,IAAI,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,cAAc,CAAC;EAClD,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;EACzB,GAAG;EAOH,EAAE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE;EAC3B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO;EACtC,IAAI,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC;EAChE,IAAI,IAAI,KAAK,GAAG,cAAc,IAAI,MAAM,GAAG,cAAc,EAAE;EAC3D,MAAM,IAAI,KAAK,GAAG,MAAM,EAAE;EAC1B,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,kBAAkB,EAAE,KAAK,CAAC,6BAA6B,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;EACjH,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,mBAAmB,EAAE,MAAM,CAAC,6BAA6B,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC,CAAC;EACnH,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,cAAc,GAAG;EACnB,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC3C,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EACxB,GAAG;EAEH,EAAE,YAAY,GAAG;EACjB,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;EACvD,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;EACvC,IAAI,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC;EACxC,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC;EACnC,GAAG;EAEH,EAAE,oBAAoB,CAAC,KAAK,EAAE;EAC9B,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;EACjC,MAAM,OAAO,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,QAAQ,KAAK,CAAC,WAAW;EAC7B,MAAM,KAAK,KAAK,CAAC;EACjB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,YAAY,CAAC;EAC5B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,YAAY;EACvB,QAAQ,OAAO,KAAK,CAAC,WAAW,CAAC;EACjC,KAAK;EACL,IAAI,OAAO,CAAC,IAAI,CAAC,wGAAwG,CAAC,CAAC;EAC3H,IAAI,OAAO,KAAK,CAAC,WAAW,CAAC;EAC7B,GAAG;EAUH,EAAE,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE;EAC3C,IAAI,IAAIA,OAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,mBAAmB,EAAE;EAE7D,MAAM,MAAM,UAAU,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;EAClD,MAAMA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;EACzC,MAAM,OAAO,UAAU,CAAC;EACxB,KAAK,MAAM;EACX,MAAM,QAAQ,KAAK,CAAC,WAAW;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,UAAU,CAAC;EACxB,QAAQ,KAAK,SAAS,CAAC;EACvB,QAAQ,KAAK,WAAW,CAAC;EACzB,QAAQ,KAAK,UAAU,CAAC;EACxB,QAAQ,KAAK,YAAY,CAAC;EAC1B,QAAQ,KAAK,UAAU,EAAE;EACzB,UAAU,MAAM,UAAU,GAAG,IAAI,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;EACpE,UAAUA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;EAC7C,UAAU,OAAO,UAAU,CAAC;EAC5B,SAAS;EACT,QAAQ,SAAS;EACjB,UAAU,MAAM,UAAU,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;EACtD,UAAUA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;EAC7C,UAAU,OAAO,UAAU,CAAC;EAC5B,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;EACjC,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;EACxC,KAAK,MAAM,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,EAAE;EAC5C,MAAM,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;EAC3C,KAAK;EACL,IAAI,QAAQ,KAAK,CAAC,WAAW;EAC7B,MAAM,KAAK,iBAAiB,CAAC;EAC7B,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM,KAAK,SAAS;EACpB,QAAQ,OAAO,CAAC,CAAC;EACjB,MAAM,KAAK,WAAW,CAAC;EACvB,MAAM,KAAK,UAAU;EACrB,QAAQ,OAAO,CAAC,CAAC;EACjB,MAAM,KAAK,YAAY,CAAC;EACxB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,CAAC,CAAC;EACjB,KAAK;EACL,GAAG;EAKH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,2CAA2C,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3F,GAAG;EAEH,EAAE,0BAA0B,GAAG;EAC/B,IAAI,QAAQ,IAAI,CAAC,MAAM;EACvB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,MAAM,CAAC;EACtB,MAAM,KAAK,aAAa;EACxB,QAAQ,OAAO,OAAO,CAAC;EACvB,MAAM,KAAK,UAAU,CAAC;EACtB,MAAM;EACN,QAAQ,OAAO,SAAS,CAAC;EACzB,KAAK;EACL,GAAG;EACH,CAAC;;ECrJM,MAAM,uBAAuB,SAAS,gBAAgB,CAAC;EAC9D,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;EACnD,KAAK;EACL,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EAChE,GAAG;EACH,CAAC;;ECpBM,MAAM,qBAAqB,SAAS,gBAAgB,CAAC;EAC5D,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;EACnC,QAAQ,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;EACxD,OAAO;EACP,MAAM,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;EACpD,KAAK;EACL,IAAI,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACzC,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EAChE,GAAG;EACH,CAAC;;ECtBM,MAAM,uBAAuB,SAAS,gBAAgB,CAAC;EAC9D,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;EAC9D,KAAK;EACL,IAAI,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EAChE,GAAG;EACH,CAAC;;ECnBM,MAAM,yBAAyB,SAAS,gBAAgB,CAAC;EAChE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;EACpC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;EACzC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,UAAU,EAAE;EAC1B,IAAI,IAAI,UAAU,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EACjE,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;EACjD,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,CAAC;EACvG,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECvCM,MAAM,gCAAgC,SAAS,yBAAyB,CAAC;EAChF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;EACpC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;EACzC,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECnBM,MAAM,yBAAyB,SAAS,yBAAyB,CAAC,EAAE;;ECApE,MAAM,gCAAgC,SAAS,gCAAgC,CAAC,EAAE;;ECClF,MAAM,2BAA2B,SAAS,gBAAgB,CAAC;EAClE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAClE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACnD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC5CM,MAAM,kCAAkC,SAAS,2BAA2B,CAAC;EACpF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECpBM,MAAM,6BAA6B,SAAS,gBAAgB,CAAC;EACpE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC5C,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,mCAAmC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EACjG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzG,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;EACnE,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAC5E,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,qBAAqB,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACxG,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,iCAAiC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;EAC3F,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EACrE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EACtD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACvI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC/CM,MAAM,oCAAoC,SAAS,6BAA6B,CAAC;EACxF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,mCAAmC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EACjG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzG,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;EACxD,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAC3D,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECtBM,MAAM,4CAA4C,SAAS,gBAAgB,CAAC;EACnF,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;EACrC,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;EACzE,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,YAAY,EAAE;EAC5B,IAAI,IAAI,YAAY,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EACnE,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE;EACpE,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,2BAA2B,CAAC,CAAC,CAAC;EACtF,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;EAC3E,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECrCM,MAAM,mDAAmD,SAAS,4CAA4C,CAAC;EACtH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,YAAY,EAAE;EAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;EAC9C,IAAI,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC;EACzC,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;EACpC,GAAG;EACH,CAAC;;ECjBM,MAAM,6BAA6B,SAAS,gBAAgB,CAAC;EACpE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EACxB,IAAI,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;EACpD,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC5C,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;EACjC,IAAI,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;EACnC,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC;EACrC,IAAI,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;EACnC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;EACzE,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,YAAY,EAAE;EAC5B,IAAI,IAAI,YAAY,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EACnE,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE;EACpE,MAAM,MAAM,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;EAC3E,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECvCM,MAAM,oCAAoC,SAAS,6BAA6B,CAAC;EACxF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EACjD,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC;EAClC,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECjBM,MAAM,2BAA2B,SAAS,gBAAgB,CAAC;EAClE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC3CM,MAAM,kCAAkC,SAAS,2BAA2B,CAAC;EACpF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECnBM,MAAM,8BAA8B,SAAS,gBAAgB,CAAC;EACrE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,GAAG;EAEH,EAAE,QAAQ,CAAC,KAAK,EAAE;EAClB,IAAI,MAAM,eAAe,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC7D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EACjE,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EChDM,MAAM,qCAAqC,SAAS,8BAA8B,CAAC;EAC1F,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECfM,MAAM,8BAA8B,SAAS,gBAAgB,CAAC;EACrE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,GAAG;EAEH,EAAE,QAAQ,CAAC,KAAK,EAAE;EAClB,IAAI,MAAM,eAAe,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC7D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;EAClF,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EChDM,MAAM,qCAAqC,SAAS,8BAA8B,CAAC;EAC1F,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECfM,MAAM,8BAA8B,SAAS,gBAAgB,CAAC;EACrE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;EACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,GAAG;EAEH,EAAE,QAAQ,CAAC,KAAK,EAAE;EAClB,IAAI,MAAM,eAAe,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC7D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACnG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC5D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACpD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC/H,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EChDM,MAAM,qCAAqC,SAAS,8BAA8B,CAAC;EAC1F,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECfM,MAAM,4BAA4B,SAAS,gBAAgB,CAAC;EACnE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACxE,KAAK;EACL,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAE1B,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO,EAAE,CAAC;EAC/C,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EACjE,GAAG;EACH,CAAC;;ECtBM,MAAM,4BAA4B,SAAS,gBAAgB,CAAC;EACnE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACpF,KAAK;EACL,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAE1B,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO,EAAE,CAAC;EAC/C,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EACjE,GAAG;EACH,CAAC;;ECtBM,MAAM,4BAA4B,SAAS,gBAAgB,CAAC;EACnE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;EAC7B,GAAG;EACH,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EAChG,KAAK;EACL,IAAI,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAE1B,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO,EAAE,CAAC;EAC/C,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EACjE,GAAG;EACH,CAAC;;ECtBM,MAAM,6BAA6B,SAAS,gBAAgB,CAAC;EACpE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC5C,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,mCAAmC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EACjG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzG,IAAI,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;EAC7D,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAC5E,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,qBAAqB,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;EACxG,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,iCAAiC,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;EAC3F,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;EAC/D,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/G,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACvI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC9CM,MAAM,oCAAoC,SAAS,6BAA6B,CAAC;EACxF,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,mCAAmC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EACjG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzG,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;EAClD,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAC3D,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECiBM,MAAM,eAAe,GAAG;EAC/B,EAAE,QAAQ,EAAE;EACZ,IAAI,OAAO,EAAE;EACb,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,qBAAqB;EACpC,MAAM,OAAO,EAAE,oCAAoC;EACnD,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,OAAO,EAAE,oCAAoC;EACnD,MAAM,eAAe,EAAE,oCAAoC;EAC3D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,8BAA8B,EAAE,4CAA4C;EAClF,MAAM,WAAW,EAAE,gCAAgC;EACnD,MAAM,gBAAgB,EAAE,KAAK;EAC7B,MAAM,WAAW,EAAE,gCAAgC;EACnD,KAAK;EACL,IAAI,MAAM,EAAE;EACZ,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,qBAAqB;EACpC,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,6BAA6B;EAC5C,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,OAAO,EAAE,6BAA6B;EAC5C,MAAM,eAAe,EAAE,6BAA6B;EACpD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,8BAA8B,EAAE,mDAAmD;EACzF,MAAM,WAAW,EAAE,yBAAyB;EAC5C,MAAM,gBAAgB,EAAE,KAAK;EAC7B,MAAM,WAAW,EAAE,yBAAyB;EAC5C,KAAK;EACL,GAAG;EACH,EAAE,MAAM,EAAE;EACV,IAAI,OAAO,EAAE;EACb,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,qBAAqB;EACpC,MAAM,OAAO,EAAE,kCAAkC;EACjD,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,YAAY,EAAE,qCAAqC;EACzD,MAAM,OAAO,EAAE,kCAAkC;EACjD,MAAM,eAAe,EAAE,oCAAoC;EAC3D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,iBAAiB,EAAE,oCAAoC;EAC7D,MAAM,8BAA8B,EAAE,mDAAmD;EACzF,MAAM,WAAW,EAAE,gCAAgC;EACnD,MAAM,gBAAgB,EAAE,KAAK;EAC7B,MAAM,WAAW,EAAE,gCAAgC;EACnD,KAAK;EACL,IAAI,MAAM,EAAE;EACZ,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,qBAAqB;EACpC,MAAM,SAAS,EAAE,uBAAuB;EACxC,MAAM,OAAO,EAAE,2BAA2B;EAC1C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,UAAU,EAAE,4BAA4B;EAC9C,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,YAAY,EAAE,8BAA8B;EAClD,MAAM,OAAO,EAAE,2BAA2B;EAC1C,MAAM,eAAe,EAAE,6BAA6B;EACpD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,iBAAiB,EAAE,6BAA6B;EACtD,MAAM,8BAA8B,EAAE,4CAA4C;EAClF,MAAM,WAAW,EAAE,yBAAyB;EAC5C,MAAM,gBAAgB,EAAE,KAAK;EAC7B,MAAM,WAAW,EAAE,yBAAyB;EAC5C,KAAK;EACL,GAAG;EACH,CAAC,CAAC;AAEF,EAAO,SAAS,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;EACvE,EAAE,IAAI,CAAC,IAAI,EAAE;EACb,IAAI,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;EACpC,GAAG;EACH,EAAE,IAAI,CAAC,OAAO,EAAE;EAChB,IAAI,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;EACvC,GAAG;EACH,EAAE,IAAI,CAAC,SAAS,EAAE;EAClB,IAAI,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;EACzC,GAAG;EACH,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE;EAClB,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;EACtB,GAAG;EACH,EAAE,MAAM,KAAK,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC;EACpD,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;EAC7B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EAClE,GAAG;EACH,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;EACrB,CAAC;;EC1KD,IAAI,WAAW,GAAG,IAAI,CAAC;EACvB,IAAI,UAAU,GAAG,IAAI,CAAC;EACtB,IAAI,WAAW,GAAG,IAAI,CAAC;EACvB,IAAI,cAAc,GAAG,IAAI,CAAC;EAC1B,IAAI,QAAQ,GAAG,IAAI,CAAC;EAEpB,MAAM,OAAO,GAAG,CAAC,aAAa,CAAC,CAAC;EAChC,MAAM,QAAQ,GAAG,EAAE,CAAC;EACpB,MAAM,WAAW,GAAG,EAAE,CAAC;AAqBvB,EAAO,MAAM,WAAW,SAAS,QAAQ,CAAC;EAC1C,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,IAAI,WAAW,KAAK,IAAI,EAAE;EAC9B,MAAM,OAAO,WAAW,CAAC;EACzB,KAAK;EACL,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;EAC9B,IAAI,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;EACnD,IAAI,OAAO,WAAW,CAAC;EACvB,GAAG;EAEH,EAAE,OAAO,kBAAkB,GAAG;EAC9B,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACzC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EACpD,KAAK,MAAM,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE;EACvD,MAAM,UAAU,GAAG,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EAC7C,KAAK;EACL,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO;EAC5B,IAAI,WAAW,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO;EAC1D,IAAI,cAAc,GAAG;EACrB,MAAM,iBAAiB,EAAE,WAAW,CAAC,YAAY,CAAC,mBAAmB,CAAC;EACtE,MAAM,wBAAwB,EAAE,WAAW,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACpF,MAAM,sBAAsB,EAAE,WAAW,CAAC,YAAY,CAAC,wBAAwB,CAAC;EAChF,MAAM,kBAAkB,EAAE,WAAW,CAAC,YAAY,CAAC,oBAAoB,CAAC;EACxE,KAAK,CAAC;EACN,IAAI,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;EAClC,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,IAAI,OAAO,qBAAqB,KAAK,WAAW,EAAE;EACtD,MAAM,OAAO,OAAO,YAAY,qBAAqB,CAAC;EACtD,KAAK;EACL,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAEH,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAClD,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC;EACzB,MAAM,WAAW,EAAE,IAAI,CAAC,cAAc,EAAE;EACxC,MAAM,yBAAyB,EAAE,IAAI,CAAC,4BAA4B,EAAE;EACpE,MAAM,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE;EAC9C,MAAM,aAAa;EACnB,MAAM,SAAS,EAAE,aAAa;EAC9B,MAAM,YAAY,EAAE,IAAI,CAAC,eAAe,EAAE;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,OAAO,iBAAiB,GAAG;EAC7B,IAAI,OAAO,OAAO,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;EACrD,GAAG;EAEH,EAAE,OAAO,gBAAgB,GAAG;EAC5B,IAAI,OAAO,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;EACtD,GAAG;EAEH,EAAE,OAAO,eAAe,GAAG;EAC3B,IAAI,OAAO,cAAc,CAAC,kBAAkB;EAC5C,MAAM,WAAW,CAAC,YAAY,CAAC,cAAc,CAAC,kBAAkB,CAAC,sBAAsB,CAAC;EACxF,MAAM,CAAC,CAAC;EACR,GAAG;EAEH,EAAE,OAAO,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;EAChE,IAAI,OAAO,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,WAAW,UAAU,GAAG;EAC1B,IAAI,OAAO,UAAU,CAAC;EACtB,GAAG;EAEH,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,OAAO,WAAW,CAAC;EACvB,GAAG;EAEH,EAAE,WAAW,QAAQ,GAAG;EACxB,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EAEH,EAAE,WAAW,cAAc,GAAG;EAC9B,IAAI,OAAO,cAAc,CAAC;EAC1B,GAAG;EAEH,EAAE,WAAW,YAAY,GAAG;EAC5B,IAAI,OAAO,YAAY,CAAC;EACxB,GAAG;EAOH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;EACxB,IAAI,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;EACtC,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,gBAAgB,EAAE,CAAC;EAC/C,IAAI,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;EACzB,IAAI,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;EACxC,IAAI,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;EAChC,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;EACvC,IAAI,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;EACrC,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;EAM9B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;EAC3B,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;EAEtC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;EAMpD,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;EAC1B,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EACvB,IAAI,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;EAC3B,IAAI,IAAI,CAAC,2BAA2B,GAAG,EAAE,CAAC;EAC1C,IAAI,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;EAC7B,IAAI,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;EAC7B,IAAI,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC;EAC7B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,GAAG;EAEH,EAAE,UAAU,GAAG;EACf,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACzC,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EAEtD,MAAM,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;EACvB,MAAM,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;EACxB,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK,MAAM,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE;EACvD,MAAM,OAAO,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EACvC,KAAK;EACL,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,MAAM,QAAQ,GAAG;EACrB,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,SAAS,EAAE,KAAK;EACtB,KAAK,CAAC;EACN,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;EAC/G,GAAG;EAEH,EAAE,WAAW,CAAC,QAAQ,EAAE;EAExB,IAAI,MAAM,YAAY,GAAG,EAAE,CAAC;EAC5B,IAAI,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;EAC5B,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EACpC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC/C,QAAQ,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAClC,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;EAChD,UAAU,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,SAAS;EACT,OAAO;EACP,KAAK,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EAE3C,MAAM,IAAI,QAAQ,CAAC,WAAW,EAAE;EAChC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,UAAU,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACpC,UAAU,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,IAAI,UAAU,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC;EAChG,UAAU,IAAI,SAAS,EAAE;EACzB,YAAY,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACtC,WAAW;EACX,SAAS;EACT,OAAO;EACP,KAAK;EACL,IAAI,OAAO,YAAY,CAAC;EACxB,GAAG;EAEH,EAAE,cAAc,GAAG;EACnB,IAAI,IAAI,CAAC,UAAU,GAAG;EACtB,MAAM,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,mBAAmB,CAAC;EACvE,MAAM,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACrF,MAAM,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC;EACjF,MAAM,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC;EACzE,MAAM,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACrF,KAAK,CAAC;EACN,GAAG;EAMH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;EACxB,MAAM,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,oBAAoB,CAAC;EAChD,QAAQ,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACrD,QAAQ,SAAS,EAAE,IAAI,CAAC,SAAS;EACjC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACtB,MAAM,OAAO;EACb,KAAK;EAEL,IAAI,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC;EAC1C,IAAI,IAAI,IAAI,CAAC,mBAAmB,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;EACvE,MAAM,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;EAC1D,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;EACrE,MAAM,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;EACxD,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,QAAQ,CAAC,cAAc,EAAE;EACtF,MAAM,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;EACpE,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE;EAC9F,MAAM,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;EACtE,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,0BAA0B,KAAK,IAAI,EAAE;EAClD,MAAM,IAAI,CAAC,0BAA0B,GAAG,CAAC,QAAQ,CAAC,yBAAyB,CAAC;EAC5E,KAAK,MAAM,IAAI,IAAI,CAAC,0BAA0B,IAAI,QAAQ,CAAC,yBAAyB,EAAE;EACtF,MAAM,IAAI,CAAC,0BAA0B,GAAG,KAAK,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;EAEvB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAClD,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;EAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;EACtF,OAAO;EAEP,MAAM,MAAM,OAAO,GAAGA,OAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAC1E,MAAM,IAAI,OAAO,KAAK,OAAO,EAAE;EAC/B,QAAQ,IAAI,CAAC,MAAM,GAAGA,OAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;EACnD,OAAO,MAAM,IAAI,OAAO,KAAK,eAAe,IAAI,OAAO,KAAK,iBAAiB,EAAE;EAC/E,QAAQ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACrC,OAAO,MAAM;EACb,QAAQ,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,OAAO,CAAC,CAAC;EAChF,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EACpC,QAAQ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;EAC3E,OAAO;EAEP,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,WAAW,EAAE;EAC1C,QAAQ,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;EACpC,QAAQ,OAAO,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;EACxF,OAAO;EAEP,MAAM,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9C,MAAM,OAAO;EACb,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,QAAQ,CAAC,cAAc,EAAE;EACnE,MAAM,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;EAChC,KAAK;EAEL,IAAI,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,oBAAoB,CAAC;EAC9C,MAAM,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACnD,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAEpB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC5B,GAAG;EAEH,EAAE,gBAAgB,GAAG;EACrB,IAAI,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;EACrC,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EAClC,MAAM,IAAI,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;EACjD,MAAM,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE;EAC9B,QAAQ,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC;EACtC,QAAQ,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9B,QAAQ,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5D,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACtC,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE;EACzC,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACtC,KAAK;EACL,GAAG;EAGH,EAAE,mBAAmB,GAAG;EACxB,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE;EAChF,MAAM,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;EACjE,KAAK,CAAC,CAAC;EAGP,IAAI,MAAM,gBAAgB,GAAG,eAAe,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;EAE1E,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC1B,MAAM,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,mBAAmB,EAAE,CAAC;EAC9D,KAAK;EAEL,IAAI,IAAI,gBAAgB,GAAG,CAAC,CAAC;EAC7B,IAAI,MAAM,WAAW,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC;EACzD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,MAAM,QAAQ,WAAW,CAAC,CAAC,CAAC;EAC5B,QAAQ,KAAK,OAAO,CAAC;EACrB,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,SAAS;EACtB,UAAU,gBAAgB,EAAE,CAAC;EAC7B,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,gBAAgB,IAAI,CAAC,CAAC;EAChC,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,gBAAgB,IAAI,CAAC,CAAC;EAChC,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,gBAAgB,IAAI,CAAC,CAAC;EAChC,UAAU,MAAM;EAChB,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,QAAQ,IAAI,gBAAgB,GAAG,QAAQ,CAAC,YAAY,EAAE;EAC9D,MAAM,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;EAC5C,KAAK;EAEL,IAAI,OAAO,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;EACpD,GAAG;EAEH,EAAE,cAAc,CAAC,IAAI,EAAE;EACvB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;EAClC,IAAI,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC;EAE3D,IAAI,IAAI,kBAAkB,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC9B,KAAK;EACL,IAAI,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;EAGhC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;EACjD,MAAM,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;EACzD,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;EACxD,MAAM,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;EACvD,KAAK;EAEL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,cAAc,GAAG,CAAC,CAAC;EAC3B,IAAI,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;EACtD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;EAChC,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;EAC7C,MAAM,IAAI,IAAI,CAAC;EACf,MAAM,IAAI,kBAAkB,EAAE;EAC9B,QAAQ,IAAI,GAAGA,OAAK,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EACjE,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EACtC,OAAO,MAAM;EACb,QAAQ,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;EACzC,OAAO;EACP,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,SAAS,GAAG,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;EAClJ,MAAM,IAAI,WAAW,KAAK,IAAI,EAAE;EAChC,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC1C,OAAO;EACP,MAAM,MAAM,cAAc,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE;EACpD,QAAQ,IAAI;EACZ,QAAQ,IAAI;EACZ,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAM;EAC3B,QAAQ,MAAM,EAAE,MAAM;EACtB,QAAQ,OAAO,EAAE,EAAE;EACnB,QAAQ,YAAY,EAAE,IAAI,CAAC,YAAY;EACvC,QAAQ,MAAM,EAAE,IAAI;EACpB,QAAQ,cAAc,EAAE,IAAI,CAAC,cAAc;EAC3C,QAAQ,gBAAgB,EAAE,MAAM;EAChC,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EAC9C,SAAS;EACT,QAAQ,cAAc,EAAE,MAAM;EAC9B,UAAU,OAAO,cAAc,EAAE,CAAC;EAClC,SAAS;EACT,QAAQ,qBAAqB,EAAE,MAAM;EACrC,UAAU,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;EACvC,SAAS;EACT,QAAQ,sBAAsB,EAAE,MAAM;EACtC,UAAU,OAAO,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;EACvF,SAAS;EACT,OAAO,CAAC,CAAC;EACT,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAChD,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;EAC1D,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC;EAC9D,KAAK;EACL,GAAG;EAEH,EAAE,cAAc,CAAC,IAAI,EAAE;EACvB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,0BAA0B,GAAG,EAAE,CAAC;EACzC,IAAI,IAAI,kBAAkB,GAAG,IAAI,CAAC,aAAa,KAAK,IAAI,CAAC;EACzD,IAAI,IAAI,kBAAkB,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;EAC9B,KAAK;EACL,IAAI,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;EAChC,IAAI,IAAI,cAAc,GAAG,CAAC,CAAC;EAC3B,IAAI,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACvC,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;EACzC,MAAM,IAAI,IAAI,CAAC;EACf,MAAM,IAAI,kBAAkB,EAAE;EAC9B,QAAQ,IAAI,GAAGA,OAAK,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EACjE,QAAQ,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;EACxC,OAAO,MAAM;EACb,QAAQ,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;EACxC,OAAO;EACP,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;EACxG,MAAM,IAAI,WAAW,KAAK,IAAI,EAAE;EAChC,QAAQ,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC1C,OAAO;EACP,MAAM,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,KAAK,EAAE;EACjD,QAAQ,IAAI;EACZ,QAAQ,IAAI;EACZ,QAAQ,MAAM,EAAE,IAAI,CAAC,MAAM;EAC3B,QAAQ,MAAM,EAAE,WAAW;EAC3B,QAAQ,OAAO,EAAE,IAAI,CAAC,OAAO;EAC7B,QAAQ,YAAY,EAAE,IAAI,CAAC,YAAY;EACvC,QAAQ,MAAM,EAAE,IAAI;EACpB,QAAQ,cAAc,EAAE,IAAI,CAAC,cAAc;EAC3C,QAAQ,gBAAgB,EAAE,MAAM;EAChC,UAAU,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EAC9C,SAAS;EACT,QAAQ,cAAc,EAAE,MAAM;EAC9B,UAAU,OAAO,cAAc,EAAE,CAAC;EAClC,SAAS;EACT,QAAQ,sBAAsB,EAAE,MAAM;EACtC,UAAU,OAAO,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;EAC3D,SAAS;EACT,OAAO,CAAC,CAAC;EACT,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC;EAC1D,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,MAAM,IAAI,WAAW,CAAC,kBAAkB,EAAE;EAC1C,QAAQ,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EAC1D,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,KAAK,GAAG;EACV,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;EACrC,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;EACnC,IAAI,IAAI,IAAI,CAAC,iBAAiB,EAAE,OAAO;EACvC,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;EACnC,IAAI,IAAI,IAAI,CAAC,iBAAiB,EAAE,OAAO;EACvC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC5B,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;EAC3B,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;EAC7D,IAAI,IAAI,aAAa,EAAE;EACvB,MAAM,OAAO,aAAa,CAAC;EAC3B,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;EAClD,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;EAC/B,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACtD,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAChE,MAAM,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EACxC,MAAM,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAChE,MAAM,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EACxC,MAAM,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EACzC,KAAK;EACL,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC/D,IAAI,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;EACjC,MAAM,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EACxB,KAAK;EAEL,IAAI,MAAM,oBAAoB,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;EACjE,IAAI,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;EACzD,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;EACtD,IAAI,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;EAEjC,IAAI,MAAM,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;EACrE,IAAI,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;EAC3D,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;EACxD,IAAI,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;EACjC,IAAI,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;EAEjC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;EACpB,MAAM,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;EACzC,MAAM,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;EAC1C,KAAK;EAEL,IAAI,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE;EAC/D,MAAM,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;EAC3F,KAAK;EACL,IAAI,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,CAAC,EAAE;EAC/D,MAAM,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,EAAE,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;EAC7F,KAAK;EAEL,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;EACtD,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;EAC5B,IAAI,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,iBAAiB,EAAE,CAAC;EAC9C,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EACxC,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;EAEzC,IAAI,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;EAC7C,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;EAClB,MAAM,CAAC,EAAE,CAAC;EACV,KAAK,CAAC,CAAC;EACP,IAAI,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC;EACvC,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,MAAM,CAAC,EAAE,CAAC;EACV,KAAK,CAAC,CAAC;EAEP,IAAI,MAAM,cAAc,GAAG,QAAQ,CAAC,UAAU,CAAC;EAE/C,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;EAC7B,IAAI,IAAI,CAAC,MAAM,EAAE;EACjB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC;EAC/C,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC7C,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC;EACjG,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;EAC7C,KAAK;EAEL,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;EACnD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,SAAS,CAAC,CAAC;EAEjE,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;EAC/D,IAAI,EAAE,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;EACxC,IAAI,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC9D,IAAI,MAAM,YAAY,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,mBAAmB,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC;EAChF,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAEzD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;EACd,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAChC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE;EAClC,MAAM,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;EACzB,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACjC,MAAM;EACN,QAAQ,IAAI,CAAC,UAAU,KAAK,IAAI;EAChC,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;EAClC,QAAQ;EACR,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;EACvC,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,EAAE;EAChF,MAAM,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;EACjE,KAAK,CAAC,CAAC;EACP,IAAI,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;EACzE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC7C,MAAM,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,mBAAmB,EAAE,CAAC;EAC9D,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACvD,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC7C,QAAQ,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;EACnC,UAAU,SAAS,CAAC,UAAU,GAAG,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;EAC3E,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,GAAG,GAAG;EACR,IAAI,MAAM,EAAE,eAAe,EAAE,0BAA0B,EAAE,GAAG,IAAI,CAAC;EACjE,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;EACjC,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAE5B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAChC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAE7C,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;EACvE,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAEjG,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,0BAA0B,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChE,MAAM,MAAM,QAAQ,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC;EACrD,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1D,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO;EACxC,KAAK;EACL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,eAAe,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EACnD,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO;EACxC,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EACvC,QAAQ,IAAI,MAAM,CAAC,WAAW,EAAE;EAChC,UAAU,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;EACnC,SAAS;EACT,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;EACnD,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,QAAQ,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,SAAS,EAAE;EACnD,UAAU,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACrC,SAAS;EACT,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC/C,QAAQ,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC;EAC3C,UAAU,OAAO,EAAE,IAAI,CAAC,aAAa;EACrC,UAAU,IAAI,EAAE,OAAO;EACvB,UAAU,UAAU,EAAE,IAAI,CAAC,SAAS;EACpC,UAAU,MAAM,EAAE,IAAI,CAAC,MAAM;EAC7B,UAAU,OAAO,EAAE,IAAI,CAAC,OAAO;EAC/B,SAAS,CAAC,CAAC;EACX,OAAO;EACP,MAAM,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;EACjD,MAAM,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;EAC/C,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC7C,MAAM,OAAO;EACb,KAAK;EAEL,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACzD,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACjC,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EAClC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE;EAC1B,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;EACvC,OAAO;EACP,MAAM,IAAI,CAAC,UAAU,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC/E,KAAK;EAEL,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC3C,GAAG;EAMH,EAAE,gBAAgB,GAAG;EACrB,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC;EAC9B,GAAG;EAKH,EAAE,mBAAmB,GAAG;EACxB,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAC5B,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;EACjC,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EACtE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAC1F,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC3C,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EAMvE,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACrC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EAEzB,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,mBAAmB,EAAE;EAC1C,cAAc,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC3G,aAAa,MAAM;EACnB,cAAc,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EAC3G,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACzG,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACzG,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACzG,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;EACjC,cAAc,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;EACvD,aAAa;EACb,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACrG,OAAO;EACP,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;EAC3G,KAAK;EACL,IAAI,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;EAC7F,GAAG;EAKH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAC5B,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;EACjC,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;EACjD,IAAI,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EACnD,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACjD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC7D,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;EAChG,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EAC3E,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EAC3E,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACzE,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACzE,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACvC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACrG,OAAO,MAAM;EACb,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;EAC7G,OAAO;EACP,MAAM,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;EACvG,KAAK;EACL,GAAG;EAOH,EAAE,eAAe,CAAC,IAAI,EAAE;EACxB,IAAI,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAChD,MAAM,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;EACrC,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EAClE,GAAG;EAMH,EAAE,kBAAkB,CAAC,IAAI,EAAE;EAC3B,IAAI,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;EACnC,GAAG;EAEH,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;EAC5B,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAClD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC9C,MAAM,IAAI,KAAK,KAAK,KAAK,EAAE;EAC3B,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACtC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE;EAC5B,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAClD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC9C,MAAM,IAAI,KAAK,KAAK,KAAK,EAAE;EAC3B,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACtC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE;EACrC,IAAI,IAAI,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAClD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;EAC9C,MAAM;EACN,QAAQ,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC;EAC3B,QAAQ,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC;EAC3B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;EACjD,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;EAChD,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAEH,EAAE,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;EAC7B,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EACnD,MAAM,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;EAC/C,MAAM;EACN,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;EAC7B,QAAQ;EACR,QAAQ,OAAO;EACf,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;EACvC,IAAI,MAAM,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;EAC9C,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;EACxC,GAAG;EAOH,EAAE,kBAAkB,CAAC,IAAI,EAAE;EAC3B,IAAI,IAAI,IAAI,CAAC,2BAA2B,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE;EAC/D,MAAM,OAAO,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC;EACpD,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,2BAA2B,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;EACxG,GAAG;EASH,EAAE,yBAAyB,CAAC,IAAI,EAAE;EAClC,IAAI,OAAO;EACX,MAAM,MAAM,EAAE,IAAI,CAAC,gBAAgB,EAAE;EACrC,MAAM,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE;EACxC,MAAM,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE;EACvC,MAAM,SAAS,EAAE,IAAI,CAAC,mBAAmB,EAAE;EAC3C,MAAM,mBAAmB,EAAE,IAAI,CAAC,4BAA4B,EAAE;EAC9D,MAAM,mBAAmB,EAAE,IAAI,CAAC,4BAA4B,EAAE;EAC9D,MAAM,yBAAyB,EAAE,IAAI,CAAC,gCAAgC,EAAE;EACxE,MAAM,eAAe,EAAE,IAAI,CAAC,kBAAkB,EAAE;EAChD,MAAM,cAAc,EAAE,IAAI,CAAC,uBAAuB,EAAE;EACpD,MAAM,cAAc,EAAE,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;EACxD,MAAM,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE;EACpC,MAAM,WAAW,EAAE,IAAI,CAAC,mBAAmB,EAAE;EAC7C,MAAM,wBAAwB,EAAE,IAAI,CAAC,yBAAyB,EAAE;EAChE,MAAM,sBAAsB,EAAE,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,6BAA6B,EAAE,IAAI,CAAC,6BAA6B,EAAE;EACzE,MAAM,mCAAmC,EAAE,IAAI,CAAC,kCAAkC,EAAE;EACpF,KAAK,CAAC;EACN,GAAG;EASH,EAAE,yBAAyB,CAAC,IAAI,EAAE;EAClC,IAAI,OAAO;EACX,MAAM,wBAAwB,EAAE,IAAI,CAAC,yBAAyB,EAAE;EAChE,MAAM,sBAAsB,EAAE,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,6BAA6B,EAAE,IAAI,CAAC,6BAA6B,EAAE;EACzE,MAAM,mCAAmC,EAAE,IAAI,CAAC,kCAAkC,EAAE;EACpF,KAAK,CAAC;EACN,GAAG;EAQH,EAAE,gBAAgB,GAAG;EACrB,IAAI;EACJ,MAAM,IAAI,CAAC,UAAU,KAAK,IAAI;EAC9B,MAAM,4CAA4C;EAClD,MAAM,EAAE;EACR,MAAM;EACN,GAAG;EAMH,EAAE,iBAAiB,GAAG;EACtB,IAAI;EACJ,MAAM,IAAI,CAAC,iBAAiB;EAC5B,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC;EAC/C,MAAM,UAAU;EAChB,MAAM;EACN,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,CAAC;EACnC,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAChI,GAAG;EAMH,EAAE,mBAAmB,GAAG;EACxB,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;EACxC,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,0BAA0B;EAClC,QAAQ,wBAAwB;EAChC,OAAO,CAAC;EACR,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACrF,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9D,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAMH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACtD,MAAM,OAAO,2BAA2B,CAAC;EACzC,KAAK,MAAM;EACX,MAAM,OAAO,uBAAuB,CAAC;EACrC,KAAK;EACL,GAAG;EAMH,EAAE,4BAA4B,GAAG;EACjC,IAAI;EACJ,MAAM,IAAI,CAAC,UAAU,KAAK,IAAI;EAC9B,MAAM,EAAE;EACR,MAAM,8BAA8B;EACpC,MAAM;EACN,GAAG;EAMH,EAAE,4BAA4B,GAAG;EACjC,IAAI;EACJ,MAAM,IAAI,CAAC,UAAU,KAAK,IAAI;EAC9B,MAAM,EAAE;EACR,MAAM,8BAA8B;EACpC,MAAM;EACN,GAAG;EAMH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO,IAAI,CAAC,0BAA0B;EAC1C,MAAM,CAAC;;;;;CAKN,CAAC;EACF,MAAM,EAAE,CAAC;EACT,GAAG;EAOH,EAAE,uBAAuB,CAAC,IAAI,EAAE;EAChC,IAAI,MAAM,OAAO,GAAG,EAAE,CAAC;EACvB,IAAI,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;EACnC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACnD,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,KAAK;EACL,IAAI,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC5B,GAAG;EAEH,EAAE,kBAAkB,GAAG;EACvB,IAAI,OAAO,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC;EACrC,GAAG;EAEH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,SAAS,EAAE;EACnB,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;EAChB,MAAM,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE;EACpC,QAAQ,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/E,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EAMH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,uBAAuB,CAAC;EAChC,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS;EACpB,QAAQ,uBAAuB,GAAG,oBAAoB,CAAC;EACvD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;EAC5B,UAAU,uBAAuB,GAAG,oBAAoB,CAAC;EACzD,SAAS,MAAM;EACf,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;EAC7E,SAAS;EACT,KAAK;EAEL,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE;EAC7B,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,uBAAuB;EAC/B,OAAO,CAAC;EACR,MAAM,QAAQ,IAAI,CAAC,UAAU;EAC7B,QAAQ,KAAK,QAAQ,CAAC;EACtB,QAAQ,KAAK,OAAO,CAAC;EACrB,QAAQ,KAAK,SAAS;EACtB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,YAAY,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EAC5C,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,SAAS,CAAC,UAAU,KAAK,SAAS;EAChD,cAAc,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;EAC3D,cAAc,CAAC,sBAAsB,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;EAC/D,aAAa,CAAC;EACd,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,qBAAqB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;EAC5D,aAAa,CAAC;EACd,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,qBAAqB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;EAC5D,aAAa,CAAC;EACd,WAAW;EACX,UAAU,MAAM;EAChB,QAAQ,KAAK,UAAU;EACvB,UAAU,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACtD,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,qBAAqB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;EAC5D,aAAa,CAAC;EACd,WAAW;EACX,UAAU,MAAM;EAChB,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,uBAAuB;EAC/B,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC;EAC/D,GAAG;EAEH,EAAE,sBAAsB,GAAG;EAC3B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,8BAA8B;EACpC,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,yBAAyB,GAAG;EAC9B,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,IAAI,CAAC,+BAA+B,EAAE;EACrD,UAAU,IAAI,CAAC,kCAAkC,EAAE,CAAC;EACpD,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,yCAAyC,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;EAClG,KAAK;EACL,GAAG;EAKH,EAAE,+BAA+B,GAAG;EACpC,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,CAAC,mBAAmB,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,cAAc,CAAC;EACjG,KAAK,CAAC,CAAC;EACP,GAAG;EAKH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;EACpC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;EACjJ,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1I,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,cAAc;EACpB,KAAK,CAAC;EAEN,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;EAC9C,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,UAAU,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EACtC,UAAU,IAAI,CAAC,wCAAwC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;EACzE,UAAU,IAAI,CAAC,2CAA2C,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;EAC5E,UAAU,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE;EACvC,YAAY,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EACxC,WAAW;EACX,SAAS;EACT,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,2CAA2C,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;EACnG,KAAK;EAEL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,wCAAwC,CAAC,MAAM,EAAE,OAAO,EAAE;EAC5D,IAAI,MAAM,CAAC,IAAI;EACf,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,eAAe,CAAC;EAClD,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,2CAA2C,CAAC,MAAM,EAAE,OAAO,EAAE;EAC/D,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAClG,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EAC3F,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,oCAAoC;EAC1C,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,6BAA6B,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;EACjF,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;EAC1E,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,uCAAuC;EAC7C,MAAM,uCAAuC;EAC7C,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,uCAAuC;EAC7C,MAAM,uCAAuC;EAC7C,MAAM,uCAAuC;EAC7C,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,QAAQ,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACpF,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,iCAAiC;EACvC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,SAAS;EACpB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACzD,UAAU,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC/C,UAAU,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAClD,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,0BAA0B,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EAC3F,aAAa,CAAC;EACd,WAAW,MAAM;EACjB,YAAY,MAAM,CAAC,IAAI;EACvB,cAAc,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,oBAAoB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACpF,aAAa,CAAC;EACd,WAAW;EACX,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACzD,UAAU,MAAM,CAAC,IAAI;EACrB,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACzD,UAAU,MAAM,CAAC,IAAI;EACrB,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACzD,UAAU,MAAM,CAAC,IAAI;EACrB,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,YAAY,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;EACxF,WAAW,CAAC;EACZ,SAAS;EACT,QAAQ,MAAM;EACd,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAMH,EAAE,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE;EAC7B,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,+CAA+C,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK;EAC7F,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE;EACxC,QAAQ,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;EAC7B,OAAO;EACP,MAAM,MAAM,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC,CAAC;EAC7C,KAAK,CAAC,CAAC;EACP,GAAG;EAUH,EAAE,iBAAiB,CAAC,IAAI,EAAE;EAC1B,IAAI,IAAI,IAAI,CAAC,sBAAsB,KAAK,IAAI,EAAE;EAC9C,MAAM,OAAO,IAAI,CAAC,sBAAsB,CAAC;EACzC,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;EACtI,GAAG;EAOH,EAAE,eAAe,CAAC,IAAI,EAAE;EACxB,IAAI,IAAI,IAAI,CAAC,oBAAoB,KAAK,IAAI,EAAE;EAC5C,MAAM,OAAO,IAAI,CAAC,oBAAoB,CAAC;EACvC,KAAK;EACL,IAAI,OAAO,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC;EAClI,GAAG;EAKH,EAAE,QAAQ,GAAG;EACb,IAAI,MAAM,kBAAkB,GAAGA,OAAK,CAAC,aAAa,CAAC;EACnD,MAAM,CAAC,kBAAkB,CAAC;EAC1B,KAAK,CAAC,CAAC;EACP,IAAI,OAAO,cAAc,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,CAAC,CAAC;EACjF,GAAG;EAEH,EAAE,OAAO,CAAC,sBAAsB,EAAE;EAClC,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACrD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE;EACrB,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC7C,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE;EAC1B,MAAM,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;EACvD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;EACzB,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;EACzB,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;EACjD,KAAK;EACL,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC/C,KAAK;EAEL,IAAI,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;EAEhD,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1C,MAAM,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EAC3B,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1D,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,uBAAuB,EAAE;EACtC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpE,QAAQ,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC;EACpE,OAAO;EACP,KAAK;EACL,IAAI,IAAI,sBAAsB,EAAE;EAChC,MAAM,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAChD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE;EACpB,QAAQ,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;EAC7B,QAAQ,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;EAChC,OAAO;EACP,KAAK;EACL,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;EAC7B,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC;EACxB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC;EACvB,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,GAAG,IAAI,CAAC;EAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACpD,IAAI,IAAI,CAAC,UAAU,CAAC,sBAAsB,GAAG,IAAI,CAAC;EAClD,IAAI,IAAI,CAAC,UAAU,CAAC,kBAAkB,GAAG,IAAI,CAAC;EAC9C,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EACjC,IAAI,MAAM,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,oBAAoB,CAAC,CAAC;EACjE,IAAI,IAAI,SAAS,EAAE;EACnB,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;EAC9B,KAAK;EACL,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;EAChC,IAAI,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,MAAM,EAAE,CAAC;EACtF,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,CAAC;;EC5gDM,MAAM,kBAAkB,SAAS,iBAAiB,CAAC;EAQ1D,EAAE,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE;EAC3C,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY,EAAE;EACvC,MAAM,MAAM,IAAI,CAAC,cAAc;EAC/B,QAAQ,0CAA0C;EAClD,QAAQ,OAAO;EACf,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;EAEvC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE;EACrC,MAAM,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;EAChD,KAAK,MAAM,IAAI,IAAI,KAAK,SAAS,EAAE;EACnC,MAAM,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;EACzD,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;EAClD,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC5C,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC1C,KAAK;EAEL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EACH,CAAC;;ECvCM,MAAMK,gBAAc,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqY9B,CAAC,CAAC;;ECrYI,MAAMC,cAAY,GAAG,CAAC;;;;;;;;;;;;;;CAc5B,CAAC,CAAC;;ECbI,MAAM,wBAAwB,SAAS,uBAAuB,CAAC,EAAE;;ECAjE,MAAM,sBAAsB,SAAS,qBAAqB,CAAC,EAAE;;ECA7D,MAAM,wBAAwB,SAAS,uBAAuB,CAAC;EACtE,EAAE,SAAS,CAAC,KAAK,EAAE;EACnB,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE;EACrC,MAAM,OAAO,CAAC,MAAM,GAAG,iBAAiB,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;EACrF,KAAK;EACL,IAAI,OAAO,CAAC,QAAQ,GAAG,iBAAiB,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;EAC9D,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,OAAO;EAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC;EAChE,GAAG;EACH,CAAC;;ECZM,MAAM,0BAA0B,SAAS,yBAAyB,CAAC;EAC1E,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAON,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,iCAAiC,SAAS,gCAAgC,CAAC;EACxF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,+BAA+B,SAAS,gBAAgB,CAAC;EACtE,EAAE,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE;EAC/B,IAAI,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;EAC3B,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;EACpD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;EAC1B,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;EACtE,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;EACzD,GAAG;EACH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;EACjE,GAAG;EACH,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAChE,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,MAAM,EAAE;EACtB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EACtD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EAC7E,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,gBAAgB,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EAC7E,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;EAEjD,IAAI,EAAE,CAAC,UAAU;EACjB,MAAM,EAAE,CAAC,gBAAgB;EACzB,MAAM,CAAC;EACP,MAAM,EAAE,CAAC,IAAI;EACb,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;EACrB,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;EACtB,MAAM,MAAM,CAAC,MAAM;EACnB,MAAM,CAAC;EACP,MAAM,EAAE,CAAC,IAAI;EACb,MAAM,EAAE,CAAC,aAAa;EACtB,MAAM,IAAI;EACV,KAAK,CAAC;EACN,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5C,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC;EACxB,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC;EACxB,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC;EAC3B,MAAM,EAAE,CAAC,aAAa;EACtB,QAAQ,EAAE,CAAC,gBAAgB;EAC3B,QAAQ,CAAC;EACT,QAAQ,OAAO;EACf,QAAQ,OAAO;EACf,QAAQ,CAAC;EACT,QAAQ,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK;EACvB,QAAQ,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM;EACxB,QAAQ,UAAU;EAClB,QAAQ,EAAE,CAAC,IAAI;EACf,QAAQ,EAAE,CAAC,aAAa;EACxB,QAAQ,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC;EACpC,OAAO,CAAC;EACR,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC7DM,MAAM,sCAAsC,SAAS,+BAA+B,CAAC;EAC5F,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAO,KAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAChE,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,MAAM,EAAE;EACtB,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;EACxC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EAClC,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;EACrD,IAAI,IAAI,CAAC,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;EACvC,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;EAC9B,GAAG;EACH,CAAC;;ECnBM,MAAM,0BAA0B,SAAS,0BAA0B,CAAC,EAAE;;ECAtE,MAAM,iCAAiC,SAAS,iCAAiC,CAAC,EAAE;;ECCpF,MAAM,4BAA4B,SAAS,2BAA2B,CAAC;EAC9E,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACnD,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECtBM,MAAM,mCAAmC,SAAS,4BAA4B,CAAC;EACtF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;EAC/B,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC/D,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECrBM,MAAM,8BAA8B,SAAS,6BAA6B,CAAC;EAClF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,qCAAqC,SAAS,oCAAoC,CAAC;EAChG,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,6CAA6C,SAAS,4CAA4C,CAAC;EAChH,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;EACvE,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;EAC/B,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5F,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAClH,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECVM,MAAM,oDAAoD,SAAS,mDAAmD,CAAC;EAC9H,EAAE,SAAS,GAAG;EACd,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,kBAAkB,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACpC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EAC1C,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECRM,MAAM,8BAA8B,SAAS,6BAA6B,CAAC;EAClF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;EACvE,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;EACtD,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC5F,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,YAAY,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAClH,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECVM,MAAM,qCAAqC,SAAS,oCAAoC,CAAC;EAChG,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,4BAA4B,SAAS,2BAA2B,CAAC;EAC9E,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;EC1BM,MAAM,mCAAmC,SAAS,4BAA4B,CAAC;EACtF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,UAAU,GAAGA,OAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACvD,IAAI,IAAI,CAAC,WAAW,GAAGA,OAAK,CAAC,kCAAkC,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;EAChG,IAAI,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;EACvF,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;EAC7F,IAAI,IAAI,CAAC,WAAW,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;EAChE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECpBM,MAAM,+BAA+B,SAAS,8BAA8B,CAAC;EACpF,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECjBM,MAAM,sCAAsC,SAAS,+BAA+B,CAAC;EAC5F,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;EChBM,MAAM,+BAA+B,SAAS,8BAA8B,CAAC;EACpF,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECjBM,MAAM,sCAAsC,SAAS,+BAA+B,CAAC;EAC5F,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;EChBM,MAAM,+BAA+B,SAAS,8BAA8B,CAAC;EACpF,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,uBAAuB,EAAE;EAC5D,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;EACnC,MAAM,OAAO;EACb,KAAK;EACL,IAAI,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,IAAI,CAAC;EACjC,IAAIA,OAAK,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7C,IAAI,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;EACzC,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;EAChD,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAClI,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;EAClD,GAAG;EACH,CAAC;;ECjBM,MAAM,sCAAsC,SAAS,+BAA+B,CAAC;EAC5F,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,WAAW,CAAC,KAAK,EAAE;EACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;EACzB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;EAClE,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,IAAI,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;EAC7B,GAAG;EACH,CAAC;;ECjBM,MAAM,6BAA6B,SAAS,4BAA4B,CAAC,EAAE;;ECA3E,MAAM,6BAA6B,SAAS,4BAA4B,CAAC,EAAE;;ECA3E,MAAM,6BAA6B,SAAS,4BAA4B,CAAC,EAAE;;ECC3E,MAAM,8BAA8B,SAAS,6BAA6B,CAAC;EAClF,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC3G,MAAM,CAAC,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EACtI,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECTM,MAAM,qCAAqC,SAAS,oCAAoC,CAAC;EAChG,EAAE,SAAS,GAAG;EACd,IAAI,MAAM,iBAAiB,GAAG,IAAI,CAAC,0BAA0B,EAAE,CAAC;EAChE,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAC3D,MAAM,CAAC,QAAQ,GAAG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;EACjE,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC;;ECgCM,MAAMO,iBAAe,GAAG;EAC/B,EAAE,QAAQ,EAAE;EACZ,IAAI,OAAO,EAAE;EACb,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,sBAAsB;EACrC,MAAM,OAAO,EAAE,qCAAqC;EACpD,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,OAAO,EAAE,qCAAqC;EACpD,MAAM,eAAe,EAAE,qCAAqC;EAC5D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,8BAA8B,EAAE,oDAAoD;EAC1F,MAAM,WAAW,EAAE,iCAAiC;EACpD,MAAM,gBAAgB,EAAE,sCAAsC;EAC9D,MAAM,WAAW,EAAE,iCAAiC;EACpD,KAAK;EACL,IAAI,MAAM,EAAE;EACZ,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,sBAAsB;EACrC,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,8BAA8B;EAC7C,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,UAAU,EAAE,KAAK;EACvB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,YAAY,EAAE,KAAK;EACzB,MAAM,OAAO,EAAE,8BAA8B;EAC7C,MAAM,eAAe,EAAE,8BAA8B;EACrD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,8BAA8B,EAAE,oDAAoD;EAC1F,MAAM,WAAW,EAAE,0BAA0B;EAC7C,MAAM,gBAAgB,EAAE,+BAA+B;EACvD,MAAM,WAAW,EAAE,0BAA0B;EAC7C,KAAK;EACL,GAAG;EACH,EAAE,MAAM,EAAE;EACV,IAAI,OAAO,EAAE;EACb,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,sBAAsB;EACrC,MAAM,OAAO,EAAE,mCAAmC;EAClD,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,YAAY,EAAE,sCAAsC;EAC1D,MAAM,OAAO,EAAE,mCAAmC;EAClD,MAAM,eAAe,EAAE,qCAAqC;EAC5D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,iBAAiB,EAAE,qCAAqC;EAC9D,MAAM,8BAA8B,EAAE,oDAAoD;EAC1F,MAAM,WAAW,EAAE,iCAAiC;EACpD,MAAM,gBAAgB,EAAE,sCAAsC;EAC9D,MAAM,WAAW,EAAE,iCAAiC;EACpD,KAAK;EACL,IAAI,MAAM,EAAE;EACZ,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,sBAAsB;EACrC,MAAM,SAAS,EAAE,wBAAwB;EACzC,MAAM,OAAO,EAAE,4BAA4B;EAC3C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,UAAU,EAAE,6BAA6B;EAC/C,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,YAAY,EAAE,+BAA+B;EACnD,MAAM,OAAO,EAAE,4BAA4B;EAC3C,MAAM,eAAe,EAAE,8BAA8B;EACrD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,iBAAiB,EAAE,8BAA8B;EACvD,MAAM,8BAA8B,EAAE,6CAA6C;EACnF,MAAM,WAAW,EAAE,0BAA0B;EAC7C,MAAM,gBAAgB,EAAE,+BAA+B;EACvD,MAAM,WAAW,EAAE,0BAA0B;EAC7C,KAAK;EACL,GAAG;EACH,CAAC,CAAC;AAEF,EAAO,SAASC,uBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;EACvE,EAAE,IAAI,CAAC,IAAI,EAAE;EACb,IAAI,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;EACpC,GAAG;EACH,EAAE,IAAI,CAAC,OAAO,EAAE;EAChB,IAAI,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;EACvC,GAAG;EACH,EAAE,IAAI,CAAC,SAAS,EAAE;EAClB,IAAI,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;EACzC,GAAG;EACH,EAAE,IAAI,KAAK,CAAC,IAAI,EAAE;EAClB,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;EACtB,GAAG;EACH,EAAE,MAAM,KAAK,GAAGD,iBAAe,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC;EACpD,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,EAAE;EAC7B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,SAAS,EAAE;EACxC,IAAI,MAAM,IAAI,KAAK,CAAC,CAAC,iCAAiC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;EAClE,GAAG;EACH,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;EACrB,CAAC;;EC/KD,IAAIE,aAAW,GAAG,IAAI,CAAC;EACvB,IAAIC,YAAU,GAAG,IAAI,CAAC;EACtB,IAAIC,aAAW,GAAG,IAAI,CAAC;EACvB,IAAIC,gBAAc,GAAG,IAAI,CAAC;EAM1B,IAAIC,UAAQ,GAAG,IAAI,CAAC;AAKpB,EAAO,MAAM,YAAY,SAAS,WAAW,CAAC;EAC9C,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,IAAIJ,aAAW,KAAK,IAAI,EAAE;EAC9B,MAAM,OAAOA,aAAW,CAAC;EACzB,KAAK;EACL,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;EAC9B,IAAIA,aAAW,GAAG,IAAI,CAAC,cAAc,CAACE,aAAW,CAAC,CAAC;EACnD,IAAI,OAAOF,aAAW,CAAC;EACvB,GAAG;EAEH,EAAE,OAAO,kBAAkB,GAAG;EAC9B,IAAI,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE;EACzC,MAAMC,YAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;EACpD,KAAK,MAAM,IAAI,OAAO,eAAe,KAAK,WAAW,EAAE;EACvD,MAAMA,YAAU,GAAG,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;EAC7C,KAAK;EACL,IAAI,IAAI,CAACA,YAAU,EAAE,OAAO;EAC5B,IAAIC,aAAW,GAAGD,YAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;EAClD,IAAI,IAAI,CAACC,aAAW,IAAI,CAACA,aAAW,CAAC,YAAY,EAAE,OAAO;EAC1D,IAAIC,gBAAc,GAAG;EACrB,MAAM,sBAAsB,EAAED,aAAW,CAAC,YAAY,CAAC,wBAAwB,CAAC;EAChF,MAAM,wBAAwB,EAAEA,aAAW,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACpF,KAAK,CAAC;EACN,IAAIE,UAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;EAClC,GAAG;EAEH,EAAE,OAAO,cAAc,CAAC,OAAO,EAAE;EAEjC,IAAI,IAAI,OAAO,sBAAsB,KAAK,WAAW,EAAE;EACvD,MAAM,OAAO,OAAO,YAAY,sBAAsB,CAAC;EACvD,KAAK;EACL,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAEH,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC;EACzB,MAAM,WAAW,EAAE,IAAI,CAAC,cAAc,EAAE;EACxC,MAAM,yBAAyB,EAAE,IAAI,CAAC,4BAA4B,EAAE;EACpE,MAAM,SAAS,EAAE,IAAI;EACrB,MAAM,cAAc,EAAE,IAAI;EAC1B,MAAM,YAAY,EAAE,IAAI,CAAC,eAAe,EAAE;EAC1C,MAAM,cAAc,EAAE,IAAI,CAAC,iBAAiB,EAAE;EAC9C,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,OAAO,iBAAiB,GAAG;EAC7B,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAEH,EAAE,OAAO,4BAA4B,GAAG;EACxC,IAAI,OAAO,KAAK,CAAC,4BAA4B,EAAE,CAAC;EAChD,GAAG;EAEH,EAAE,OAAO,eAAe,GAAG;EAC3B,IAAI,OAAOF,aAAW,CAAC,YAAY,CAACA,aAAW,CAAC,gBAAgB,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,OAAO,iBAAiB,GAAG;EAC7B,IAAI,OAAOA,aAAW,CAAC,YAAY,CAACA,aAAW,CAAC,gBAAgB,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,OAAO,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;EAChE,IAAI,OAAOH,uBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;EAClE,GAAG;EAEH,EAAE,WAAW,UAAU,GAAG;EAC1B,IAAI,OAAOE,YAAU,CAAC;EACtB,GAAG;EAEH,EAAE,WAAW,WAAW,GAAG;EAC3B,IAAI,OAAOC,aAAW,CAAC;EACvB,GAAG;EAMH,EAAE,WAAW,QAAQ,GAAG;EACxB,IAAI,OAAOE,UAAQ,CAAC;EACpB,GAAG;EAEH,EAAE,WAAW,cAAc,GAAG;EAC9B,IAAI,OAAOR,gBAAc,CAAC;EAC1B,GAAG;EACH,EAAE,WAAW,YAAY,GAAG;EAC5B,IAAI,OAAOC,cAAY,CAAC;EACxB,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,MAAM,QAAQ,GAAG;EACrB,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,KAAK,EAAE,KAAK;EAClB,MAAM,SAAS,EAAE,KAAK;EACtB,KAAK,CAAC;EACN,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;EAC/D,IAAI,OAAO,OAAO,CAAC;EACnB,GAAG;EAEH,EAAE,cAAc,GAAG;EACnB,IAAI,IAAI,CAAC,UAAU,GAAG;EACtB,MAAM,sBAAsB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,wBAAwB,CAAC;EACjF,MAAM,wBAAwB,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,0BAA0B,CAAC;EACrF,KAAK,CAAC;EACN,GAAG;EAMH,EAAE,gBAAgB,CAAC,IAAI,EAAE;EACzB,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE;EACxB,MAAM,IAAI,CAAC,OAAO,GAAGN,OAAK,CAAC,oBAAoB,CAAC;EAChD,QAAQ,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACrD,QAAQ,SAAS,EAAE,IAAI,CAAC,SAAS;EACjC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EACtB,MAAM,OAAO;EACb,KAAK;EAEL,IAAI,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;EAC/C,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;EAC9D,MAAM,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;EACjE,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE;EAC3D,MAAM,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;EACpE,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,0BAA0B,KAAK,IAAI,EAAE;EAClD,MAAM,IAAI,CAAC,0BAA0B,GAAG,CAAC,QAAQ,CAAC,yBAAyB,CAAC;EAC5E,KAAK,MAAM,IAAI,IAAI,CAAC,0BAA0B,IAAI,QAAQ,CAAC,yBAAyB,EAAE;EACtF,MAAM,IAAI,CAAC,0BAA0B,GAAG,KAAK,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;EAEvB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EAClD,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;EAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;EACtF,OAAO;EAEP,MAAM,MAAM,OAAO,GAAGA,OAAK,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;EAC1E,MAAM,QAAQ,OAAO;EACrB,QAAQ,KAAK,OAAO;EACpB,UAAU,IAAI,CAAC,MAAM,GAAGA,OAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;EACrD,UAAU,MAAM;EAChB,QAAQ,KAAK,eAAe,CAAC;EAC7B,QAAQ,KAAK,8BAA8B,CAAC;EAC5C,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB,CAAC;EAC/B,QAAQ,KAAK,iBAAiB;EAC9B,UAAU,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACvC,UAAU,MAAM;EAChB,QAAQ;EACR,UAAU,MAAM,IAAI,KAAK,CAAC,4CAA4C,GAAG,OAAO,CAAC,CAAC;EAClF,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;EACpC,QAAQ,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;EAC3E,OAAO;EAEP,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACvC,QAAQ,OAAO,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;EACxF,QAAQ,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC;EACpC,OAAO;EAEP,MAAM,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC9C,MAAM,OAAO;EACb,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,QAAQ,CAAC,cAAc,EAAE;EACtF,MAAM,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;EAChC,KAAK;EAEL,IAAI,IAAI,CAAC,OAAO,GAAGA,OAAK,CAAC,oBAAoB,CAAC;EAC9C,MAAM,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;EACnD,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;EAEpB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;EAC5B,GAAG;EAEH,EAAE,eAAe,GAAG;EACpB,IAAI,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,kBAAkB,EAAE;EACjF,MAAM,0BAA0B,EAAE,IAAI,CAAC,0BAA0B;EACjE,KAAK,CAAC,CAAC;EACP,IAAI,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;EACzE,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;EAC7C,MAAM,IAAI,CAAC,UAAU,GAAG,eAAe,CAAC,mBAAmB,EAAE,CAAC;EAC9D,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACvD,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACvD,QAAQ,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC7C,QAAQ,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;EACnC,UAAU,SAAS,CAAC,UAAU,GAAG,eAAe,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;EAC3E,SAAS;EACT,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,GAAG,GAAG;EACR,IAAI,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,0BAA0B,EAAE,GAAG,IAAI,CAAC;EAC1E,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAE5B,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAChC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAE7C,IAAI,IAAI,IAAI,CAAC,aAAa,EAAE;EAC5B,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;EACvE,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC9C,KAAK;EAEL,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;EAEjG,IAAI,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAClC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,0BAA0B,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAChE,MAAM,MAAM,QAAQ,GAAG,0BAA0B,CAAC,CAAC,CAAC,CAAC;EACrD,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;EAC1D,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO;EACxC,KAAK;EACL,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,eAAe,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EACnD,MAAM,IAAI,IAAI,CAAC,gBAAgB,EAAE,OAAO;EACxC,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EACvC,QAAQ,IAAI,MAAM,CAAC,WAAW,EAAE;EAChC,UAAU,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;EACnC,SAAS;EACT,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;EACnD,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EAC7D,QAAQ,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,SAAS,EAAE;EACnD,UAAU,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACrC,SAAS;EACT,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC/C,QAAQ,OAAO,IAAI,IAAI,CAAC,kBAAkB,CAAC;EAC3C,UAAU,OAAO,EAAE,IAAI,CAAC,aAAa;EACrC,UAAU,IAAI,EAAE,OAAO;EACvB,UAAU,UAAU,EAAE,IAAI,CAAC,SAAS;EACpC,UAAU,MAAM,EAAE,IAAI,CAAC,MAAM;EAC7B,UAAU,OAAO,EAAE,IAAI,CAAC,OAAO;EAC/B,SAAS,CAAC,CAAC;EACX,OAAO;EACP,MAAM,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;EACjD,MAAM,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;EAC/C,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC7C,MAAM,OAAO;EACb,KAAK;EAEL,IAAI,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;EACzD,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE;EACxB,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;EACjC,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE;EAClC,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE;EAC1B,QAAQ,IAAI,CAAC,uBAAuB,EAAE,CAAC;EACvC,OAAO;EACP,MAAM,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAC1C,KAAK;EAEL,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;EAC3C,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EAClD,GAAG;EAEH,EAAE,gBAAgB,GAAG;EACrB,IAAI,OAAO,IAAI,CAAC,aAAa,CAAC;EAC9B,GAAG;EAEH,EAAE,mBAAmB,GAAG;EACxB,IAAI,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;EAC7B,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAC5B,IAAI,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC;EAC5D,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,CAAC,CAAC;EAC1F,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC3C,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EACzE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACvE,IAAI,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACrC,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;EACzB,QAAQ,QAAQ,IAAI,CAAC,UAAU;EAC/B,UAAU,KAAK,QAAQ,CAAC;EACxB,UAAU,KAAK,OAAO,CAAC;EACvB,UAAU,KAAK,SAAS;EACxB,YAAY,IAAI,IAAI,CAAC,mBAAmB,EAAE;EAC1C,cAAc,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EACpF,aAAa,MAAM;EACnB,cAAc,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EACjF,aAAa;EACb,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAChF,YAAY,MAAM;EAClB,UAAU,KAAK,UAAU,CAAC;EAC1B,UAAU,KAAK,UAAU;EACzB,YAAY,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAClF,YAAY,MAAM;EAClB,UAAU;EACV,YAAY,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;EACrD,SAAS;EACT,OAAO,MAAM;EACb,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9E,OAAO;EACP,KAAK,MAAM;EACX,MAAM,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;EAC3G,KAAK;EACL,IAAI,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;EAC7F,GAAG;EAEH,EAAE,uBAAuB,GAAG;EAC5B,IAAI,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;EAC7B,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;EAC5B,IAAI,IAAI,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;EACjD,IAAI,IAAI,CAAC,uBAAuB,GAAG,EAAE,CAAC;EACtC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;EACnD,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EACjD,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;EAC7D,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,QAAQ,GAAG,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC,CAAC;EAChG,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;EAC7C,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EAC3E,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC;EAC3E,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EACzE,MAAM,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC;EAEzE,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE;EACvC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;EACxG,OAAO,MAAM;EACb,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;EAC7G,OAAO;EACP,MAAM,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,iBAAiB,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;EACvG,KAAK;EACL,GAAG;EASH,EAAE,gBAAgB,GAAG;EACrB,IAAI,OAAO,EAAE,CAAC;EACd,GAAG;EAMH,EAAE,qBAAqB,GAAG;EAC1B,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE;EACtD,MAAM,QAAQ,IAAI,CAAC,MAAM;EACzB,QAAQ,KAAK,OAAO;EACpB,UAAU,OAAO,2BAA2B,CAAC;EAC7C,QAAQ,KAAK,aAAa;EAC1B,UAAU,OAAO,4BAA4B,CAAC;EAC9C,QAAQ,KAAK,UAAU,CAAC;EACxB,QAAQ;EACR,UAAU,OAAO,8BAA8B,CAAC;EAChD,OAAO;EACP,KAAK,MAAM;EACX,MAAM,QAAQ,IAAI,CAAC,MAAM;EACzB,QAAQ,KAAK,OAAO;EACpB,UAAU,OAAO,4BAA4B,CAAC;EAC9C,QAAQ,KAAK,aAAa;EAC1B,UAAU,OAAO,6BAA6B,CAAC;EAC/C,QAAQ,KAAK,UAAU,CAAC;EACxB,QAAQ;EACR,UAAU,OAAO,+BAA+B,CAAC;EACjD,OAAO;EACP,KAAK;EACL,GAAG;EAOH,EAAE,uBAAuB,CAAC,IAAI,EAAE;EAChC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;EAC7C,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACnD,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;EAC9D,KAAK;EACL,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;EAC3B,GAAG;EAMH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,uBAAuB,CAAC;EAChC,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,UAAU;EACrB,QAAQ,uBAAuB,GAAG,mBAAmB,CAAC;EACtD,QAAQ,MAAM;EACd,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,OAAO,CAAC;EACnB,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS;EACpB,QAAQ,uBAAuB,GAAG,oBAAoB,CAAC;EACvD,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE;EAC5B,UAAU,uBAAuB,GAAG,oBAAoB,CAAC;EACzD,SAAS,MAAM;EACf,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,0BAA0B,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;EAC7E,SAAS;EACT,KAAK;EAEL,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;EACvC,IAAI,IAAI,UAAU,KAAK,IAAI,EAAE;EAC7B,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,uBAAuB;EAC/B,QAAQ,qCAAqC;EAC7C,OAAO,CAAC;EACR,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,QAAQ,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EACxC,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,SAAS,CAAC,UAAU,KAAK,SAAS;EAC5C,UAAU,CAAC,oBAAoB,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;EACvD,UAAU,CAAC,sBAAsB,GAAG,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC;EAC3D,UAAU,CAAC,kBAAkB,GAAG,CAAC,GAAG,CAAC,EAAE,eAAe,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;EACjE,SAAS,CAAC;EACV,OAAO;EACP,KAAK,MAAM;EACX,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,gBAAgB;EACxB,QAAQ,uBAAuB;EAC/B,OAAO,CAAC;EACR,KAAK;EAEL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC;EAC/D,GAAG;EAEH,EAAE,sBAAsB,GAAG;EAC3B,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,uBAAuB;EAC7B,KAAK,CAAC,CAAC;EACP,GAAG;EAEH,EAAE,yBAAyB,GAAG;EAC9B,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,gBAAgB,CAAC;EAC5B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,OAAO,IAAI,CAAC,+BAA+B,EAAE;EACrD,UAAU,IAAI,CAAC,kCAAkC,EAAE,CAAC;EACpD,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,yCAAyC,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;EAClG,KAAK;EACL,GAAG;EAKH,EAAE,+BAA+B,GAAG;EACpC,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC;EAC/B,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,cAAc,CAAC;EACxF,KAAK,CAAC,CAAC;EACP,GAAG;EAKH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;EACpC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,uBAAuB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;EACxI,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,GAAG,UAAU,CAAC,iBAAiB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;EACjI,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,kCAAkC,GAAG;EACvC,IAAI,MAAM,MAAM,GAAG;EACnB,MAAM,cAAc;EACpB,KAAK,CAAC;EAEN,IAAI,QAAQ,IAAI,CAAC,UAAU;EAC3B,MAAM,KAAK,QAAQ,CAAC;EACpB,MAAM,KAAK,SAAS,CAAC;EACrB,MAAM,KAAK,OAAO;EAClB,QAAQ,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;EAC9C,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAClD,UAAU,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;EACtC,UAAU,IAAI,CAAC,wCAAwC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;EACzE,UAAU,IAAI,CAAC,2CAA2C,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;EAC5E,UAAU,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE;EACvC,YAAY,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;EACxC,WAAW;EACX,SAAS;EACT,QAAQ,MAAM;EACd,MAAM;EACN,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,2CAA2C,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;EACnG,KAAK;EAEL,IAAI,OAAOA,OAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;EACvC,GAAG;EAEH,EAAE,wCAAwC,CAAC,MAAM,EAAE,OAAO,EAAE;EAC5D,IAAI,MAAM,CAAC,IAAI;EACf,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC;EACzC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,2CAA2C,CAAC,MAAM,EAAE,OAAO,EAAE;EAC/D,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,yBAAyB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;EAChF,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,mBAAmB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;EACzE,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,2BAA2B;EACjC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,EAAE;EAC9C,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,4BAA4B,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;EACxE,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,MAAM,CAAC,IAAI;EACnB,UAAU,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;EACjE,SAAS,CAAC;EACV,OAAO;EACP,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,8BAA8B;EACpC,MAAM,8BAA8B;EACpC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,8BAA8B;EACpC,MAAM,8BAA8B;EACpC,MAAM,8BAA8B;EACpC,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;EAC3C,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,sBAAsB,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;EAClE,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,gCAAgC,GAAG;EACrC,IAAI,OAAO;EACX,MAAM,2CAA2C;EACjD,MAAM,YAAY;EAClB,MAAM,wBAAwB;EAC9B,KAAK,CAAC;EACN,GAAG;EAEH,EAAE,mCAAmC,GAAG;EACxC,IAAI,MAAM,MAAM,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,CAAC;EACxC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;EACrD,MAAM,MAAM,CAAC,IAAI;EACjB,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;EACrE,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAEH,EAAE,iBAAiB,GAAG;EACtB,IAAI,IAAI,CAAC,UAAU,CAAC,sBAAsB,GAAG,IAAI,CAAC;EAClD,IAAI,IAAI,CAAC,UAAU,CAAC,wBAAwB,GAAG,IAAI,CAAC;EACpD,GAAG;EAEH,EAAE,MAAM,GAAG;EACX,IAAI,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;EAChC,IAAI,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,MAAM,EAAE,CAAC;EACvF,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EACH,CAAC;;ECjqBM,SAAS,iBAAiB,CAAC,MAAM,EAAE;EAC1C,EAAE,IAAI,GAAG,GAAG,WAAW;EACvB,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EAC1C,IAAI,IAAI,MAAM,CAAC,aAAa,EAAE;EAC9B,MAAM,GAAG,GAAG,WAAW;EACvB,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EAC5C,QAAQ,IAAI,MAAM,CAAC,gBAAgB,EAAE;EACrC,UAAU,MAAM,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAC1C,UAAU,OAAO,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EACjE,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC,aAAa,EAAE,CAAC;EACtC,OAAO,CAAC;EACR,KAAK,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE;EACpC,MAAM,GAAG,GAAG,WAAW;EACvB,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EAC5C,QAAQ,IAAI,MAAM,CAAC,gBAAgB,EAAE;EACrC,UAAU,MAAM,CAAC,gBAAgB,GAAG,KAAK,CAAC;EAC1C,UAAU,OAAO,MAAM,CAAC,qBAAqB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;EACjE,SAAS;EACT,QAAQ,OAAO,MAAM,CAAC,YAAY,EAAE,CAAC;EACrC,OAAO,CAAC;EACR,KAAK,MAAM;EACX,MAAM,GAAG,GAAG,WAAW;EACvB,QAAQ,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACnD,OAAO,CAAC;EACR,KAAK;EACL,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACxC,GAAG,CAAC;EACJ,EAAE,MAAM,QAAQ,GAAG,WAAW;EAC9B,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACxC,GAAG,CAAC;EAKJ,EAAE,QAAQ,CAAC,IAAI,GAAG,WAAW;EAC7B,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK;EAC3C,MAAM,IAAI;EACV,QAAQ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;EAC3C,OAAO,CAAC,OAAO,CAAC,EAAE;EAClB,QAAQ,MAAM,CAAC,CAAC,CAAC,CAAC;EAClB,OAAO;EACP,KAAK,CAAC,CAAC;EACP,GAAG,CAAC;EACJ,EAAE,QAAQ,CAAC,aAAa,GAAG,SAAS,iBAAiB,EAAE;EACvD,IAAI,MAAM,GAAG,iBAAiB,CAAC;EAC/B,IAAI,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EAC3C,IAAI,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;EAC7B,GAAG,CAAC;EAEJ,EAAE,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;EACzC,EAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;EAC3B,EAAE,OAAO,QAAQ,CAAC;EAClB,CAAC;EAED,SAAS,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChD,EAAE,MAAM,UAAU,GAAGA,OAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;EACnD,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC9C,IAAI,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;EACnC,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,SAAS;EAC7D,IAAI,IAAI,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,UAAU,EAAE;EAChD,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,EAAE;EACpF,QAAQ,QAAQ,CAAC,QAAQ,CAAC,GAAG,WAAW;EACxC,UAAU,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EACpD,UAAU,OAAO,QAAQ,CAAC;EAC1B,SAAS,CAAC;EACV,OAAO,MAAM;EACb,QAAQ,IAAI,QAAQ,KAAK,UAAU,EAAE;EACrC,UAAU,QAAQ,CAAC,QAAQ,GAAG,WAAW;EACzC,YAAY,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;EAC5D,WAAW,CAAC;EACZ,SAAS,MAAM;EACf,UAAU,QAAQ,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EAC7D,SAAS;EACT,OAAO;EACP,KAAK,MAAM;EACX,MAAM,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM;EAChD,QAAQ,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC;EAChC,OAAO,CAAC,CAAC;EACT,MAAM,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC,KAAK,KAAK;EACrD,QAAQ,MAAM,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;EACjC,OAAO,CAAC,CAAC;EACT,KAAK;EACL,GAAG;EACH,CAAC;;EC3ED,MAAM,WAAW,GAAG,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;EAKlD,MAAM,WAAW,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;EAErC,MAAM,eAAe,GAAG;EACxB,EAAE,QAAQ,EAAE,YAAY;EACxB,EAAE,OAAO,EAAE,WAAW;EACtB,CAAC,CAAC;EAEF,IAAI,QAAQ,GAAG,IAAI,CAAC;AAKpB,EAAO,MAAM,GAAG,CAAC;EACjB,EAAE,OAAO,iBAAiB,GAAG;EAC7B,IAAI,QAAQ,GAAG,KAAK,CAAC;EACrB,GAAG;EAEH,EAAE,OAAO,gBAAgB,GAAG;EAC5B,IAAI,QAAQ,GAAG,IAAI,CAAC;EACpB,GAAG;EAEH,EAAE,WAAW,cAAc,GAAG;EAC9B,IAAI,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC;EAC1D,GAAG;EAMH,EAAE,WAAW,oBAAoB,GAAG;EACpC,IAAI,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;EACvF,GAAG;EAKH,EAAE,WAAW,0BAA0B,GAAG;EAC1C,IAAI,OAAO,CAAC,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,eAAe,KAAK,WAAW,KAAK,OAAO,aAAa,KAAK,WAAW,CAAC;EAC7H,GAAG;EAKH,EAAE,WAAW,gBAAgB,GAAG;EAChC,IAAI,OAAO,WAAW,CAAC,WAAW,CAAC;EACnC,GAAG;EAKH,EAAE,WAAW,iBAAiB,GAAG;EACjC,IAAI,OAAO,YAAY,CAAC,WAAW,CAAC;EACpC,GAAG;EAKH,EAAE,WAAW,qBAAqB,GAAG;EACrC,IAAI,OAAO,KAAK,CAAC;EACjB,GAAG;EAMH,EAAE,WAAW,iBAAiB,GAAG;EACjC,IAAI,OAAO,OAAO,iBAAiB,KAAK,WAAW,CAAC;EACpD,GAAG;EAKH,EAAE,WAAW,4BAA4B,GAAG;EAC5C,IAAI,OAAO,YAAY,CAAC,WAAW,CAAC;EACpC,GAAG;EAMH,EAAE,WAAW,0BAA0B,GAAG;EAC1C,IAAI,OAAO,WAAW,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;EAC3H,GAAG;EAMH,EAAE,WAAW,CAAC,QAAQ,EAAE;EACxB,IAAI,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC;EAC1C,IAAI,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC;EAC5C,IAAI,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;EAC9B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;EACvB,IAAI,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;EACtB,IAAI,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;EACxB,IAAI,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;EAC9B,IAAI,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;EAC/B,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO;EACpC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;EAExB,IAAI,IAAI,QAAQ,CAAC,SAAS,EAAE;EAC5B,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC1D,QAAQ,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;EAChD,OAAO;EACP,KAAK;EAGL,IAAI,IAAI,QAAQ,CAAC,eAAe,EAAE;EAClC,MAAM,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,eAAe,EAAE;EAChD,QAAQ,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;EAC/D,OAAO;EACP,KAAK;EACL,GAAG;EAEH,EAAE,WAAW,GAAG;EAChB,IAAI,OAAO,QAAQ,CAAC;EACpB,GAAG;EAKH,EAAE,YAAY,GAAG;EACjB,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO;EAE5B,IAAI,IAAI,MAAM,GAAG,IAAI,CAAC;EAEtB,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE;EACtB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACnD,QAAQ,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;EAC9C,QAAQ,IAAI,cAAc,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE;EACzD,UAAU,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE;EAC3C,YAAY,MAAM,IAAI,KAAK,CAAC,CAAC,YAAY,EAAE,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;EAChF,WAAW;EACX,UAAU,MAAM,GAAG,cAAc,CAAC;EAClC,UAAU,MAAM;EAChB,SAAS;EACT,OAAO;EACP,MAAM,IAAI,MAAM,KAAK,IAAI,EAAE;EAC3B,QAAQ,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;EAC3C,OAAO;EACP,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE;EAC1B,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,eAAe,EAAE;EACxC,QAAQ,IAAI,CAAC,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;EACjE,UAAU,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;EAC9C,SAAS;EACT,OAAO,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;EACtC,QAAQ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACrD,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;EAC1C,YAAY,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;EACpC,YAAY,MAAM;EAClB,WAAW;EACX,SAAS;EACT,OAAO,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;EACtC,QAAQ,MAAM,GAAG,SAAS,CAAC;EAC3B,OAAO;EACP,MAAM,IAAI,CAAC,MAAM,EAAE;EACnB,QAAQ,MAAM,IAAI,KAAK,CAAC,CAAC,qBAAqB,EAAE,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;EACnF,OAAO;EACP,KAAK,MAAM;EACX,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACnD,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;EACxC,UAAU,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;EAClC,UAAU,MAAM;EAChB,SAAS;EACT,OAAO;EACP,MAAM,IAAI,CAAC,MAAM,EAAE;EACnB,QAAQ,MAAM,GAAG,SAAS,CAAC;EAC3B,OAAO;EACP,KAAK;EAEL,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;EACpB,MAAM,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;EAC9B,KAAK;EACL,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;EACzB,GAAG;EAQH,EAAE,YAAY,CAAC,MAAM,EAAE,QAAQ,EAAE;EACjC,IAAI,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;EACvC,MAAM,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;EAClD,KAAK;EACL,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;EACzF,MAAM,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;EACzD,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;EAC7B,MAAM,MAAM,SAAS,GAAGc,YAAO,CAAC,MAAM,EAAE,qCAAqC,CAAC,QAAQ,CAAC,CAAC,CAAC;EACzF,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EACnC,MAAM,OAAO,SAAS,CAAC;EACvB,KAAK;EAEL,IAAI,MAAM,GAAG,OAAO,MAAM,KAAK,UAAU,GAAG,MAAM,CAAC,QAAQ,EAAE,GAAG,MAAM,CAAC;EACvE,IAAI,MAAM,iBAAiB,GAAG,EAAE,CAAC;EACjC,IAAI,MAAM,YAAY,GAAG,qCAAqC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;EAE/E,IAAI,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,EAAE;EAChE,MAAM,YAAY,CAAC,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;EACjI,KAAK;EAEL,IAAI,SAAS,iBAAiB,CAAC,IAAI,EAAE;EACrC,MAAM,MAAM,cAAc,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE;EACnD,QAAQ,aAAa,EAAE,SAAS,CAAC,aAAa;EAC9C,QAAQ,aAAa,EAAE,SAAS,CAAC,aAAa;EAC9C,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;EACtD,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,aAAa,EAAE,SAAS,CAAC,aAAa;EAC9C,QAAQ,eAAe,EAAE,SAAS,CAAC,gBAAgB;EACnD,QAAQ,MAAM,EAAE,SAAS,CAAC,MAAM;EAChC,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,QAAQ,EAAE,SAAS,CAAC,QAAQ;EACpC,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,mBAAmB,EAAE,SAAS,CAAC,mBAAmB;EAC1D,QAAQ,0BAA0B,EAAE,SAAS,CAAC,0BAA0B;EACxE,QAAQ,SAAS,EAAE,SAAS,CAAC,SAAS;EACtC,QAAQ,eAAe,EAAE,SAAS,CAAC,eAAe;EAClD,QAAQ,cAAc,EAAE,SAAS,CAAC,cAAc;EAChD,QAAQ,UAAU,EAAE,SAAS,CAAC,UAAU;EACxC,QAAQ,cAAc,EAAE,SAAS,CAAC,cAAc;EAChD,QAAQ,KAAK,EAAE,SAAS,CAAC,KAAK;EAC9B,QAAQ,YAAY,EAAE,SAAS,CAAC,YAAY;EAC5C,OAAO,CAAC,CAAC;EACT,MAAM,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;EACvD,MAAM,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;EACpE,MAAM,SAAS,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;EAC9C,MAAM,OAAO,MAAM,CAAC;EACpB,KAAK;EAEL,IAAI,SAAS,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE;EACjD,MAAM,MAAM,aAAa,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;EACnD,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EAC5C,QAAQ,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;EAC5B,QAAQ,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;EAC7C,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE;EACtB,UAAU,aAAa,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;EACtC,SAAS,MAAM;EACf,UAAU,QAAQ,IAAI;EACtB,YAAY,KAAK,QAAQ,CAAC;EAC1B,YAAY,KAAK,SAAS,CAAC;EAC3B,YAAY,KAAK,OAAO,CAAC;EACzB,YAAY,KAAK,iBAAiB;EAClC,cAAc,aAAa,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;EACtD,cAAc,MAAM;EACpB,YAAY;EACZ,cAAc,aAAa,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;EACtC,WAAW;EACX,SAAS;EACT,OAAO;EACP,MAAM,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;EAChD,MAAM,MAAM,cAAc,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;EAC1D,MAAM,IAAI,cAAc,EAAE;EAC1B,QAAQ,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;EACvD,QAAQ,IAAI,cAAc,CAAC,aAAa,EAAE;EAC1C,UAAU,OAAO,cAAc,CAAC,aAAa,EAAE,CAAC;EAChD,SAAS,MAAM;EACf,UAAU,OAAO,cAAc,CAAC,YAAY,EAAE,CAAC;EAC/C,SAAS;EACT,OAAO;EAEP,MAAM,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,GAAG,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE;EACtF,QAAQ,aAAa;EACrB,QAAQ,aAAa,EAAE,MAAM,CAAC,aAAa;EAC3C,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;EACnD,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,aAAa,EAAE,MAAM,CAAC,aAAa;EAC3C,QAAQ,eAAe,EAAE,MAAM,CAAC,gBAAgB;EAChD,QAAQ,OAAO,EAAE,MAAM,CAAC,OAAO;EAC/B,QAAQ,MAAM,EAAE,MAAM,CAAC,MAAM;EAC7B,QAAQ,MAAM,EAAE,MAAM,CAAC,MAAM;EAC7B,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,QAAQ,EAAE,MAAM,CAAC,QAAQ;EACjC,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;EACvD,QAAQ,0BAA0B,EAAE,MAAM,CAAC,0BAA0B;EACrE,QAAQ,SAAS,EAAE,MAAM,CAAC,SAAS;EACnC,QAAQ,eAAe,EAAE,MAAM,CAAC,eAAe;EAC/C,QAAQ,cAAc,EAAE,MAAM,CAAC,cAAc;EAC7C,QAAQ,UAAU,EAAE,MAAM,CAAC,UAAU;EACrC,QAAQ,cAAc,EAAE,MAAM,CAAC,cAAc;EAC7C,QAAQ,KAAK,EAAE,MAAM,CAAC,KAAK;EAC3B,QAAQ,GAAG,EAAE,MAAM,CAAC,GAAG;EACvB,QAAQ,QAAQ;EAChB,QAAQ,YAAY,EAAE,MAAM,CAAC,YAAY;EACzC,QAAQ,UAAU,EAAE,MAAM,CAAC,UAAU;EACrC,QAAQ,iBAAiB;EACzB,QAAQ,qBAAqB;EAC7B,OAAO,CAAC,CAAC;EACT,MAAM,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;EAC7C,MAAM,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;EAC3C,MAAM,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;EACzC,MAAM,IAAI,SAAS,CAAC,aAAa,EAAE;EACnC,QAAQ,OAAO,SAAS,CAAC,aAAa,EAAE,CAAC;EACzC,OAAO,MAAM;EACb,QAAQ,OAAO,SAAS,CAAC,YAAY,EAAE,CAAC;EACxC,OAAO;EACP,KAAK;EACL,IAAI,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;EACzC,MAAM,OAAO,EAAE,IAAI,CAAC,OAAO;EAC3B,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM;EACzB,MAAM,SAAS,EAAE,IAAI,CAAC,SAAS;EAC/B,MAAM,eAAe,EAAE,IAAI,CAAC,eAAe;EAC3C,MAAM,cAAc,EAAE,IAAI,CAAC,cAAc;EACzC,MAAM,GAAG,EAAE,IAAI;EACf,MAAM,QAAQ;EACd,MAAM,iBAAiB;EACvB,MAAM,qBAAqB;EAC3B,KAAK,EAAE,YAAY,CAAC,CAAC;EAErB,IAAI,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;EAGjF,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;EACtB,MAAM,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;EACrC,KAAK;EAGL,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;EACvB,MAAM,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;EACvC,KAAK;EAEL,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;EAEjC,IAAI,OAAO,SAAS,CAAC;EACrB,GAAG;EAgCH,EAAE,eAAe,GAAG;EACpB,IAAI,IAAI,EAAE,CAAC;EACX,IAAI,IAAI,QAAQ,CAAC;EACjB,IAAI,IAAI,OAAO,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,UAAU,EAAE;EAC/D,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EAC3C,MAAM,QAAQ,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EACjD,KAAK,MAAM;EACX,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EAC3C,KAAK;EAEL,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE;EAC7B,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE;EACvE,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;EAC7D,UAAU,MAAM,IAAI,KAAK,CAAC,CAAC,2BAA2B,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;EAC5E,SAAS;EACT,OAAO;EACP,KAAK;EAEL,IAAI,MAAM,YAAY,GAAG,qCAAqC,CAAC,QAAQ,CAAC,CAAC;EAEzE,IAAI,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,aAAa,KAAK,QAAQ,EAAE;EAChE,MAAM,YAAY,CAAC,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAC;EACjI,KAAK;EAEL,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;EACrC,MAAM,YAAY,CAAC,UAAU,GAAG,EAAE,CAAC;EACnC,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;EACrC,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACjD,QAAQ,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;EAC/C,QAAQ,MAAM,IAAI,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;EACvD,QAAQ,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;EACrC,UAAU,IAAI;EACd,UAAU,MAAM;EAChB,UAAU,QAAQ,EAAE,CAAC;EACrB,SAAS,CAAC,CAAC;EACX,OAAO;EACP,KAAK,MAAM;EACX,MAAM,YAAY,CAAC,UAAU,GAAG,EAAE,CAAC;EACnC,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;EACrC,MAAM,KAAK,IAAI,CAAC,IAAI,SAAS,EAAE;EAC/B,QAAQ,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS;EACnD,QAAQ,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;EAC/C,QAAQ,MAAM,IAAI,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAC;EACvD,QAAQ,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;EACrC,UAAU,IAAI,EAAE,IAAI,IAAI,CAAC;EACzB,UAAU,MAAM;EAChB,UAAU,QAAQ,EAAE,CAAC;EACrB,SAAS,CAAC,CAAC;EACX,OAAO;EACP,KAAK;EACL,IAAI,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;EAEvD,IAAI,OAAO,MAAM,CAAC;EAClB,GAAG;EAuBH,EAAE,cAAc,GAAG;EACnB,IAAI,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;EACrC,IAAI,MAAM,cAAc,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;EAC3D,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,KAAK,KAAK,EAAE,OAAO,cAAc,CAAC;EAC7E,IAAI,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;EACvC,IAAI,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;EACzC,IAAI,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;EACrC,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE;EAClC,MAAM,SAAS,CAAC,CAAC,CAAC;EAClB,SAAS,SAAS,CAAC,MAAM,CAAC;EAC1B,SAAS,UAAU,CAAC,OAAO,CAAC;EAC5B,SAAS,WAAW,CAAC,IAAI,CAAC,CAAC;EAC3B,KAAK;EAEL,IAAI,OAAO,WAAW;EACtB,MAAM,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;EAC5D,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE;EAC3B,QAAQ,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;EACjC,OAAO;EACP,MAAM,OAAO,OAAO,CAAC;EACrB,KAAK,CAAC;EACN,GAAG;EAQH,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE;EAChC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;EAC/D,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EASH,EAAE,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE;EAC5C,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;EACjC,MAAM,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;EAChG,KAAK;EACL,IAAI,QAAQ,GAAG,QAAQ,IAAI,EAAE,CAAC;EAC9B,IAAI,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;EAC/F,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;EAC9B,MAAM,IAAI;EACV,MAAM,MAAM;EACZ,MAAM,QAAQ;EACd,MAAM,aAAa;EACnB,MAAM,aAAa;EACnB,MAAM,UAAU,EAAE,QAAQ,CAAC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,MAAM,CAAC;EACrF,KAAK,CAAC,CAAC;EACP,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAOH,EAAE,YAAY,CAAC,MAAM,EAAE;EACvB,IAAI,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;EACjC,IAAI,OAAO,IAAI,CAAC;EAChB,GAAG;EAKH,EAAE,OAAO,GAAG;EACZ,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO;EAG9B,IAAI,UAAU,CAAC,MAAM;EACrB,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;EACpD,QAAQ,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;EACtC,OAAO;EAEP,MAAM,IAAI,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;EACxC,MAAM,IAAI,WAAW,EAAE;EAEvB,QAAQ,IAAI,WAAW,CAAC,MAAM,EAAE;EAChC,UAAU,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC;EAC3C,SAAS;EACT,QAAQ,IAAI,WAAW,CAAC,WAAW,CAAC,cAAc,EAAE;EACpD,UAAU,WAAW,CAAC,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;EAC/D,SAAS;EACT,OAAO;EACP,KAAK,EAAE,CAAC,CAAC,CAAC;EACV,GAAG;EACH,CAAC;EAED,SAAS,qCAAqC,CAAC,QAAQ,EAAE;EACzD,EAAE,IAAI,CAAC,QAAQ,EAAE;EACjB,IAAI,OAAO,EAAE,CAAC;EACd,GAAG;EACH,EAAE,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;EAEvD,EAAE,IAAI,QAAQ,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE;EAC9C,IAAI,cAAc,CAAC,SAAS,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC;EAC1D,IAAI,gBAAgB,CAAC,SAAS,GAAG,QAAQ,CAAC,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;EAC9E,GAAG;EACH,EAAE,IAAI,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE;EAClD,IAAI,cAAc,CAAC,SAAS,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC;EAC7D,IAAI,gBAAgB,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;EAClE,GAAG;EACH,EAAE,IAAI,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE;EAClD,IAAI,cAAc,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,CAAC,CAAC;EAC9D,IAAI,gBAAgB,CAAC,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;EACnE,GAAG;EACH,EAAE,IAAI,QAAQ,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE;EAChD,IAAI,cAAc,CAAC,SAAS,EAAE,eAAe,EAAE,qBAAqB,CAAC,CAAC;EACtE,IAAI,gBAAgB,CAAC,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;EAC3E,GAAG;EACH,EAAE,OAAO,gBAAgB,CAAC;EAC1B,CAAC;;ECzjBM,SAAS,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE;EACpC,EAAE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;EACrC,EAAE,OAAO,IAAI,QAAQ,CAAC,CAAC,gBAAgB,GAAG,IAAI,EAAE,EAAE,GAAGd,OAAK,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;EAC1G,GAAGA,OAAK,CAAC,yBAAyB,CAAC,QAAQ,CAAC,EAAE;CAC/C,CAAC,CAAC,EAAE,CAAC;EACN,CAAC;;ECQD,MAAM,gBAAgB,SAAS,WAAW,CAAC;EAC3C,EAAE,WAAW,WAAW,GAAG,EAAE,OAAO,KAAK,EAAE;EAC3C,EAAE,OAAO,cAAc,GAAG,EAAE,OAAO,KAAK,EAAE;EAC1C,EAAE,OAAO,iBAAiB,GAAG,EAAE,OAAO,KAAK,EAAE;EAC7C,EAAE,OAAO,gBAAgB,GAAG,EAAE,OAAO,KAAK,EAAE;EAC5C,EAAE,OAAO,eAAe,GAAG,EAAE,OAAO,CAAC,EAAE;EACvC,EAAE,WAAW,UAAU,GAAG,EAAE,OAAO,IAAI,EAAE;EACzC,EAAE,WAAW,WAAW,GAAG,EAAE,OAAO,IAAI,EAAE;EAC1C,EAAE,WAAW,QAAQ,GAAG,EAAE,OAAO,IAAI,EAAE;EACvC,EAAE,OAAO,kBAAkB,GAAG,EAAE;EAChC,EAAE,OAAO,cAAc,GAAG,EAAE;EAC5B,EAAE,UAAU,GAAG,EAAE,OAAO,EAAE,EAAE;EAC5B,EAAE,WAAW,GAAG,EAAE,OAAO,IAAI,EAAE;EAC/B,EAAE,QAAQ,GAAG,EAAE,OAAO,EAAE,EAAE;EAC1B,EAAE,cAAc,GAAG,EAAE;EACrB,EAAE,KAAK,GAAG,EAAE;EACZ,EAAE,iBAAiB,GAAG,EAAE;EACxB,EAAE,SAAS,GAAG,EAAE;EAEhB,EAAE,OAAO,WAAW,GAAG;EACvB,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC;EACzB,MAAM,WAAW,EAAE,KAAK;EACxB,MAAM,yBAAyB,EAAE,KAAK;EACtC,MAAM,cAAc,EAAE,KAAK;EAC3B,MAAM,aAAa,EAAE,KAAK;EAC1B,MAAM,SAAS,EAAE,KAAK;EACtB,MAAM,YAAY,EAAE,CAAC;EACrB,KAAK,CAAC,CAAC;EACP,GAAG;EACH,CAAC,AAED,MAAM,GAAG,GAAG,GAAG,CAAC;EAChB,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;EAClB,GAAG,CAAC,eAAe,GAAG,eAAe,CAAC;EACtC,GAAG,CAAC,SAAS,GAAG,SAAS,CAAC;EAC1B,GAAG,CAAC,eAAe,GAAG,eAAe,CAAC;EACtC,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;EAChC,GAAG,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;EACxC,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;EAClB,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;EAClB,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;EACtB,GAAG,CAAC,KAAK,GAAG,EAAE,GAAG,MAAM,EAAE,GAAGA,OAAK,EAAE,CAAC;EACpC,GAAG,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;EAC5C,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;EAChC,GAAG,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;EAC1C,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;EAC9B,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;EACxB,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;;;;;;;;"} \ No newline at end of file diff --git a/dist/gpu-browser-core.min.js b/dist/gpu-browser-core.min.js index 1d3c6b6c..7cd8db25 100644 --- a/dist/gpu-browser-core.min.js +++ b/dist/gpu-browser-core.min.js @@ -1,14 +1,2 @@ -/** - * gpu.js - * http://gpu.rocks/ - * - * GPU Accelerated JavaScript - * - * @version 2.0.5 - * @date Fri Oct 11 2019 07:23:36 GMT-0400 (Eastern Daylight Time) - * - * @license MIT - * The MIT License - * - * Copyright (c) 2019 gpu.js Team - */!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).GPU=e()}}(function(){return function(){return function e(t,n,r){function i(a,o){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!o&&u)return u(a,!0);if(s)return s(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[a]={exports:{}};t[a][0].call(c.exports,function(e){return i(t[a][1][e]||e)},c,c.exports,e,t,n,r)}return n[a].exports}for(var s="function"==typeof require&&require,a=0;a0;)l.pop()}function A(e,t){c[e]=t}function S(e){const t=m[e];return t?n+"."+t:e}function E(e){y=" ".repeat(e)}function _(e,t){const r=`${n}Variable${g.length}`;return l.push(`${y}const ${r} = ${t};`),g.push(e),r}function v(e){l.push(`${y}// ${e}`)}function D(){l.push(`${y}(() => {\n${y}const error = ${n}.getError();\n${y}if (error !== ${n}.NONE) {\n${y} const names = Object.getOwnPropertyNames(gl);\n${y} for (let i = 0; i < names.length; i++) {\n${y} const name = names[i];\n${y} if (${n}[name] === error) {\n${y} throw new Error('${n} threw ' + name);\n${y} }\n${y} }\n${y}}\n${y}})();`)}function w(e,t){return`${n}.${e}(${s(t,{contextName:n,contextVariables:g,getEntity:S,addVariable:_,variables:c,onUnrecognizedArgumentLookup:p})})`}function $(e){const t=g.indexOf(e);return-1!==t?`${n}Variable${t}`:null}}function i(e,t){const n=new Proxy(e,{get:function(t,n){if("function"==typeof t[n])return function(){switch(n){case"drawBuffersWEBGL":return c.push(`${p}${i}.drawBuffersWEBGL([${s(arguments[0],{contextName:i,contextVariables:o,getEntity:g,addVariable:x,variables:h,onUnrecognizedArgumentLookup:d})}]);`),e.drawBuffersWEBGL(arguments[0])}let t=e[n].apply(e,arguments);switch(typeof t){case"undefined":return void c.push(`${p}${m(n,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(a(t))?(c.push(`${p}const ${i}Variable${o.length} = ${m(n,arguments)};`),o.push(t=a(t))):(c.push(`${p}const ${i}Variable${o.length} = ${m(n,arguments)};`),o.push(t));break;default:null===t?c.push(`${m(n,arguments)};`):c.push(`${p}const ${i}Variable${o.length} = ${m(n,arguments)};`),o.push(t)}return t};return r[e[n]]=n,e[n]}}),r={},{contextName:i,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:c,variables:h,indent:p,onUnrecognizedArgumentLookup:d}=t;return n;function g(e){return r.hasOwnProperty(e)?`${i}.${r[e]}`:u(e)}function m(e,t){return`${i}.${e}(${s(t,{contextName:i,contextVariables:o,getEntity:g,addVariable:x,variables:h,onUnrecognizedArgumentLookup:d})})`}function x(e,t){const n=`${i}Variable${o.length}`;return o.push(e),c.push(`${p}const ${n} = ${t};`),n}}function s(e,t){const{variables:n,onUnrecognizedArgumentLookup:r}=t;return Array.from(e).map(e=>{const i=function(e){if(n)for(const t in n)if(n.hasOwnProperty(t)&&n[t]===e)return t;if(r)return r(e);return null}(e);return i||function(e,t){const{contextName:n,contextVariables:r,getEntity:i,addVariable:s,onUnrecognizedArgumentLookup:a}=t;if(void 0===e)return"undefined";if(null===e)return"null";const o=r.indexOf(e);if(o>-1)return`${n}Variable${o}`;switch(e.constructor.name){case"String":const t=/\n/.test(e),n=/'/.test(e),r=/"/.test(e);return t?"`"+e+"`":n&&!r?'"'+e+'"':"'"+e+"'";case"Number":case"Boolean":return i(e);case"Array":return s(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return s(e,`new ${e.constructor.name}(${JSON.stringify(Array.from(e))})`);default:if(a){const t=a(e);if(t)return t}throw new Error(`unrecognized argument type ${e.constructor.name}`)}}(e,t)}).join(", ")}function a(e){return new e.constructor(e)}void 0!==t&&(t.exports={glWiretap:r,glExtensionWiretap:i}),"undefined"!=typeof window&&(r.glExtensionWiretap=i,window.glWiretap=r)},{}],3:[function(e,t,n){function r(e){const t=new Array(e.length);for(let n=0;n{e.output=a(t),e.graphical&&s(e)}),e.toJSON=(()=>{throw new Error("Not usable with gpuMock")}),e.setConstants=(t=>(e.constants=t,e)),e.setGraphical=(t=>(e.graphical=t,e)),e.setCanvas=(t=>(e.canvas=t,e)),e.setContext=(t=>(e.context=t,e)),e.exec=function(){return new Promise((t,n)=>{try{t(e.apply(e,arguments))}catch(e){n(e)}})},e.getPixels=(t=>{const{x:n,y:r}=e.output;return t?function(e,t,n){const r=n/2|0,i=4*t,s=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee),e.setOptimizeFloatMemory=(()=>e),e.setArgumentTypes=(()=>e),e.setDebug=(()=>e),e.setLoopMaxIterations=(()=>e),e.setPipeline=(()=>e),e.setPrecision=(()=>e),e.setImmutable=(()=>e),e.setFunctions=(()=>e),e.addSubKernel=(()=>e),e.destroy=(()=>{}),e.validateSettings=(()=>{}),e.graphical&&e.output&&s(e),e}function s(e){const{x:t,y:n}=e.output;if(e.context&&e.context.createImageData){const r=new Uint8ClampedArray(t*n*4);e._imageData=e.context.createImageData(t,n),e._colorData=r}else{const r=new Uint8ClampedArray(t*n*4);e._imageData={data:r},e._colorData=r}}function a(e){let t=null;if(e.length)if(3===e.length){const[n,r,i]=e;t={x:n,y:r,z:i}}else if(2===e.length){const[n,r]=e;t={x:n,y:r}}else{const[n]=e;t={x:n}}else t=e;return t}t.exports={gpuMock:function(e,t={}){const n=t.output?a(t.output):null;function s(){return s.output.z?function(){const e=r(arguments),t=new Array(this.output.z);for(let n=0;n0&&t.push(", "),t.push("user_"),t.push(n)}t.push(") {\n")}for(let n=0;n0&&t.push(n.join(""),";\n"),t.push(`for (let ${e}=0;${e}0&&t.push(`if (!${r.join("")}) break;\n`),t.push(s.join("")),t.push(`\n${i.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),t.push("if ("),this.astGeneric(e.test,t),t.push(") {\n"),this.astGeneric(e.body,t),t.push("} else {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astDoWhileStatement(e,t){if("DoWhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),this.astGeneric(e.body,t),t.push("if (!"),this.astGeneric(e.test,t),t.push(") {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astAssignmentExpression(e,t){const n=this.getDeclaration(e.left);if(n&&!n.assignable)throw this.astErrorOutput(`Variable ${e.left.name} is not assignable here`,e);return this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let n=0;n0&&t.push(","),this.astGeneric(n[e],t);return this.isState("in-for-loop-init")||t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){const{discriminant:n,cases:r}=e;t.push("switch ("),this.astGeneric(n,t),t.push(") {\n");for(let e=0;e0&&(this.astGeneric(r[e].consequent,t),t.push("break;\n"))):(t.push("default:\n"),this.astGeneric(r[e].consequent,t),r[e].consequent&&r[e].consequent.length>0&&t.push("break;\n"));t.push("\n}")}astThisExpression(e,t){return t.push("_this"),t}astMemberExpression(e,t){const{signature:n,type:r,property:i,xProperty:s,yProperty:a,zProperty:o,name:u,origin:l}=this.getMemberExpressionDetails(e);switch(n){case"this.thread.value":return t.push(`_this.thread.${u}`),t;case"this.output.value":switch(u){case"x":t.push("outputX");break;case"y":t.push("outputY");break;case"z":t.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value.value":if("Math"===l)return t.push(Math[u]),t;switch(i){case"r":return t.push(`user_${u}[0]`),t;case"g":return t.push(`user_${u}[1]`),t;case"b":return t.push(`user_${u}[2]`),t;case"a":return t.push(`user_${u}[3]`),t}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":return this.astGeneric(e.object,t),t.push("["),this.astGeneric(e.property,t),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!e.computed)switch(r){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${l}_${u}`),t}const c=`${l}_${u}`;switch(r){case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLImageArray":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"HTMLImage":default:let e,n;if("constants"===l){const t=this.constants[u];e=(n="Input"===this.constantTypes[u])?t.size:null}else e=(n=this.isInput(u))?this.argumentSizes[this.argumentNames.indexOf(u)]:null;t.push(`${c}`),o&&a?n?(t.push("[("),this.astGeneric(o,t),t.push(`*${this.dynamicArguments?"(outputY * outputX)":e[1]*e[0]})+(`),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):a?n?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):void 0!==s&&(t.push("["),this.astGeneric(s,t),t.push("]"))}return t}astCallExpression(e,t){if("CallExpression"!==e.type)throw this.astErrorOutput("Unknown CallExpression",e);let n=this.astMemberExpressionUnroll(e.callee);this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),this.isAstMathFunction(e),this.onFunctionCall&&this.onFunctionCall(this.name,n,e.arguments),t.push(n),t.push("(");const r=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", "),this.astGeneric(s,t)}return t.push(")"),t}astArrayExpression(e,t){const n=e.elements.length;t.push("new Float32Array([");for(let r=0;r0&&t.push(", ");const n=e.elements[r];this.astGeneric(n,t)}return t.push("])"),t}astDebuggerStatement(e,t){return t.push("debugger;"),t}}}},{"../function-node":9}],6:[function(e,t,n){const{utils:r}=e("../../utils");t.exports={cpuKernelString:function(e,t){const n=[],i=[],s=[],a=!/^function/.test(e.color.toString());if(n.push(" const { context, canvas, constants: incomingConstants } = settings;",` const output = new Int32Array(${JSON.stringify(Array.from(e.output))});`,` const _constantTypes = ${JSON.stringify(e.constantTypes)};`,` const _constants = ${function(e,t){const n=[];for(const r in t){if(!t.hasOwnProperty(r))continue;const i=t[r],s=e[r];switch(i){case"Number":case"Integer":case"Float":case"Boolean":n.push(`${r}:${s}`);break;case"Array(2)":case"Array(3)":case"Array(4)":n.push(`${r}:new ${s.constructor.name}(${JSON.stringify(Array.from(s))})`)}}return`{ ${n.join()} }`}(e.constants,e.constantTypes)};`),i.push(" constants: _constants,"," context,"," output,"," thread: {x: 0, y: 0, z: 0},"),e.graphical){n.push(` const _imageData = context.createImageData(${e.output[0]}, ${e.output[1]});`),n.push(` const _colorData = new Uint8ClampedArray(${e.output[0]} * ${e.output[1]} * 4);`);const t=r.flattenFunctionToString((a?"function ":"")+e.color.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),o=r.flattenFunctionToString((a?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});i.push(" _imageData,"," _colorData,",` color: ${t},`),s.push(` kernel.getPixels = ${o};`)}const o=[],u=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(a?"function ":"")+e[n].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});s.push(t),i.push(" _mediaTo2DArray,"),i.push(" _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==o.indexOf("HTMLImage")){const t=r.flattenFunctionToString((a?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});s.push(t),i.push(" _mediaTo2DArray,")}return`function(settings) {\n${n.join("\n")}\n for (const p in _constantTypes) {\n if (!_constantTypes.hasOwnProperty(p)) continue;\n const type = _constantTypes[p];\n switch (type) {\n case 'Number':\n case 'Integer':\n case 'Float':\n case 'Boolean':\n case 'Array(2)':\n case 'Array(3)':\n case 'Array(4)':\n if (incomingConstants.hasOwnProperty(p)) {\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\n }\n continue;\n }\n if (!incomingConstants.hasOwnProperty(p)) {\n throw new Error('constant ' + p + ' not found');\n }\n _constants[p] = incomingConstants[p];\n }\n const kernel = (function() {\n${e._kernelString}\n })\n .apply({ ${i.join("\n")} });\n ${s.join("\n")}\n return kernel;\n}`}}},{"../../utils":111}],7:[function(e,t,n){const{Kernel:r}=e("../kernel"),{FunctionBuilder:i}=e("../function-builder"),{CPUFunctionNode:s}=e("./function-node"),{utils:a}=e("../../utils"),{cpuKernelString:o}=e("./kernel-string");t.exports={CPUKernel:class extends r{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:!0,isIntegerDivisionAccurate:!0})}static get isSupported(){return!0}static isContextMatch(e){return!1}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){return null}static combineKernels(e){return e}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,this.thread={x:0,y:0,z:0},this.translatedSources=null}initCanvas(){return"undefined"!=typeof document?document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(0,0):void 0}initContext(){return this.canvas?this.canvas.getContext("2d"):null}initPlugins(e){return[]}validateSettings(e){if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=a.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical&&2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");this.checkOutput()}translateSource(){if(this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ",this.subKernels){const e=[];for(let t=0;t1?`resultX_${n}[x] = subKernelResult_${n};\n`:`result_${n}[x] = subKernelResult_${n};\n`)}this.followingReturnStatement=e.join("")}const e=i.fromKernel(this,s);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.setupConstants(),this.setupArguments(arguments),this.validateSettings(arguments),this.translateSource(),this.graphical){const{canvas:e,output:t}=this;if(!e)throw new Error("no canvas available for using graphical output");const n=t[0],r=t[1]||1;e.width=n,e.height=r,this._imageData=this.context.createImageData(n,r),this._colorData=new Uint8ClampedArray(n*r*4)}const e=this.getKernelString();this.kernelString=e,this.debug&&(console.log("Function output:"),console.log(e));try{this.run=new Function([],e).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}}color(e,t,n,r){void 0===r&&(r=1),e=Math.floor(255*e),t=Math.floor(255*t),n=Math.floor(255*n),r=Math.floor(255*r);const i=this.output[0],s=this.output[1],a=this.thread.x+(s-this.thread.y-1)*i;this._colorData[4*a+0]=e,this._colorData[4*a+1]=t,this._colorData[4*a+2]=n,this._colorData[4*a+3]=r}getKernelString(){if(null!==this._kernelString)return this._kernelString;let e=null,{translatedSources:t}=this;return t.length>1?t=t.filter(t=>/^function/.test(t)?t:(e=t,!1)):e=t.shift(),this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()};\n ${this.injectedNative||""}\n const _this = this;\n ${this._processConstants()}\n return (${this.argumentNames.map(e=>"user_"+e).join(", ")}) => {\n ${this._processArguments()}\n ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n ${t.length>0?t.join("\n"):""}\n };`}toString(){return o(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const e=[];for(let t in this.constants)switch(this.constantTypes[t]){case"HTMLImage":case"HTMLVideo":e.push(` const constants_${t} = this._mediaTo2DArray(this.constants.${t});\n`);break;case"HTMLImageArray":e.push(` const constants_${t} = this._imageTo3DArray(this.constants.${t});\n`);break;case"Input":e.push(` const constants_${t} = this.constants.${t}.value;\n`);break;default:e.push(` const constants_${t} = this.constants.${t};\n`)}return e.join("")}_processArguments(){const e=[];for(let t=0;t0?e.width:e.videoWidth,r=e.height>0?e.height:e.videoHeight;t.width=0;e--){const t=a[e]=new Array(n);for(let e=0;e`const result_${e.name} = new ${n}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_resultKernel2DLoop(e){const{output:t}=this,n=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y] = new ${n}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${n}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_graphicalKernel2DLoop(e){const{output:t}=this,n=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${n}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_resultKernel3DLoop(e){const{output:t}=this,n=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y] = new ${n}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${n}(outputX);\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_kernelOutput(){return this.subKernels?`\n return {\n result: result,\n ${this.subKernels.map(e=>`${e.property}: result_${e.name}`).join(",\n ")}\n };`:"\n return result;"}_mapSubKernels(e){return null===this.subKernels?[""]:this.subKernels.map(e)}destroy(e){e&&delete this.canvas}static destroyContext(e){}toJSON(){const e=super.toJSON();return e.functionNodes=i.fromKernel(this,s).toJSON(),e}setOutput(e){super.setOutput(e);const[t,n]=this.output;this.graphical&&(this._imageData=this.context.createImageData(t,n),this._colorData=new Uint8ClampedArray(t*n*4))}}}},{"../../utils":111,"../function-builder":8,"../kernel":34,"./function-node":5,"./kernel-string":6}],8:[function(e,t,n){class r{static fromKernel(e,t,n){const{kernelArguments:i,kernelConstants:s,argumentNames:a,argumentSizes:o,argumentBitRatios:u,constants:l,constantBitRatios:c,debug:h,loopMaxIterations:p,nativeFunctions:d,output:g,optimizeFloatMemory:m,precision:x,plugins:f,source:y,subKernels:T,functions:b,leadingReturnStatement:A,followingReturnStatement:S,dynamicArguments:E,dynamicOutput:_,warnVarUsage:v}=e,D=new Array(i.length),w={};for(let e=0;eP.needsArgumentType(e,t),I=(e,t,n)=>{P.assignArgumentType(e,t,n)},R=(e,t,n)=>P.lookupReturnType(e,t,n),F=e=>P.lookupFunctionArgumentTypes(e),k=(e,t)=>P.lookupFunctionArgumentName(e,t),L=(e,t)=>P.lookupFunctionArgumentBitRatio(e,t),z=(e,t,n,r)=>{P.assignArgumentType(e,t,n,r)},O=(e,t,n,r)=>{P.assignArgumentBitRatio(e,t,n,r)},V=(e,t,n)=>{P.trackFunctionCall(e,t,n)},M=(e,n)=>{const r=[];for(let t=0;tnew t(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:g,plugins:f,constants:l,constantTypes:w,constantBitRatios:c,optimizeFloatMemory:m,precision:x,lookupReturnType:R,lookupFunctionArgumentTypes:F,lookupFunctionArgumentName:k,lookupFunctionArgumentBitRatio:L,needsArgumentType:$,assignArgumentType:I,triggerImplyArgumentType:z,triggerImplyArgumentBitRatio:O,onFunctionCall:V,onNestedFunction:M})));let G=null;T&&(G=T.map(e=>{const{name:n,source:r}=e;return new t(r,Object.assign({},C,{name:n,isSubKernel:!0,isRootKernel:!1}))}));const P=new r({kernel:e,rootNode:K,functionNodes:U,nativeFunctions:d,subKernelNodes:G});return P}constructor(e){if(e=e||{},this.kernel=e.kernel,this.rootNode=e.rootNode,this.functionNodes=e.functionNodes||[],this.subKernelNodes=e.subKernelNodes||[],this.nativeFunctions=e.nativeFunctions||[],this.functionMap={},this.nativeFunctionNames=[],this.lookupChain=[],this.argumentChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1)return-1===t.indexOf(e)&&t.push(e),t;const n=this.functionMap[e];if(n){const r=t.indexOf(e);if(-1===r){t.push(e),n.toString();for(let e=0;e-1){t.push(this.nativeFunctions[i].source);continue}const s=this.functionMap[r];s&&t.push(s.toString())}return t}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map(e=>{const t=this.nativeFunctions.indexOf(e);if(t>-1)return{name:e,source:this.nativeFunctions[t].source};if(this.functionMap[e])return this.functionMap[e].toJSON();throw new Error(`function ${e} not found`)})}fromJSON(e,t){this.functionMap={};for(let n=0;n0){const i=t.arguments;for(let t=0;t0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"_"===e.object.name[0]?this.astMemberExpressionUnroll(e.property):this.astMemberExpressionUnroll(e.object)+"."+this.astMemberExpressionUnroll(e.property);if(e.hasOwnProperty("expressions")){const t=e.expressions[0];if("Literal"===t.type&&0===t.value&&2===e.expressions.length)return this.astMemberExpressionUnroll(e.expressions[1])}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",e)}getJsAST(e){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;if(null===(e=e||r))throw new Error("Missing JS to AST parser");const t=Object.freeze(e.parse(`const parser_${this.name} = ${this.source};`,{locations:!0})),n=t.body[0].declarations[0].init;if(this.traceFunctionAST(n),!t)throw new Error("Failed to parse JS code");return this.ast=n}traceFunctionAST(e){const{contexts:t,declarations:n,functions:r,identifiers:i,functionCalls:a}=new s(e);this.contexts=t,this.identifiers=i,this.functionCalls=a,this.declarations=[],this.functions=r;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const n=this.getType(e.left);if(this.isState("skip-literal-correction"))return n;if("LiteralInteger"===n){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return a[n]||n;case"UpdateExpression":return this.getType(e.argument);case"UnaryExpression":return"~"===e.operator?"Integer":this.getType(e.argument);case"VariableDeclaration":{const t=e.declarations;let n;for(let e=0;e-1}isAstMathFunction(e){return"CallExpression"===e.type&&e.callee&&"MemberExpression"===e.callee.type&&e.callee.object&&"Identifier"===e.callee.object.type&&"Math"===e.callee.object.name&&e.callee.property&&"Identifier"===e.callee.property.type&&["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","log2","max","min","pow","random","round","sign","sin","sqrt","tan"].indexOf(e.callee.property.name)>-1}isAstVariable(e){return"Identifier"===e.type||"MemberExpression"===e.type}isSafe(e){return this.isSafeDependencies(this.getDependencies(e))}isSafeDependencies(e){return!e||!e.every||e.every(e=>e.isSafe)}getDependencies(e,t,n){if(t||(t=[]),!e)return null;if(Array.isArray(e)){for(let r=0;r-1/0&&e.value<1/0&&!isNaN(e.value)});break;case"VariableDeclarator":return this.getDependencies(e.init,t,n);case"Identifier":const r=this.getDeclaration(e);if(r)t.push({name:e.name,origin:"declaration",isSafe:!n&&this.isSafeDependencies(r.dependencies)});else if(this.argumentNames.indexOf(e.name)>-1)t.push({name:e.name,origin:"argument",isSafe:!1});else if(this.strictTypingChecking)throw new Error(`Cannot find identifier origin "${e.name}"`);break;case"FunctionDeclaration":return this.getDependencies(e.body.body[e.body.body.length-1],t,n);case"ReturnStatement":return this.getDependencies(e.argument,t);case"BinaryExpression":return n="/"===e.operator||"*"===e.operator,this.getDependencies(e.left,t,n),this.getDependencies(e.right,t,n),t;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(e.argument,t,n);case"VariableDeclaration":return this.getDependencies(e.declarations,t,n);case"ArrayExpression":return t.push({origin:"declaration",isSafe:!0}),t;case"CallExpression":return t.push({origin:"function",isSafe:!0}),t;case"MemberExpression":const i=this.getMemberExpressionDetails(e);switch(i.signature){case"value[]":this.getDependencies(e.object,t,n);break;case"value[][]":this.getDependencies(e.object.object,t,n);break;case"value[][][]":this.getDependencies(e.object.object.object,t,n);break;case"this.output.value":this.dynamicOutput&&t.push({name:i.name,origin:"output",isSafe:!1})}if(i)return i.property&&this.getDependencies(i.property,t,n),i.xProperty&&this.getDependencies(i.xProperty,t,n),i.yProperty&&this.getDependencies(i.yProperty,t,n),i.zProperty&&this.getDependencies(i.zProperty,t,n),t;default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const t=[];for(;e;)e.computed?t.push("[]"):"ThisExpression"===e.type?t.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?t.unshift(".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?t.unshift("."+e.property.name):t.unshift(".value"):e.name?t.unshift("value"):e.callee&&e.callee.name?t.unshift("fn()"):e.elements?t.unshift("[]"):t.unshift("unknown"),e=e.object;const n=t.join("");return["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"].indexOf(n)>-1?n:null}build(){return this.toString().length>0}astGeneric(e,t){if(null===e)throw this.astErrorOutput("NULL ast",e);if(Array.isArray(e)){for(let n=0;n0?r[r.length-1]:0;return new Error(`${e} on line ${r.length}, position ${s.length}:\n ${n}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t0&&t.push(","),this.astGeneric(e.expressions,t);return t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)?t:(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t)}checkAndUpconvertBitwiseUnary(e,t){}astUpdateExpression(e,t){return e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t}astLogicalExpression(e,t){return t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t.push(")"),t}astMemberExpression(e,t){return t}astCallExpression(e,t){return t}astArrayExpression(e,t){return t}getMemberExpressionDetails(e){if("MemberExpression"!==e.type)throw this.astErrorOutput(`Expression ${e.type} not a MemberExpression`,e);let t=null,n=null;const r=this.getVariableSignature(e);switch(r){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:r,type:"Integer",name:e.property.name};case"value[]":if("string"!=typeof e.object.name)throw this.astErrorOutput("Unexpected expression",e);return{name:t=e.object.name,origin:"user",signature:r,type:this.getVariableType(e.object),xProperty:e.property};case"value[][]":if("string"!=typeof e.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return{name:t=e.object.object.name,origin:"user",signature:r,type:this.getVariableType(e.object.object),yProperty:e.object.property,xProperty:e.property};case"value[][][]":if("string"!=typeof e.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return{name:t=e.object.object.object.name,origin:"user",signature:r,type:this.getVariableType(e.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value[][][][]":if("string"!=typeof e.object.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return{name:t=e.object.object.object.object.name,origin:"user",signature:r,type:this.getVariableType(e.object.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(this.isAstMathVariable(e))return{name:t=e.property.name,origin:"Math",type:"Number",signature:r};switch(e.property.name){case"r":case"g":case"b":case"a":return{name:t=e.object.name,property:e.property.name,origin:"user",signature:r,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",e)}case"this.constants.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.property.name,!(n=this.getConstantType(t)))throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r};case"this.constants.value[]":if("string"!=typeof e.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.property.name,!(n=this.getConstantType(t)))throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,xProperty:e.property};case"this.constants.value[][]":if("string"!=typeof e.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.property.name,!(n=this.getConstantType(t)))throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,yProperty:e.object.property,xProperty:e.property};case"this.constants.value[][][]":if("string"!=typeof e.object.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.object.property.name,!(n=this.getConstantType(t)))throw this.astErrorOutput("Constant has no type",e);return{name:t,type:n,origin:"constants",signature:r,zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"fn()[]":case"[][]":return{signature:r,property:e.property};default:throw this.astErrorOutput("Unexpected expression",e)}}findIdentifierOrigin(e){const t=[this.ast];for(;t.length>0;){const n=t[0];if("VariableDeclarator"===n.type&&n.id&&n.id.name&&n.id.name===e.name)return n;if(t.shift(),n.argument)t.push(n.argument);else if(n.body)t.push(n.body);else if(n.declarations)t.push(n.declarations);else if(Array.isArray(n))for(let e=0;e0;){const e=t.pop();if("ReturnStatement"===e.type)return e;if("FunctionDeclaration"!==e.type)if(e.argument)t.push(e.argument);else if(e.body)t.push(e.body);else if(e.declarations)t.push(e.declarations);else if(Array.isArray(e))for(let n=0;n0?this.runningContexts[this.runningContexts.length-1]:null}newContext(e){const t=Object.assign({},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e(),this.runningContexts.pop()}scan(e){if(e)if(Array.isArray(e))for(let t=0;t{this.scan(e.body)});break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":this.scan(e.declarations);break;case"VariableDeclarator":const{currentContext:t}=this,n={ast:e,context:t,name:e.id.name,origin:"declaration",forceInteger:this.inLoopInit,assignable:!this.inLoopInit&&!t.hasOwnProperty(e.id.name)};t[e.id.name]=n,this.declarations.push(n),this.scan(e.id),this.scan(e.init);break;case"FunctionExpression":case"FunctionDeclaration":0===this.runningContexts.length?this.scan(e.body):this.functions.push(e);break;case"IfStatement":this.scan(e.test),this.scan(e.consequent),e.alternate&&this.scan(e.alternate);break;case"ForStatement":this.newContext(()=>{this.inLoopInit=!0,this.scan(e.init),this.inLoopInit=!1,this.scan(e.test),this.scan(e.update),this.newContext(()=>{this.scan(e.body)})});break;case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(e.body),this.scan(e.test)});break;case"Identifier":this.identifiers.push({context:this.currentContext,ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.scan(e.object),this.scan(e.property);break;case"ExpressionStatement":this.scan(e.expression);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast:e}),this.scan(e.arguments);break;case"ArrayExpression":this.scan(e.elements);break;case"ConditionalExpression":this.scan(e.test),this.scan(e.alternate),this.scan(e.consequent);break;case"SwitchStatement":this.scan(e.discriminant),this.scan(e.cases);break;case"SwitchCase":this.scan(e.test),this.scan(e.consequent);break;case"ThisExpression":case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}}},{}],11:[function(e,t,n){const{glWiretap:r}=e("gl-wiretap"),{utils:i}=e("../../utils");function s(e){return e.toString().replace("=>","").replace(/^function /,"").replace(/utils[.]/g,"/*utils.*/")}function a(e,t){const n="single"===t.precision?e:`new Float32Array(${e}.buffer)`;return t.output[2]?`renderOutput(${n}, ${t.output[0]}, ${t.output[1]}, ${t.output[2]})`:t.output[1]?`renderOutput(${n}, ${t.output[0]}, ${t.output[1]})`:`renderOutput(${n}, ${t.output[0]})`}function o(e,t){const n=e.toArray.toString(),r=!/^function/.test(n);return`() => {\n ${i.flattenFunctionToString(`${r?"function ":""}${n}`,{findDependency:(t,n)=>{if("utils"===t)return`const ${n} = ${i[n].toString()};`;if("this"===t)return`${r?"function ":""}${e[n].toString()}`;throw new Error("unhandled fromObject")},thisLookup:n=>{if("texture"===n)return t;if(e.hasOwnProperty(n))return JSON.stringify(e[n]);throw new Error(`unhandled thisLookup ${n}`)}})}\n return toArray();\n }`}function u(e,t,n,r,i){if(null===e)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement){for(let i=0;i{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}}):null;const h=[],p=r(n.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if(L.subKernels){if(d){const t=L.subKernels[g++].property;h.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${a(e,L)};`)}else h.push(` const result = { result: ${a(e,L)} };`),d=!0;g===L.subKernels.length&&h.push(" return result;")}else e?h.push(` return ${a(e,L)};`):h.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=u(e,L.kernelArguments,[],p);if(t)return t;const n=u(e,L.kernelConstants,A?Object.keys(A).map(e=>A[e]):[],p);return n||null}});let d=!1,g=0;const{source:m,canvas:x,output:f,pipeline:y,graphical:T,loopMaxIterations:b,constants:A,optimizeFloatMemory:S,precision:E,fixIntegerDivisionAccuracy:_,functions:v,nativeFunctions:D,subKernels:w,immutable:$,argumentTypes:I,constantTypes:R,kernelArguments:F,kernelConstants:k}=n,L=new e(m,{canvas:x,context:p,checkContext:!1,output:f,pipeline:y,graphical:T,loopMaxIterations:b,constants:A,optimizeFloatMemory:S,precision:E,fixIntegerDivisionAccuracy:_,functions:v,nativeFunctions:D,subKernels:w,immutable:$,argumentTypes:I,constantTypes:R});let z=[];if(p.setIndent(2),L.build.apply(L,t),z.push(p.toString()),p.reset(),L.kernelArguments.forEach((e,n)=>{switch(e.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLImage":case"HTMLVideo":p.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let r=0;re.varName).join(", ")}) {`),p.setIndent(4),L.run.apply(L,t),L.renderKernels?L.renderKernels():L.renderOutput&&L.renderOutput(),z.push(" /** start setup uploads for kernel values **/"),L.kernelArguments.forEach(e=>{z.push(" "+e.getStringValueHandler().split("\n").join("\n "))}),z.push(" /** end setup uploads for kernel values **/"),z.push(p.toString()),L.renderOutput===L.renderTexture){p.reset();const e=L.renderKernels(),t=p.getContextVariableName(L.outputTexture);z.push(` return {\n result: {\n texture: ${t},\n type: '${e.result.type}',\n toArray: ${o(e.result,t)}\n },`);const{subKernels:n,subKernelOutputTextures:r}=L;for(let t=0;t"utils"===e?`const ${t} = ${i[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}(L)),z.push(" innerKernel.getPixels = getPixels;")),z.push(" return innerKernel;");let O=[];return k.forEach(e=>{O.push(`${e.getStringValueHandler()}`)}),`function kernel(settings) {\n const { context, constants } = settings;\n ${O.join("")}\n ${l||""}\n${z.join("\n")}\n}`}}},{"../../utils":111,"gl-wiretap":2}],12:[function(e,t,n){const{Kernel:r}=e("../kernel"),{Texture:i}=e("../../texture"),{utils:s}=e("../../utils"),{GLTextureArray2Float:a}=e("./texture/array-2-float"),{GLTextureArray2Float2D:o}=e("./texture/array-2-float-2d"),{GLTextureArray2Float3D:u}=e("./texture/array-2-float-3d"),{GLTextureArray3Float:l}=e("./texture/array-3-float"),{GLTextureArray3Float2D:c}=e("./texture/array-3-float-2d"),{GLTextureArray3Float3D:h}=e("./texture/array-3-float-3d"),{GLTextureArray4Float:p}=e("./texture/array-4-float"),{GLTextureArray4Float2D:d}=e("./texture/array-4-float-2d"),{GLTextureArray4Float3D:g}=e("./texture/array-4-float-3d"),{GLTextureFloat:m}=e("./texture/float"),{GLTextureFloat2D:x}=e("./texture/float-2d"),{GLTextureFloat3D:f}=e("./texture/float-3d"),{GLTextureMemoryOptimized:y}=e("./texture/memory-optimized"),{GLTextureMemoryOptimized2D:T}=e("./texture/memory-optimized-2d"),{GLTextureMemoryOptimized3D:b}=e("./texture/memory-optimized-3d"),{GLTextureUnsigned:A}=e("./texture/unsigned"),{GLTextureUnsigned2D:S}=e("./texture/unsigned-2d"),{GLTextureUnsigned3D:E}=e("./texture/unsigned-3d"),{GLTextureGraphical:_}=e("./texture/graphical");const v=Object.freeze({PackedPixelToUint8Array:Symbol("PackedPixelToUint8Array"),PackedPixelToFloat:Symbol("PackedPixelToFloat"),PackedPixelTo2DFloat:Symbol("PackedPixelTo2DFloat"),PackedPixelTo3DFloat:Symbol("PackedPixelTo3DFloat"),PackedTexture:Symbol("PackedTexture"),FloatPixelToFloat32Array:Symbol("FloatPixelToFloat32Array"),FloatPixelToFloat:Symbol("FloatPixelToFloat"),FloatPixelTo2DFloat:Symbol("FloatPixelTo2DFloat"),FloatPixelTo3DFloat:Symbol("FloatPixelTo3DFloat"),FloatPixelToArray2:Symbol("FloatPixelToArray2"),FloatPixelTo2DArray2:Symbol("FloatPixelTo2DArray2"),FloatPixelTo3DArray2:Symbol("FloatPixelTo3DArray2"),FloatPixelToArray3:Symbol("FloatPixelToArray3"),FloatPixelTo2DArray3:Symbol("FloatPixelTo2DArray3"),FloatPixelTo3DArray3:Symbol("FloatPixelTo3DArray3"),FloatPixelToArray4:Symbol("FloatPixelToArray4"),FloatPixelTo2DArray4:Symbol("FloatPixelTo2DArray4"),FloatPixelTo3DArray4:Symbol("FloatPixelTo3DArray4"),FloatTexture:Symbol("FloatTexture"),MemoryOptimizedFloatPixelToMemoryOptimizedFloat:Symbol("MemoryOptimizedFloatPixelToFloat"),MemoryOptimizedFloatPixelToMemoryOptimized2DFloat:Symbol("MemoryOptimizedFloatPixelTo2DFloat"),MemoryOptimizedFloatPixelToMemoryOptimized3DFloat:Symbol("MemoryOptimizedFloatPixelTo3DFloat")}),D={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};t.exports={GLKernel:class extends r{static get mode(){return"gpu"}static getIsFloatRead(){const e=new this("function kernelFunction() {\n return 1;\n }",{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[1],precision:"single",returnType:"Number",tactic:"speed"});e.build(),e.run();const t=e.renderOutput();return e.destroy(!0),1===t[0]}static getIsIntegerDivisionAccurate(){const e=new this(function(e,t){return e[this.thread.x]/t[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[2],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[6,6030401],[3,3991]];e.build.apply(e,t),e.run.apply(e,t);const n=e.renderOutput();return e.destroy(!0),2===n[0]&&1511===n[1]}static get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static get features(){throw new Error(`"features" not defined on ${this.name}`)}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return s.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],n=[],r=[],i=/^[a-zA-Z_]/,s=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?r[r.length-1]:null;if("FUNCTION_ARGUMENTS"!==h||"/"!==l||"*"!==c)if("MULTI_LINE_COMMENT"!==h||"*"!==l||"/"!==c)if("FUNCTION_ARGUMENTS"!==h||"/"!==l||"/"!==c)if("COMMENT"!==h||"\n"!==l)if(null!==h||"("!==l){if("FUNCTION_ARGUMENTS"===h){if(")"===l){r.pop();break}if("f"===l&&"l"===c&&"o"===e[a+2]&&"a"===e[a+3]&&"t"===e[a+4]&&" "===e[a+5]){r.push("DECLARE_VARIABLE"),u="float",o="",a+=6;continue}if("i"===l&&"n"===c&&"t"===e[a+2]&&" "===e[a+3]){r.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===l&&"e"===c&&"c"===e[a+2]&&"2"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec2",o="",a+=5;continue}if("v"===l&&"e"===c&&"c"===e[a+2]&&"3"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec3",o="",a+=5;continue}if("v"===l&&"e"===c&&"c"===e[a+2]&&"4"===e[a+3]&&" "===e[a+4]){r.push("DECLARE_VARIABLE"),u="vec4",o="",a+=5;continue}}else if("DECLARE_VARIABLE"===h){if(""===o){if(" "===l){a++;continue}if(!i.test(l))throw new Error("variable name is not expected string")}o+=l,s.test(c)||(r.pop(),n.push(o),t.push(D[u]))}a++}else r.push("FUNCTION_ARGUMENTS"),a++;else r.pop(),a++;else r.push("COMMENT"),a+=2;else r.pop(),a+=2;else r.push("MULTI_LINE_COMMENT"),a+=2}if(r.length>0)throw new Error("GLSL function was not parsable");return{argumentNames:n,argumentTypes:t}}static nativeFunctionReturnType(e){return D[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:n,context:r,threadDim:i}=t.texSize;let a;if("single"===t.precision){const e=n[0],t=Math.ceil(n[1]/4);a=new Float32Array(e*t*4*4),r.readPixels(0,0,e,4*t,r.RGBA,r.FLOAT,a)}else{const e=new Uint8Array(n[0]*n[1]*4);r.readPixels(0,0,n[0],n[1],r.RGBA,r.UNSIGNED_BYTE,e),a=new Float32Array(e.buffer)}return a=a.subarray(0,i[0]*i[1]*i[2]),1===t.output.length?a:2===t.output.length?s.splitArray(a,t.output[0]):3===t.output.length?s.splitArray(a,t.output[0]*t.output[1]).map(function(e){return s.splitArray(e,t.output[0])}):void 0}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.renderStrategy=null,this.compiledFragmentShader=null,this.compiledVertexShader=null}checkTextureSize(){const{features:e}=this.constructor;if(this.texSize[0]>e.maxTextureSize||this.texSize[1]>e.maxTextureSize)throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${e.maxTextureSize},${e.maxTextureSize}]`)}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(e){if(this.graphical)return this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=(e=>e),this.TextureConstructor=_,null;if("unsigned"===this.precision)if(this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=this.readPackedPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=E,this.renderStrategy=v.PackedPixelTo3DFloat,null):this.output[1]>0?(this.TextureConstructor=S,this.renderStrategy=v.PackedPixelTo2DFloat,null):(this.TextureConstructor=A,this.renderStrategy=v.PackedPixelToFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else switch(null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.renderOutput=this.renderValues,this.output[2]>0?(this.TextureConstructor=E,this.renderStrategy=v.PackedPixelTo3DFloat,this.formatValues=s.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=S,this.renderStrategy=v.PackedPixelTo2DFloat,this.formatValues=s.erect2DPackedFloat,null):(this.TextureConstructor=A,this.renderStrategy=v.PackedPixelToFloat,this.formatValues=s.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderStrategy=v.FloatTexture,this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=b,null):this.output[1]>0?(this.TextureConstructor=T,null):(this.TextureConstructor=y,null):this.output[2]>0?(this.TextureConstructor=f,null):this.output[1]>0?(this.TextureConstructor=x,null):(this.TextureConstructor=m,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,null):this.output[1]>0?(this.TextureConstructor=o,null):(this.TextureConstructor=a,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,null):this.output[1]>0?(this.TextureConstructor=c,null):(this.TextureConstructor=l,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=g,null):this.output[1]>0?(this.TextureConstructor=d,null):(this.TextureConstructor=p,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=b,this.renderStrategy=v.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat,this.formatValues=s.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=T,this.renderStrategy=v.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat,this.formatValues=s.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=y,this.renderStrategy=v.MemoryOptimizedFloatPixelToMemoryOptimizedFloat,this.formatValues=s.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.renderStrategy=v.FloatPixelTo3DArray2,this.formatValues=s.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.renderStrategy=v.FloatPixelTo2DArray2,this.formatValues=s.erect2DArray2,null):(this.TextureConstructor=a,this.renderStrategy=v.FloatPixelToArray2,this.formatValues=s.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.renderStrategy=v.FloatPixelTo3DArray3,this.formatValues=s.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=c,this.renderStrategy=v.FloatPixelTo2DArray3,this.formatValues=s.erect2DArray3,null):(this.TextureConstructor=l,this.renderStrategy=v.FloatPixelToArray3,this.formatValues=s.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=g,this.renderStrategy=v.FloatPixelTo3DArray4,this.formatValues=s.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.renderStrategy=v.FloatPixelTo2DArray4,this.formatValues=s.erect2DArray4,null):(this.TextureConstructor=p,this.renderStrategy=v.FloatPixelToArray4,this.formatValues=s.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=f,this.renderStrategy=v.FloatPixelTo3DFloat,this.formatValues=s.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=x,this.renderStrategy=v.FloatPixelTo2DFloat,this.formatValues=s.erect2DFloat,null):(this.TextureConstructor=m,this.renderStrategy=v.FloatPixelToFloat,this.formatValues=s.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=u,this.renderStrategy=v.FloatPixelTo3DArray2,this.formatValues=s.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=o,this.renderStrategy=v.FloatPixelTo2DArray2,this.formatValues=s.erect2DArray2,null):(this.TextureConstructor=a,this.renderStrategy=v.FloatPixelToArray2,this.formatValues=s.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=h,this.renderStrategy=v.FloatPixelTo3DArray3,this.formatValues=s.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=c,this.renderStrategy=v.FloatPixelTo2DArray3,this.formatValues=s.erect2DArray3,null):(this.TextureConstructor=l,this.renderStrategy=v.FloatPixelToArray3,this.formatValues=s.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=g,this.renderStrategy=v.FloatPixelTo3DArray4,this.formatValues=s.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=d,this.renderStrategy=v.FloatPixelTo2DArray4,this.formatValues=s.erect2DArray4,null):(this.TextureConstructor=p,this.renderStrategy=v.FloatPixelToArray4,this.formatValues=s.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return s.linesToString(this.getMainResultKernelNumberTexture())+s.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return s.linesToString(this.getMainResultKernelArray2Texture())+s.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return s.linesToString(this.getMainResultKernelArray3Texture())+s.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return s.linesToString(this.getMainResultKernelArray4Texture())+s.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp float;\n";case"performance":return"precision highp float;\n";case"balanced":default:return"precision mediump float;\n"}}getIntTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp int;\n";case"performance":return"precision highp int;\n";case"balanced":default:return"precision mediump int;\n"}}getSampler2DTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp sampler2D;\n";case"performance":return"precision highp sampler2D;\n";case"balanced":default:return"precision mediump sampler2D;\n"}}getSampler2DArrayTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp sampler2DArray;\n";case"performance":return"precision highp sampler2DArray;\n";case"balanced":default:return"precision mediump sampler2DArray;\n"}}renderTexture(){return new this.TextureConstructor({texture:this.outputTexture,size:this.texSize,dimensions:this.threadDim,output:this.output,context:this.context})}readPackedPixelsToUint8Array(){if("unsigned"!==this.precision)throw new Error('Requires this.precision to be "unsigned"');const{texSize:e,context:t}=this,n=new Uint8Array(e[0]*e[1]*4);return t.readPixels(0,0,e[0],e[1],t.RGBA,t.UNSIGNED_BYTE,n),n}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,n=e[0],r=e[1],i=new Float32Array(n*r*4);return t.readPixels(0,0,n,r,t.RGBA,t.FLOAT,i),i}readMemoryOptimizedFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,n=e[0],r=e[1],i=new Float32Array(n*r*4);return t.readPixels(0,0,n,r,t.RGBA,t.FLOAT,i),i}getPixels(e){const{context:t,output:n}=this,[r,i]=n,a=new Uint8Array(r*i*4);return t.readPixels(0,0,r,i,t.RGBA,t.UNSIGNED_BYTE,a),new Uint8ClampedArray((e?a:s.flipPixels(a,r,i)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0&&this._setupSubOutputTextures()}return this}renderValues(){return this.formatValues(this.transferValues(),this.output[0],this.output[1],this.output[2])}},renderStrategy:v}},{"../../texture":110,"../../utils":111,"../kernel":34,"./texture/array-2-float":15,"./texture/array-2-float-2d":13,"./texture/array-2-float-3d":14,"./texture/array-3-float":18,"./texture/array-3-float-2d":16,"./texture/array-3-float-3d":17,"./texture/array-4-float":21,"./texture/array-4-float-2d":19,"./texture/array-4-float-3d":20,"./texture/float":24,"./texture/float-2d":22,"./texture/float-3d":23,"./texture/graphical":25,"./texture/memory-optimized":28,"./texture/memory-optimized-2d":26,"./texture/memory-optimized-3d":27,"./texture/unsigned":31,"./texture/unsigned-2d":29,"./texture/unsigned-3d":30}],13:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray2Float2D:class extends i{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect2DArray2(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],14:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray2Float3D:class extends i{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erect3DArray2(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],15:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray2Float:class extends i{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return r.erectArray2(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],16:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray3Float2D:class extends i{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect2DArray3(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],17:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray3Float3D:class extends i{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erect3DArray3(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],18:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray3Float:class extends i{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return r.erectArray3(this.renderValues(),this.output[0])}}}},{"../../../utils":111,"./float":24}],19:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray4Float2D:class extends i{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect2DArray4(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],20:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray4Float3D:class extends i{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erect3DArray4(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],21:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureArray4Float:class extends i{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return r.erectArray4(this.renderValues(),this.output[0])}}}},{"../../../utils":111,"./float":24}],22:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureFloat2D:class extends i{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect2DFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],23:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureFloat3D:class extends i{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return r.erect3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],24:[function(e,t,n){const{utils:r}=e("../../../utils"),{Texture:i}=e("../../../texture");t.exports={GLTextureFloat:class extends i{constructor(e){super(e),this.type="ArrayTexture(1)"}renderRawOutput(){const{context:e}=this,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const n=new Float32Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.FLOAT,n),n}renderValues(){return this.renderRawOutput()}toArray(){return r.erectFloat(this.renderValues(),this.output[0])}}}},{"../../../texture":110,"../../../utils":111}],25:[function(e,t,n){const{GLTextureUnsigned:r}=e("./unsigned");t.exports={GLTextureGraphical:class extends r{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return this.renderValues()}}}},{"./unsigned":31}],26:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized2D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./float":24}],27:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized3D:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./float":24}],28:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureFloat:i}=e("./float");t.exports={GLTextureMemoryOptimized:class extends i{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return r.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}}},{"../../../utils":111,"./float":24}],29:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned2D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}}},{"../../../utils":111,"./unsigned":31}],30:[function(e,t,n){const{utils:r}=e("../../../utils"),{GLTextureUnsigned:i}=e("./unsigned");t.exports={GLTextureUnsigned3D:class extends i{constructor(e){super(e),this.type="NumberTexture"}toArray(){return r.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}}},{"../../../utils":111,"./unsigned":31}],31:[function(e,t,n){const{utils:r}=e("../../../utils"),{Texture:i}=e("../../../texture");t.exports={GLTextureUnsigned:class extends i{constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const n=new Uint8Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.UNSIGNED_BYTE,n),n}renderValues(){return new Float32Array(this.renderRawOutput().buffer)}toArray(){return r.erectPackedFloat(this.renderValues(),this.output[0])}}}},{"../../../texture":110,"../../../utils":111}],32:[function(e,t,n){const r=e("gl"),{WebGLKernel:i}=e("../web-gl/kernel"),{glKernelString:s}=e("../gl/kernel-string");let a=null,o=null,u=null,l=null,c=null;t.exports={HeadlessGLKernel:class extends i{static get isSupported(){return null!==a?a:(this.setupFeatureChecks(),a=null!==u)}static setupFeatureChecks(){if(o=null,l=null,"function"==typeof r)try{if(!(u=r(2,2,{preserveDrawingBuffer:!0}))||!u.getExtension)return;l={STACKGL_resize_drawingbuffer:u.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:u.getExtension("STACKGL_destroy_context"),OES_texture_float:u.getExtension("OES_texture_float"),OES_texture_float_linear:u.getExtension("OES_texture_float_linear"),OES_element_index_uint:u.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:u.getExtension("WEBGL_draw_buffers")},c=this.getFeatures()}catch(e){console.warn(e)}}static isContextMatch(e){try{return"ANGLE"===e.getParameter(e.RENDERER)}catch(e){return!1}}static getFeatures(){const e=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:e,kernelMap:e,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize()})}static getIsTextureFloat(){return Boolean(l.OES_texture_float)}static getIsDrawBuffers(){return Boolean(l.WEBGL_draw_buffers)}static getChannelCount(){return l.WEBGL_draw_buffers?u.getParameter(l.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return u.getParameter(u.MAX_TEXTURE_SIZE)}static get testCanvas(){return o}static get testContext(){return u}static get features(){return c}initCanvas(){return{}}initContext(){return r(2,2,{preserveDrawingBuffer:!0})}initExtensions(){this.extensions={STACKGL_resize_drawingbuffer:this.context.getExtension("STACKGL_resize_drawingbuffer"),STACKGL_destroy_context:this.context.getExtension("STACKGL_destroy_context"),OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers")}}build(){super.build.apply(this,arguments),this.fallbackRequested||this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}destroyExtensions(){this.extensions.STACKGL_resize_drawingbuffer=null,this.extensions.STACKGL_destroy_context=null,this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("STACKGL_destroy_context");t&&t.destroy&&t.destroy()}toString(){return s(this.constructor,arguments,this,"const gl = context || require('gl')(1, 1);\n"," if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n")}setOutput(e){super.setOutput(e),this.graphical&&this.extensions.STACKGL_resize_drawingbuffer&&this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0],this.maxTexSize[1])}}}},{"../gl/kernel-string":11,"../web-gl/kernel":67,gl:1}],33:[function(e,t,n){t.exports={KernelValue:class{constructor(e,t){const{name:n,kernel:r,context:i,checkContext:s,onRequestContextHandle:a,onUpdateValueMismatch:o,origin:u,strictIntegers:l,type:c,tactic:h}=t;if(!n)throw new Error("name not set");if(!c)throw new Error("type not set");if(!u)throw new Error("origin not set");if(!h)throw new Error("tactic not set");if("user"!==u&&"constants"!==u)throw new Error(`origin must be "user" or "constants" value is "${u}"`);if(!a)throw new Error("onRequestContextHandle is not set");this.name=n,this.origin=u,this.tactic=h,this.id=`${this.origin}_${n}`,this.varName="constants"===u?`constants.${n}`:n,this.kernel=r,this.strictIntegers=l,this.type=e.type||c,this.size=e.size||null,this.index=null,this.context=i,this.checkContext=null==s||s,this.contextHandle=null,this.onRequestContextHandle=a,this.onUpdateValueMismatch=o,this.forceUploadEachRun=null}getSource(){throw new Error(`"getSource" not defined on ${this.constructor.name}`)}updateValue(e){throw new Error(`"updateValue" not defined on ${this.constructor.name}`)}}}},{}],34:[function(e,t,n){const{utils:r}=e("../utils"),{Input:i}=e("../input");t.exports={Kernel:class{static get isSupported(){throw new Error(`"isSupported" not implemented on ${this.name}`)}static isContextMatch(e){throw new Error(`"isContextMatch" not implemented on ${this.name}`)}static getFeatures(){throw new Error(`"getFeatures" not implemented on ${this.name}`)}static destroyContext(e){throw new Error(`"destroyContext" called on ${this.name}`)}static nativeFunctionArguments(){throw new Error(`"nativeFunctionArguments" called on ${this.name}`)}static nativeFunctionReturnType(){throw new Error(`"nativeFunctionReturnType" called on ${this.name}`)}static combineKernels(){throw new Error(`"combineKernels" called on ${this.name}`)}constructor(e,t){if("object"!=typeof e){if("string"!=typeof e)throw new Error("source not a string");if(!r.isFunctionString(e))throw new Error("source not a function string")}this.useLegacyEncoder=!1,this.fallbackRequested=!1,this.onRequestFallback=null,this.argumentNames="string"==typeof e?r.getArgumentNamesFromString(e):null,this.argumentTypes=null,this.argumentSizes=null,this.argumentBitRatios=null,this.kernelArguments=null,this.kernelConstants=null,this.forceUploadKernelConstants=null,this.source=e,this.output=null,this.debug=!1,this.graphical=!1,this.loopMaxIterations=0,this.constants=null,this.constantTypes=null,this.constantBitRatios=null,this.dynamicArguments=!1,this.dynamicOutput=!1,this.canvas=null,this.context=null,this.checkContext=null,this.gpu=null,this.functions=null,this.nativeFunctions=null,this.injectedNative=null,this.subKernels=null,this.validate=!0,this.immutable=!1,this.pipeline=!1,this.precision=null,this.tactic="balanced",this.plugins=null,this.returnType=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.optimizeFloatMemory=null,this.strictIntegers=!1,this.fixIntegerDivisionAccuracy=null,this.warnVarUsage=!0}mergeSettings(e){for(let t in e)if(e.hasOwnProperty(t)&&this.hasOwnProperty(t)){switch(t){case"output":if(!Array.isArray(e.output)){this.setOutput(e.output);continue}break;case"functions":if("function"==typeof e.functions[0]){this.functions=e.functions.map(e=>r.functionToIFunction(e));continue}break;case"graphical":e[t]&&!e.hasOwnProperty("precision")&&(this.precision="unsigned"),this[t]=e[t];continue}this[t]=e[t]}this.canvas||(this.canvas=this.initCanvas()),this.context||(this.context=this.initContext()),this.plugins||(this.plugins=this.initPlugins(e))}build(){throw new Error(`"build" not defined on ${this.constructor.name}`)}run(){throw new Error(`"run" not defined on ${this.constructor.name}`)}initCanvas(){throw new Error(`"initCanvas" not defined on ${this.constructor.name}`)}initContext(){throw new Error(`"initContext" not defined on ${this.constructor.name}`)}initPlugins(e){throw new Error(`"initPlugins" not defined on ${this.constructor.name}`)}setupArguments(e){if(this.kernelArguments=[],this.argumentTypes)for(let e=0;er.functionToIFunction(e)):this.functions=e,this}setNativeFunctions(e){return this.nativeFunctions=e,this}setInjectedNative(e){return this.injectedNative=e,this}setPipeline(e){return this.pipeline=e,this}setPrecision(e){return this.precision=e,this}setOutputToTexture(e){return r.warnDeprecated("method","setOutputToTexture","setPipeline"),this.pipeline=e,this}setImmutable(e){return this.immutable=e,this}setCanvas(e){return this.canvas=e,this}setStrictIntegers(e){return this.strictIntegers=e,this}setDynamicOutput(e){return this.dynamicOutput=e,this}setHardcodeConstants(e){return r.warnDeprecated("method","setHardcodeConstants"),this.setDynamicOutput(e),this.setDynamicArguments(e),this}setDynamicArguments(e){return this.dynamicArguments=e,this}setUseLegacyEncoder(e){return this.useLegacyEncoder=e,this}setWarnVarUsage(e){return this.warnVarUsage=e,this}getCanvas(){return r.warnDeprecated("method","getCanvas"),this.canvas}getWebGl(){return r.warnDeprecated("method","getWebGl"),this.context}setContext(e){return this.context=e,this}setArgumentTypes(e){if(Array.isArray(e))this.argumentTypes=e;else{this.argumentTypes=[];for(const t in e){const n=this.argumentNames.indexOf(t);if(-1===n)throw new Error(`unable to find argument ${t}`);this.argumentTypes[n]=e[t]}}return this}setTactic(e){return this.tactic=e,this}requestFallback(e){if(!this.onRequestFallback)throw new Error(`"onRequestFallback" not defined on ${this.constructor.name}`);return this.fallbackRequested=!0,this.onRequestFallback(e)}validateSettings(){throw new Error(`"validateSettings" not defined on ${this.constructor.name}`)}addSubKernel(e){if(null===this.subKernels&&(this.subKernels=[]),!e.source)throw new Error('subKernel missing "source" property');if(!e.property&&isNaN(e.property))throw new Error('subKernel missing "property" property');if(!e.name)throw new Error('subKernel missing "name" property');return this.subKernels.push(e),this}destroy(e){throw new Error(`"destroy" called on ${this.constructor.name}`)}getBitRatio(e){if("single"===this.precision)return 4;if(Array.isArray(e[0]))return this.getBitRatio(e[0]);if(e.constructor===i)return this.getBitRatio(e.value);switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:return 1;case Uint16Array:case Int16Array:return 2;case Float32Array:case Int32Array:default:return 4}}getPixels(){throw new Error(`"getPixels" called on ${this.constructor.name}`)}checkOutput(){if(!this.output||!r.isArray(this.output))throw new Error("kernel.output not an array");if(this.output.length<1)throw new Error("kernel.output is empty, needs at least 1 value");for(let e=0;ee.name):null,returnType:this.returnType}}}}}},{"../input":107,"../utils":111}],35:[function(e,t,n){t.exports={fragmentShader:"__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nvec4 round(vec4 x) {\n return floor(x + 0.5);\n}\n\nfloat round(float x) {\n return floor(x + 0.5);\n}\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n; \n }\n a = a / 2;\n n = n * 2;\n }\n return result;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x / y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\n return 0.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n if (channel == 0) return texel.r * 255.0;\n if (channel == 1) return texel.g * 255.0;\n if (channel == 2) return texel.b * 255.0;\n if (channel == 3) return texel.a * 255.0;\n return 0.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n\n mantissa = value*pow(2.0, -exponent)-1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return texel.r;\n if (channel == 1) return texel.g;\n if (channel == 2) return texel.b;\n if (channel == 3) return texel.a;\n return 0.0;\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture2D(tex, st / vec2(texSize));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n \n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n actualColor = texture2D(image, vTexCoord);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}"}},{}],36:[function(e,t,n){const{utils:r}=e("../../utils"),{FunctionNode:i}=e("../function-node");const s={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4",Array2D:"sampler2D",Array3D:"sampler2D",Boolean:"bool",Float:"float",Input:"sampler2D",Integer:"int",Number:"float",LiteralInteger:"float",NumberTexture:"sampler2D",MemoryOptimizedNumberTexture:"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D",HTMLVideo:"sampler2D",HTMLImage:"sampler2D",HTMLImageArray:"sampler2DArray"},a={"===":"==","!==":"!="};t.exports={WebGLFunctionNode:class extends i{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{this.returnType||this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"));const{returnType:n}=this;if(n){const e=s[n];if(!e)throw new Error(`unknown type ${n}`);t.push(e)}else t.push("void")}if(t.push(" "),t.push(this.name),t.push("("),!this.isRootKernel)for(let n=0;n0&&t.push(", ");let i=this.argumentTypes[this.argumentNames.indexOf(r)];if(!i)throw this.astErrorOutput(`Unknown argument ${r} type`,e);"LiteralInteger"===i&&(this.argumentTypes[n]=i="Number");const a=s[i];if(!a)throw this.astErrorOutput("Unexpected expression",e);"sampler2D"===a||"sampler2DArray"===a?t.push(`${a} user_${r},ivec2 user_${r}Size,ivec3 user_${r}Dim`):t.push(`${a} user_${r}`)}t.push(") {\n");for(let n=0;n"===e.operator||"<"===e.operator&&"Literal"===e.right.type)&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const n=[];if(this.astGeneric(e.right,n),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(n.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.isState("in-for-loop-test")?(this.pushState("building-integer"),t.push("int("),this.astGeneric(e.left,t),t.push(")"),t.push(a[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float"));break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("in-for-loop-test")||this.isState("in-for-loop-init")||this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(a[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${i}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){const n=this.checkAndUpconvertBitwiseOperators(e,t);if(n)return n;const r={"%":"mod","**":"pow"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const n={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const n={"~":"bitwiseNot"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===n&&this.argumentNames.indexOf(e.name)>-1?t.push(`bool(user_${e.name})`):t.push(`user_${e.name}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const n=[],r=[],i=[],s=[];let a=null;if(e.init){this.pushState("in-for-loop-init"),this.astGeneric(e.init,n);const{declarations:t}=e.init;for(let e=0;e0&&t.push(n.join(""),";\n"),t.push(`for (int ${e}=0;${e}0&&t.push(`if (!${r.join("")}) break;\n`),t.push(s.join("")),t.push(`\n${i.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const n=this.getInternalVariableName("safeI");return t.push(`for (int ${n}=0;${n}e+1){u=!0,this.astGeneric(r[e].consequent,o);continue}t.push(" else {\n")}this.astGeneric(r[e].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t}astThisExpression(e,t){return t.push("this"),t}astMemberExpression(e,t){const{property:n,name:r,signature:i,origin:s,type:a,xProperty:o,yProperty:u,zProperty:l}=this.getMemberExpressionDetails(e);switch(i){case"value.thread.value":case"this.thread.value":if("x"!==r&&"y"!==r&&"z"!==r)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${r}`),t;case"this.output.value":if(this.dynamicOutput)switch(r){case"x":this.isState("casting-to-float")?t.push("float(uOutputDim.x)"):t.push("uOutputDim.x");break;case"y":this.isState("casting-to-float")?t.push("float(uOutputDim.y)"):t.push("uOutputDim.y");break;case"z":this.isState("casting-to-float")?t.push("float(uOutputDim.z)"):t.push("uOutputDim.z");break;default:throw this.astErrorOutput("Unexpected expression",e)}else switch(r){case"x":this.isState("casting-to-integer")?t.push(this.output[0]):t.push(this.output[0],".0");break;case"y":this.isState("casting-to-integer")?t.push(this.output[1]):t.push(this.output[1],".0");break;case"z":this.isState("casting-to-integer")?t.push(this.output[2]):t.push(this.output[2],".0");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===s)return t.push(Math[r]),t;switch(n){case"r":return t.push(`user_${r}.r`),t;case"g":return t.push(`user_${r}.g`),t;case"b":return t.push(`user_${r}.b`),t;case"a":return t.push(`user_${r}.a`),t}break;case"this.constants.value":if(void 0===o)switch(a){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${r}`),t}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":return this.astCallExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;case"[][]":return this.astArrayExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(n)),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!1===e.computed)switch(a){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${s}_${r}`),t}const c=`${s}_${r}`;switch(a){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(o)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLImage":case"HTMLVideo":t.push(`getVec4FromSampler2D(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");else{const e="user"===s?this.lookupFunctionArgumentBitRatio(this.name,r):this.constantBitRatios[r];switch(e){case 1:t.push(`get8(${c}, ${c}Size, ${c}Dim, `);break;case 2:t.push(`get16(${c}, ${c}Size, ${c}Dim, `);break;case 4:case 0:t.push(`get32(${c}, ${c}Size, ${c}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(o,u,l,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${c}, ${c}Size, ${c}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;default:throw new Error(`unhandled member expression "${a}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let n=null;const r=this.isAstMathFunction(e);if(!(n=r||e.callee.object&&"ThisExpression"===e.callee.object.type?e.callee.property.name:"SequenceExpression"!==e.callee.type||"Literal"!==e.callee.expressions[0].type||isNaN(e.callee.expressions[0].raw)?e.callee.name:e.callee.expressions[1].property.name))throw this.astErrorOutput("Unhandled function, couldn't find name",e);if("atan2"===n&&(n="atan"),this.calledFunctions.indexOf(n)<0&&this.calledFunctions.push(n),"random"===n&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),i){case"Integer":this.castValueToFloat(r,t);break;default:this.astGeneric(r,t)}}else{const r=this.lookupFunctionArgumentTypes(n)||[];for(let i=0;i0&&t.push(", ");const o=this.getType(s);switch(a||(this.triggerImplyArgumentType(n,i,o,this),a=o),o){case"Number":case"Float":if("Integer"===a){t.push("int("),this.astGeneric(s,t),t.push(")");continue}if("Number"===a||"Float"===a){this.astGeneric(s,t);continue}if("LiteralInteger"===a){this.castLiteralToFloat(s,t);continue}break;case"Integer":if("Number"===a||"Float"===a){t.push("float("),this.astGeneric(s,t),t.push(")");continue}if("Integer"===a){this.astGeneric(s,t);continue}break;case"LiteralInteger":if("Integer"===a){this.castLiteralToInteger(s,t);continue}if("Number"===a||"Float"===a){this.castLiteralToFloat(s,t);continue}if("LiteralInteger"===a){this.astGeneric(s,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(a===o){if("Identifier"!==s.type)throw this.astErrorOutput(`Unhandled argument type ${s.type}`,e);this.triggerImplyArgumentBitRatio(this.name,s.name,n,i),t.push(`user_${s.name}`);continue}break;case"HTMLImage":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(a===o){if("Identifier"!==s.type)throw this.astErrorOutput(`Unhandled argument type ${s.type}`,e);this.triggerImplyArgumentBitRatio(this.name,s.name,n,i),t.push(`user_${s.name},user_${s.name}Size,user_${s.name}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${o} and ${a} for argument named "${s.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const n=e.elements.length;t.push("vec"+n+"(");for(let r=0;r0&&t.push(", ");const n=e.elements[r];this.astGeneric(n,t)}return t.push(")"),t}memberExpressionXYZ(e,t,n,r){return n?r.push(this.memberExpressionPropertyMarkup(n),", "):r.push("0, "),t?r.push(this.memberExpressionPropertyMarkup(t),", "):r.push("0, "),r.push(this.memberExpressionPropertyMarkup(e)),r}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.astGeneric(e,t)}return t.join("")}}}},{"../../utils":111,"../function-node":9}],37:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("./kernel-value/boolean"),{WebGLKernelValueFloat:i}=e("./kernel-value/float"),{WebGLKernelValueInteger:s}=e("./kernel-value/integer"),{WebGLKernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGLKernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGLKernelValueHTMLVideo:u}=e("./kernel-value/html-video"),{WebGLKernelValueDynamicHTMLVideo:l}=e("./kernel-value/dynamic-html-video"),{WebGLKernelValueSingleInput:c}=e("./kernel-value/single-input"),{WebGLKernelValueDynamicSingleInput:h}=e("./kernel-value/dynamic-single-input"),{WebGLKernelValueUnsignedInput:p}=e("./kernel-value/unsigned-input"),{WebGLKernelValueDynamicUnsignedInput:d}=e("./kernel-value/dynamic-unsigned-input"),{WebGLKernelValueMemoryOptimizedNumberTexture:g}=e("./kernel-value/memory-optimized-number-texture"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:m}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGLKernelValueNumberTexture:x}=e("./kernel-value/number-texture"),{WebGLKernelValueDynamicNumberTexture:f}=e("./kernel-value/dynamic-number-texture"),{WebGLKernelValueSingleArray:y}=e("./kernel-value/single-array"),{WebGLKernelValueDynamicSingleArray:T}=e("./kernel-value/dynamic-single-array"),{WebGLKernelValueSingleArray1DI:b}=e("./kernel-value/single-array1d-i"),{WebGLKernelValueDynamicSingleArray1DI:A}=e("./kernel-value/dynamic-single-array1d-i"),{WebGLKernelValueSingleArray2DI:S}=e("./kernel-value/single-array2d-i"),{WebGLKernelValueDynamicSingleArray2DI:E}=e("./kernel-value/dynamic-single-array2d-i"),{WebGLKernelValueSingleArray3DI:_}=e("./kernel-value/single-array3d-i"),{WebGLKernelValueDynamicSingleArray3DI:v}=e("./kernel-value/dynamic-single-array3d-i"),{WebGLKernelValueSingleArray2:D}=e("./kernel-value/single-array2"),{WebGLKernelValueSingleArray3:w}=e("./kernel-value/single-array3"),{WebGLKernelValueSingleArray4:$}=e("./kernel-value/single-array4"),{WebGLKernelValueUnsignedArray:I}=e("./kernel-value/unsigned-array"),{WebGLKernelValueDynamicUnsignedArray:R}=e("./kernel-value/dynamic-unsigned-array"),F={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:R,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:d,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:m,HTMLImage:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:I,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:p,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLImage:a,HTMLImageArray:!1,HTMLVideo:u}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:T,"Array(2)":D,"Array(3)":w,"Array(4)":$,"Array1D(2)":A,"Array1D(3)":A,"Array1D(4)":A,"Array2D(2)":E,"Array2D(3)":E,"Array2D(4)":E,"Array3D(2)":v,"Array3D(3)":v,"Array3D(4)":v,Input:h,NumberTexture:f,"ArrayTexture(1)":f,"ArrayTexture(2)":f,"ArrayTexture(3)":f,"ArrayTexture(4)":f,MemoryOptimizedNumberTexture:m,HTMLImage:o,HTMLImageArray:!1,HTMLVideo:l},static:{Boolean:r,Float:i,Integer:s,Array:y,"Array(2)":D,"Array(3)":w,"Array(4)":$,"Array1D(2)":b,"Array1D(3)":b,"Array1D(4)":b,"Array2D(2)":S,"Array2D(3)":S,"Array2D(4)":S,"Array3D(2)":_,"Array3D(3)":_,"Array3D(4)":_,Input:c,NumberTexture:x,"ArrayTexture(1)":x,"ArrayTexture(2)":x,"ArrayTexture(3)":x,"ArrayTexture(4)":x,MemoryOptimizedNumberTexture:g,HTMLImage:a,HTMLImageArray:!1,HTMLVideo:u}}};t.exports={lookupKernelValueType:function(e,t,n,r){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!n)throw new Error("precision missing");r.type&&(e=r.type);const i=F[n][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]},kernelValueMaps:F}},{"./kernel-value/boolean":38,"./kernel-value/dynamic-html-image":39,"./kernel-value/dynamic-html-video":40,"./kernel-value/dynamic-memory-optimized-number-texture":41,"./kernel-value/dynamic-number-texture":42,"./kernel-value/dynamic-single-array":43,"./kernel-value/dynamic-single-array1d-i":44,"./kernel-value/dynamic-single-array2d-i":45,"./kernel-value/dynamic-single-array3d-i":46,"./kernel-value/dynamic-single-input":47,"./kernel-value/dynamic-unsigned-array":48,"./kernel-value/dynamic-unsigned-input":49,"./kernel-value/float":50,"./kernel-value/html-image":51,"./kernel-value/html-video":52,"./kernel-value/integer":54,"./kernel-value/memory-optimized-number-texture":55,"./kernel-value/number-texture":56,"./kernel-value/single-array":57,"./kernel-value/single-array1d-i":58,"./kernel-value/single-array2":59,"./kernel-value/single-array2d-i":60,"./kernel-value/single-array3":61,"./kernel-value/single-array3d-i":62,"./kernel-value/single-array4":63,"./kernel-value/single-input":64,"./kernel-value/unsigned-array":65,"./kernel-value/unsigned-input":66}],38:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueBoolean:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const bool ${this.id} = ${e};\n`:`uniform bool ${this.id};\n`}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],39:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueHTMLImage:i}=e("./html-image");t.exports={WebGLKernelValueDynamicHTMLImage:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:n}=e;this.checkSize(t,n),this.dimensions=[t,n,1],this.textureSize=[t,n],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./html-image":51}],40:[function(e,t,n){const{WebGLKernelValueDynamicHTMLImage:r}=e("./dynamic-html-image");t.exports={WebGLKernelValueDynamicHTMLVideo:class extends r{}}},{"./dynamic-html-image":39}],41:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueMemoryOptimizedNumberTexture:i}=e("./memory-optimized-number-texture");t.exports={WebGLKernelValueDynamicMemoryOptimizedNumberTexture:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.checkSize(e.size[0],e.size[1]),this.dimensions=e.dimensions,this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./memory-optimized-number-texture":55}],42:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueNumberTexture:i}=e("./number-texture");t.exports={WebGLKernelValueDynamicNumberTexture:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./number-texture":56}],43:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleArray:i}=e("./single-array");t.exports={WebGLKernelValueDynamicSingleArray:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-array":57}],44:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleArray1DI:i}=e("./single-array1d-i");t.exports={WebGLKernelValueDynamicSingleArray1DI:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-array1d-i":58}],45:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleArray2DI:i}=e("./single-array2d-i");t.exports={WebGLKernelValueDynamicSingleArray2DI:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-array2d-i":60}],46:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleArray3DI:i}=e("./single-array3d-i");t.exports={WebGLKernelValueDynamicSingleArray3DI:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-array3d-i":62}],47:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueSingleInput:i}=e("./single-input");t.exports={WebGLKernelValueDynamicSingleInput:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,i]=e.size;this.dimensions=new Int32Array([t||1,n||1,i||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./single-input":64}],48:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueUnsignedArray:i}=e("./unsigned-array");t.exports={WebGLKernelValueDynamicUnsignedArray:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio));const t=this.getTransferArrayType(e);this.preUploadValue=new t(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./unsigned-array":65}],49:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueUnsignedInput:i}=e("./unsigned-input");t.exports={WebGLKernelValueDynamicUnsignedInput:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,i]=e.size;this.dimensions=new Int32Array([t||1,n||1,i||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio));const s=this.getTransferArrayType(e.value);this.preUploadValue=new s(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"./unsigned-input":66}],50:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueFloat:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?Number.isInteger(e)?`const float ${this.id} = ${e}.0;\n`:`const float ${this.id} = ${e};\n`:`uniform float ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1f(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],51:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueHTMLImage:class extends i{constructor(e,t){super(e,t);const{width:n,height:r}=e;this.checkSize(n,r),this.dimensions=[n,r,1],this.requestTexture(),this.textureSize=[n,r],this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue=e),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],52:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueHTMLImage:i}=e("./html-image");t.exports={WebGLKernelValueHTMLVideo:class extends i{}}},{"../../../utils":111,"./html-image":51}],53:[function(e,t,n){const{utils:r}=e("../../../utils"),{Input:i}=e("../../../input"),{KernelValue:s}=e("../../kernel-value");t.exports={WebGLKernelValue:class extends s{constructor(e,t){super(e,t),this.dimensionsId=null,this.sizeId=null,this.initialValueConstructor=e.constructor,this.onRequestTexture=t.onRequestTexture,this.onRequestIndex=t.onRequestIndex,this.uploadValue=null,this.textureSize=null,this.bitRatio=null}checkSize(e,t){if(!this.kernel.validate)return;const{maxTextureSize:n}=this.kernel.constructor.features;if(e>n||t>n)throw e>t?new Error(`Argument width of ${e} larger than maximum size of ${n} for your GPU`):new Error(`Argument height of ${t} larger than maximum size of ${n} for your GPU`)}requestTexture(){this.texture=this.onRequestTexture(),this.setupTexture()}setupTexture(){this.contextHandle=this.onRequestContextHandle(),this.index=this.onRequestIndex(),this.dimensionsId=this.id+"Dim",this.sizeId=this.id+"Size"}getTransferArrayType(e){if(Array.isArray(e[0]))return this.getTransferArrayType(e[0]);switch(e.constructor){case Array:case Int32Array:case Int16Array:case Int8Array:return Float32Array;case Uint8ClampedArray:case Uint8Array:case Uint16Array:case Uint32Array:case Float32Array:case Float64Array:return e.constructor}return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"),e.constructor}formatArrayTransfer(e,t,n){if(r.isArray(e[0])||this.optimizeFloatMemory){const n=new Float32Array(t);return r.flattenTo(e,n),n}switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:case Uint16Array:case Int16Array:case Float32Array:case Int32Array:{const i=new(n||e.constructor)(t);return r.flattenTo(e,i),i}default:{const n=new Float32Array(t);return r.flattenTo(e,n),n}}}getBitRatio(e){if(Array.isArray(e[0]))return this.getBitRatio(e[0]);if(e.constructor===i)return this.getBitRatio(e.value);switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:return 1;case Uint16Array:case Int16Array:return 2;case Float32Array:case Int32Array:default:return 4}}getStringValueHandler(){throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`)}getVariablePrecisionString(){switch(this.tactic){case"speed":return"lowp";case"performance":return"highp";case"balanced":default:return"mediump"}}}}},{"../../../input":107,"../../../utils":111,"../../kernel-value":33}],54:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueInteger:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?`const int ${this.id} = ${parseInt(e)};\n`:`uniform int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],55:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueMemoryOptimizedNumberTexture:class extends i{constructor(e,t){super(e,t);const[n,r]=e.size;this.checkSize(n,r),this.setupTexture(),this.dimensions=e.dimensions,this.textureSize=e.size,this.uploadValue=e.texture,this.forceUploadEachRun=!0}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.uploadValue=e.texture),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],56:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueNumberTexture:class extends i{constructor(e,t){super(e,t);const[n,r]=e.size;this.checkSize(n,r),this.setupTexture();const{size:i,dimensions:s}=e;this.bitRatio=this.getBitRatio(e),this.dimensions=s,this.textureSize=i,this.uploadValue=e.texture,this.forceUploadEachRun=!0}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.uploadValue=e.texture),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],57:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],58:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray1DI:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],1,1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flatten2dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],59:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray2:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec2 ${this.id} = vec2(${e[0]},${e[1]});\n`:`uniform vec2 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform2fv(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],60:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray2DI:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flatten3dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],61:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray3:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec3 ${this.id} = vec3(${e[0]},${e[1]},${e[2]});\n`:`uniform vec3 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform3fv(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],62:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray3DI:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=r.getDimensions(e,!0);this.textureSize=r.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],t[3]]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flatten4dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],63:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleArray4:class extends i{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec4 ${this.id} = vec4(${e[0]},${e[1]},${e[2]},${e[3]});\n`:`uniform vec4 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform4fv(this.id,this.uploadValue=e)}}}},{"../../../utils":111,"./index":53}],64:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueSingleInput:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4;let[n,i,s]=e.size;this.dimensions=new Int32Array([n||1,i||1,s||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return r.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}.value, uploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],65:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueUnsignedArray:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=this.getBitRatio(e),this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio)),this.TranserArrayType=this.getTransferArrayType(e),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flattenTo(e,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],66:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("./index");t.exports={WebGLKernelValueUnsignedInput:class extends i{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=this.getBitRatio(e);const[n,i,s]=e.size;this.dimensions=new Int32Array([n||1,i||1,s||1]),this.textureSize=r.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio)),this.TranserArrayType=this.getTransferArrayType(e.value),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return r.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}.value, preUploadValue_${this.name})`])}getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;r.flattenTo(e.value,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}}},{"../../../utils":111,"./index":53}],67:[function(e,t,n){const{GLKernel:r}=e("../gl/kernel"),{FunctionBuilder:i}=e("../function-builder"),{WebGLFunctionNode:s}=e("./function-node"),{utils:a}=e("../../utils"),o=e("../../plugins/triangle-noise"),{fragmentShader:u}=e("./fragment-shader"),{vertexShader:l}=e("./vertex-shader"),{glKernelString:c}=e("../gl/kernel-string"),{lookupKernelValueType:h}=e("./kernel-value-maps");let p=null,d=null,g=null,m=null,x=null;const f=[o],y=[],T={};t.exports={WebGLKernel:class extends r{static get isSupported(){return null!==p?p:(this.setupFeatureChecks(),p=this.isContextMatch(g))}static setupFeatureChecks(){"undefined"!=typeof document?d=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(d=new OffscreenCanvas(0,0)),d&&(g=d.getContext("webgl")||d.getContext("experimental-webgl"))&&g.getExtension&&(m={OES_texture_float:g.getExtension("OES_texture_float"),OES_texture_float_linear:g.getExtension("OES_texture_float_linear"),OES_element_index_uint:g.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:g.getExtension("WEBGL_draw_buffers")},x=this.getFeatures())}static isContextMatch(e){return"undefined"!=typeof WebGLRenderingContext&&e instanceof WebGLRenderingContext}static getFeatures(){const e=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:e,kernelMap:e,channelCount:this.getChannelCount(),maxTextureSize:this.getMaxTextureSize()})}static getIsTextureFloat(){return Boolean(m.OES_texture_float)}static getIsDrawBuffers(){return Boolean(m.WEBGL_draw_buffers)}static getChannelCount(){return m.WEBGL_draw_buffers?g.getParameter(m.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static getMaxTextureSize(){return g.getParameter(g.MAX_TEXTURE_SIZE)}static lookupKernelValueType(e,t,n,r){return h(e,t,n,r)}static get testCanvas(){return d}static get testContext(){return g}static get features(){return x}static get fragmentShader(){return u}static get vertexShader(){return l}constructor(e,t){super(e,t),this.program=null,this.pipeline=t.pipeline,this.endianness=a.systemEndianness(),this.extensions={},this.subKernelOutputTextures=null,this.kernelArguments=null,this.argumentTextureCount=0,this.constantTextureCount=0,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.fragShader=null,this.vertShader=null,this.drawBuffersMap=null,this.outputTexture=null,this.maxTexSize=null,this.switchingKernels=!1,this.onRequestSwitchKernel=null,this.mergeSettings(e.settings||t),this.threadDim=null,this.framebuffer=null,this.buffer=null,this.textureCache={},this.programUniformLocationCache={},this.uniform1fCache={},this.uniform1iCache={},this.uniform2fCache={},this.uniform2fvCache={},this.uniform2ivCache={},this.uniform3fvCache={},this.uniform3ivCache={},this.uniform4fvCache={},this.uniform4ivCache={}}initCanvas(){if("undefined"!=typeof document){const e=document.createElement("canvas");return e.width=2,e.height=2,e}if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(0,0)}initContext(){const e={alpha:!1,depth:!1,antialias:!1};return this.canvas.getContext("webgl",e)||this.canvas.getContext("experimental-webgl",e)}initPlugins(e){const t=[],{source:n}=this;if("string"==typeof n)for(let e=0;ee===r.name)&&t.push(r)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(!this.graphical&&null===this.precision&&t.isTextureFloat&&(this.precision=t.isFloatRead?"single":"unsigned"),this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers)throw new Error("could not instantiate draw buffers extension");if(null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=a.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=a.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"precision"===this.precision&&(this.precision="unsigned",console.warn("Cannot use graphical mode and single precision at the same time")),void(this.texSize=a.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=a.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let n=y.indexOf(t);-1===n&&(n=y.length,y.push(t),T[n]=[e[0],e[1]]),this.maxTexSize=T[n]}this.maxTexSize[0]x.channelCount)throw new Error("Too many channels!");return this.translatedSource=t}setupArguments(e){this.kernelArguments=[],this.argumentTextureCount=0;const t=null===this.argumentTypes;if(t&&(this.argumentTypes=[]),this.argumentSizes=[],this.argumentBitRatios=[],e.lengththis.argumentNames.length)throw new Error("too many arguments for kernel");const{context:n}=this;let r=0;for(let i=0;ithis.context.createTexture(),onRequestIndex:()=>r++,onUpdateValueMismatch:()=>{this.switchingKernels=!0},onRequestContextHandle:()=>n.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++});this.kernelArguments.push(c),this.argumentSizes.push(c.textureSize),this.argumentBitRatios[i]=c.bitRatio}}setupConstants(e){const{context:t}=this;this.kernelConstants=[],this.forceUploadKernelConstants=[];let n=null===this.constantTypes;n&&(this.constantTypes={}),this.constantBitRatios={};let r=0;for(const i in this.constants){const s=this.constants[i];let o;n?(o=a.getVariableType(s,this.strictIntegers),this.constantTypes[i]=o):o=this.constantTypes[i];const u=this.constructor.lookupKernelValueType(o,"static",this.precision,s);if(null===u)return this.requestFallback(e);const l=new u(s,{name:i,type:o,tactic:this.tactic,origin:"constants",context:this.context,checkContext:this.checkContext,kernel:this,strictIntegers:this.strictIntegers,onRequestTexture:()=>this.context.createTexture(),onRequestIndex:()=>r++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[i]=l.bitRatio,this.kernelConstants.push(l),l.forceUploadEachRun&&this.forceUploadKernelConstants.push(l)}}build(){if(this.initExtensions(),this.validateSettings(arguments),this.setupConstants(arguments),this.fallbackRequested)return;if(this.setupArguments(arguments),this.fallbackRequested)return;this.updateMaxTexSize(),this.translateSource();const e=this.pickRenderStrategy(arguments);if(e)return e;const{texSize:t,context:n,canvas:r}=this;n.enable(n.SCISSOR_TEST),this.pipeline&&this.precision,n.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]),r.width=this.maxTexSize[0],r.height=this.maxTexSize[1];const i=this.threadDim=Array.from(this.output);for(;i.length<3;)i.push(1);const s=this.getVertexShader(arguments),a=n.createShader(n.VERTEX_SHADER);n.shaderSource(a,s),n.compileShader(a),this.vertShader=a;const o=this.getFragmentShader(arguments),u=n.createShader(n.FRAGMENT_SHADER);if(n.shaderSource(u,o),n.compileShader(u),this.fragShader=u,this.debug&&(console.log("GLSL Shader Output:"),console.log(o)),!n.getShaderParameter(a,n.COMPILE_STATUS))throw new Error("Error compiling vertex shader: "+n.getShaderInfoLog(a));if(!n.getShaderParameter(u,n.COMPILE_STATUS))throw new Error("Error compiling fragment shader: "+n.getShaderInfoLog(u));const l=this.program=n.createProgram();n.attachShader(l,a),n.attachShader(l,u),n.linkProgram(l),this.framebuffer=n.createFramebuffer(),this.framebuffer.width=t[0],this.framebuffer.height=t[1];const c=new Float32Array([-1,-1,1,-1,-1,1,1,1]),h=new Float32Array([0,0,1,0,0,1,1,1]),p=c.byteLength;let d=this.buffer;d?n.bindBuffer(n.ARRAY_BUFFER,d):(d=this.buffer=n.createBuffer(),n.bindBuffer(n.ARRAY_BUFFER,d),n.bufferData(n.ARRAY_BUFFER,c.byteLength+h.byteLength,n.STATIC_DRAW)),n.bufferSubData(n.ARRAY_BUFFER,0,c),n.bufferSubData(n.ARRAY_BUFFER,p,h);const g=n.getAttribLocation(this.program,"aPos");n.enableVertexAttribArray(g),n.vertexAttribPointer(g,2,n.FLOAT,!1,0,0);const m=n.getAttribLocation(this.program,"aTexCoord");n.enableVertexAttribArray(m),n.vertexAttribPointer(m,2,n.FLOAT,!1,0,p),n.bindFramebuffer(n.FRAMEBUFFER,this.framebuffer);let x=0;n.useProgram(this.program);for(let e in this.constants)this.kernelConstants[x++].updateValue(this.constants[e]);this.immutable||(this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&this._setupSubOutputTextures())}translateSource(){const e=i.fromKernel(this,s,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});if(this.translatedSource=e.getPrototypeString("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType()),this.subKernels&&this.subKernels.length>0)for(let t=0;te.source&&this.source.match(e.functionMatch)?e.source:"").join("\n"):"\n"}_getConstantsString(){const e=[],{threadDim:t,texSize:n}=this;return this.dynamicOutput?e.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize"):e.push(`ivec3 uOutputDim = ivec3(${t[0]}, ${t[1]}, ${t[2]})`,`ivec2 uTexSize = ivec2(${n[0]}, ${n[1]})`),a.linesToString(e)}_getTextureCoordinate(){const e=this.subKernels;return null===e||e.length<1?"varying vec2 vTexCoord;\n":"out vec2 vTexCoord;\n"}_getDecode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?"float div_with_int_check(float x, float y) {\n if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\n return float(int(x)/int(y));\n }\n return x / y;\n}":""}_getMainArgumentsString(e){const t=[],{argumentNames:n}=this;for(let r=0;r{if(t.hasOwnProperty(n))return t[n];throw`unhandled artifact ${n}`})}getFragmentShader(e){return null!==this.compiledFragmentShader?this.compiledFragmentShader:this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(e))}getVertexShader(e){return null!==this.compiledVertexShader?this.compiledVertexShader:this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(e))}toString(){const e=a.linesToString(["const gl = context"]);return c(this.constructor,arguments,this,e)}destroy(e){this.outputTexture&&this.context.deleteTexture(this.outputTexture),this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer),this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program);const t=Object.keys(this.textureCache);for(let e=0;e=0&&(y[e]=null,T[e]=null)}this.destroyExtensions(),delete this.context,delete this.canvas}destroyExtensions(){this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}toJSON(){const e=super.toJSON();return e.functionNodes=i.fromKernel(this,s).toJSON(),e}}}},{"../../plugins/triangle-noise":109,"../../utils":111,"../function-builder":8,"../gl/kernel":12,"../gl/kernel-string":11,"./fragment-shader":35,"./function-node":36,"./kernel-value-maps":37,"./vertex-shader":68}],68:[function(e,t,n){t.exports={vertexShader:"__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}"}},{}],69:[function(e,t,n){t.exports={fragmentShader:"#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n int result = 0;\n int n = 1;\n \n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n; \n }\n a = a / 2;\n n = n * 2;\n }\n return result;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x/y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n return texel[channel] * 255.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n\n mantissa = value*pow(2.0, -exponent)-1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n index = index / 4;\n vec4 texel = texture(tex, st / vec2(texSize));\n return texel[channel];\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}"}},{}],70:[function(e,t,n){const{WebGLFunctionNode:r}=e("../web-gl/function-node");t.exports={WebGL2FunctionNode:class extends r{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const n=this.getType(e);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===n&&this.argumentNames.indexOf(e.name)>-1?t.push(`bool(user_${e.name})`):t.push(`user_${e.name}`),t}}}},{"../web-gl/function-node":36}],71:[function(e,t,n){const{WebGL2KernelValueBoolean:r}=e("./kernel-value/boolean"),{WebGL2KernelValueFloat:i}=e("./kernel-value/float"),{WebGL2KernelValueInteger:s}=e("./kernel-value/integer"),{WebGL2KernelValueHTMLImage:a}=e("./kernel-value/html-image"),{WebGL2KernelValueDynamicHTMLImage:o}=e("./kernel-value/dynamic-html-image"),{WebGL2KernelValueHTMLImageArray:u}=e("./kernel-value/html-image-array"),{WebGL2KernelValueDynamicHTMLImageArray:l}=e("./kernel-value/dynamic-html-image-array"),{WebGL2KernelValueHTMLVideo:c}=e("./kernel-value/html-video"),{WebGL2KernelValueDynamicHTMLVideo:h}=e("./kernel-value/dynamic-html-video"),{WebGL2KernelValueSingleInput:p}=e("./kernel-value/single-input"),{WebGL2KernelValueDynamicSingleInput:d}=e("./kernel-value/dynamic-single-input"),{WebGL2KernelValueUnsignedInput:g}=e("./kernel-value/unsigned-input"),{WebGL2KernelValueDynamicUnsignedInput:m}=e("./kernel-value/dynamic-unsigned-input"),{WebGL2KernelValueMemoryOptimizedNumberTexture:x}=e("./kernel-value/memory-optimized-number-texture"),{WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:f}=e("./kernel-value/dynamic-memory-optimized-number-texture"),{WebGL2KernelValueNumberTexture:y}=e("./kernel-value/number-texture"),{WebGL2KernelValueDynamicNumberTexture:T}=e("./kernel-value/dynamic-number-texture"),{WebGL2KernelValueSingleArray:b}=e("./kernel-value/single-array"),{WebGL2KernelValueDynamicSingleArray:A}=e("./kernel-value/dynamic-single-array"),{WebGL2KernelValueSingleArray1DI:S}=e("./kernel-value/single-array1d-i"),{WebGL2KernelValueDynamicSingleArray1DI:E}=e("./kernel-value/dynamic-single-array1d-i"),{WebGL2KernelValueSingleArray2DI:_}=e("./kernel-value/single-array2d-i"),{WebGL2KernelValueDynamicSingleArray2DI:v}=e("./kernel-value/dynamic-single-array2d-i"),{WebGL2KernelValueSingleArray3DI:D}=e("./kernel-value/single-array3d-i"),{WebGL2KernelValueDynamicSingleArray3DI:w}=e("./kernel-value/dynamic-single-array3d-i"),{WebGL2KernelValueSingleArray2:$}=e("./kernel-value/single-array2"),{WebGL2KernelValueSingleArray3:I}=e("./kernel-value/single-array3"),{WebGL2KernelValueSingleArray4:R}=e("./kernel-value/single-array4"),{WebGL2KernelValueUnsignedArray:F}=e("./kernel-value/unsigned-array"),{WebGL2KernelValueDynamicUnsignedArray:k}=e("./kernel-value/dynamic-unsigned-array"),L={unsigned:{dynamic:{Boolean:r,Integer:s,Float:i,Array:k,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:m,NumberTexture:T,"ArrayTexture(1)":T,"ArrayTexture(2)":T,"ArrayTexture(3)":T,"ArrayTexture(4)":T,MemoryOptimizedNumberTexture:f,HTMLImage:o,HTMLImageArray:l,HTMLVideo:h},static:{Boolean:r,Float:i,Integer:s,Array:F,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:g,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:f,HTMLImage:a,HTMLImageArray:u,HTMLVideo:c}},single:{dynamic:{Boolean:r,Integer:s,Float:i,Array:A,"Array(2)":$,"Array(3)":I,"Array(4)":R,"Array1D(2)":E,"Array1D(3)":E,"Array1D(4)":E,"Array2D(2)":v,"Array2D(3)":v,"Array2D(4)":v,"Array3D(2)":w,"Array3D(3)":w,"Array3D(4)":w,Input:d,NumberTexture:T,"ArrayTexture(1)":T,"ArrayTexture(2)":T,"ArrayTexture(3)":T,"ArrayTexture(4)":T,MemoryOptimizedNumberTexture:f,HTMLImage:o,HTMLImageArray:l,HTMLVideo:h},static:{Boolean:r,Float:i,Integer:s,Array:b,"Array(2)":$,"Array(3)":I,"Array(4)":R,"Array1D(2)":S,"Array1D(3)":S,"Array1D(4)":S,"Array2D(2)":_,"Array2D(3)":_,"Array2D(4)":_,"Array3D(2)":D,"Array3D(3)":D,"Array3D(4)":D,Input:p,NumberTexture:y,"ArrayTexture(1)":y,"ArrayTexture(2)":y,"ArrayTexture(3)":y,"ArrayTexture(4)":y,MemoryOptimizedNumberTexture:x,HTMLImage:a,HTMLImageArray:u,HTMLVideo:c}}};t.exports={kernelValueMaps:L,lookupKernelValueType:function(e,t,n,r){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!n)throw new Error("precision missing");r.type&&(e=r.type);const i=L[n][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]}}},{"./kernel-value/boolean":72,"./kernel-value/dynamic-html-image":74,"./kernel-value/dynamic-html-image-array":73,"./kernel-value/dynamic-html-video":75,"./kernel-value/dynamic-memory-optimized-number-texture":76,"./kernel-value/dynamic-number-texture":77,"./kernel-value/dynamic-single-array":78,"./kernel-value/dynamic-single-array1d-i":79,"./kernel-value/dynamic-single-array2d-i":80,"./kernel-value/dynamic-single-array3d-i":81,"./kernel-value/dynamic-single-input":82,"./kernel-value/dynamic-unsigned-array":83,"./kernel-value/dynamic-unsigned-input":84,"./kernel-value/float":85,"./kernel-value/html-image":87,"./kernel-value/html-image-array":86,"./kernel-value/html-video":88,"./kernel-value/integer":89,"./kernel-value/memory-optimized-number-texture":90,"./kernel-value/number-texture":91,"./kernel-value/single-array":92,"./kernel-value/single-array1d-i":93,"./kernel-value/single-array2":94,"./kernel-value/single-array2d-i":95,"./kernel-value/single-array3":96,"./kernel-value/single-array3d-i":97,"./kernel-value/single-array4":98,"./kernel-value/single-input":99,"./kernel-value/unsigned-array":100,"./kernel-value/unsigned-input":101}],72:[function(e,t,n){const{WebGLKernelValueBoolean:r}=e("../../web-gl/kernel-value/boolean");t.exports={WebGL2KernelValueBoolean:class extends r{}}},{"../../web-gl/kernel-value/boolean":38}],73:[function(e,t,n){const{WebGL2KernelValueHTMLImageArray:r}=e("./html-image-array");t.exports={WebGL2KernelValueDynamicHTMLImageArray:class extends r{getSource(){const e=this.getVariablePrecisionString();return utils.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:n}=e[0];this.checkSize(t,n),this.dimensions=[t,n,e.length],this.textureSize=[t,n],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"./html-image-array":86}],74:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicHTMLImage:i}=e("../../web-gl/kernel-value/dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLImage:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-html-image":39}],75:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueDynamicHTMLImage:i}=e("./dynamic-html-image");t.exports={WebGL2KernelValueDynamicHTMLVideo:class extends i{}}},{"../../../utils":111,"./dynamic-html-image":74}],76:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicMemoryOptimizedNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-memory-optimized-number-texture");t.exports={WebGL2KernelValueDynamicMemoryOptimizedNumberTexture:class extends i{getSource(){return r.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":41}],77:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicNumberTexture:i}=e("../../web-gl/kernel-value/dynamic-number-texture");t.exports={WebGL2KernelValueDynamicNumberTexture:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-number-texture":42}],78:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray:i}=e("../../web-gl2/kernel-value/single-array");t.exports={WebGL2KernelValueDynamicSingleArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=r.getDimensions(e,!0),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"../../web-gl2/kernel-value/single-array":92}],79:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray1DI:i}=e("../../web-gl2/kernel-value/single-array1d-i");t.exports={WebGL2KernelValueDynamicSingleArray1DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"../../web-gl2/kernel-value/single-array1d-i":93}],80:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray2DI:i}=e("../../web-gl2/kernel-value/single-array2d-i");t.exports={WebGL2KernelValueDynamicSingleArray2DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"../../web-gl2/kernel-value/single-array2d-i":95}],81:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleArray3DI:i}=e("../../web-gl2/kernel-value/single-array3d-i");t.exports={WebGL2KernelValueDynamicSingleArray3DI:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"../../web-gl2/kernel-value/single-array3d-i":97}],82:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGL2KernelValueSingleInput:i}=e("../../web-gl2/kernel-value/single-input");t.exports={WebGL2KernelValueDynamicSingleInput:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,n,i]=e.size;this.dimensions=new Int32Array([t||1,n||1,i||1]),this.textureSize=r.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}}},{"../../../utils":111,"../../web-gl2/kernel-value/single-input":99}],83:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedArray:i}=e("../../web-gl/kernel-value/dynamic-unsigned-array");t.exports={WebGL2KernelValueDynamicUnsignedArray:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-unsigned-array":48}],84:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueDynamicUnsignedInput:i}=e("../../web-gl/kernel-value/dynamic-unsigned-input");t.exports={WebGL2KernelValueDynamicUnsignedInput:class extends i{getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}}},{"../../../utils":111,"../../web-gl/kernel-value/dynamic-unsigned-input":49}],85:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValueFloat:i}=e("../../web-gl/kernel-value/float");t.exports={WebGL2KernelValueFloat:class extends i{}}},{"../../../utils":111,"../../web-gl/kernel-value/float":50}],86:[function(e,t,n){const{utils:r}=e("../../../utils"),{WebGLKernelValue:i}=e("../../web-gl/kernel-value/index");t.exports={WebGL2KernelValueHTMLImageArray:class extends i{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.requestTexture(),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){const e=this.getVariablePrecisionString();return r.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D_ARRAY,this.texture),t.texParameteri(t.TEXTURE_2D_ARRAY,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D_ARRAY,t.TEXTURE_MIN_FILTER,t.NEAREST),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage3D(t.TEXTURE_2D_ARRAY,0,t.RGBA,e[0].width,e[0].height,e.length,0,t.RGBA,t.UNSIGNED_BYTE,null);for(let n=0;n0)for(let t=0;te.isSupported)}static get isKernelMapSupported(){return c.some(e=>e.isSupported&&e.features.kernelMap)}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return u.isSupported}static get isWebGL2Supported(){return o.isSupported}static get isHeadlessGLSupported(){return a.isSupported}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return o.isSupported}static get isSinglePrecisionSupported(){return c.some(e=>e.isSupported&&e.features.isFloatRead&&e.features.isTextureFloat)}constructor(e){if(e=e||{},this.canvas=e.canvas||null,this.context=e.context||null,this.mode=e.mode,this.Kernel=null,this.kernels=[],this.functions=[],this.nativeFunctions=[],this.injectedNative=null,"dev"!==this.mode){if(this.chooseKernel(),e.functions)for(let t=0;tt.argumentTypes[e]));const u=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:d,onRequestFallback:o,onRequestSwitchKernel:function t(r,s){const a=new Array(r.length);for(let e=0;et.argumentTypes[e])),Array.isArray(arguments[0])){n.subKernels=[];const e=arguments[0];for(let t=0;t0)throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');n=n||{};const{argumentTypes:r,argumentNames:i}=this.Kernel.nativeFunctionArguments(t)||{};return this.nativeFunctions.push({name:e,source:t,settings:n,argumentTypes:r,argumentNames:i,returnType:n.returnType||this.Kernel.nativeFunctionReturnType(t)}),this}injectNative(e){return this.injectedNative=e,this}destroy(){this.kernels&&setTimeout(()=>{for(let e=0;ee[i]),t.__defineSetter__(i,t=>{e[i]=t})))}}t.exports={kernelRunShortcut:function(e){let t=function(){return e.build.apply(e,arguments),(t=e.renderKernels?function(){return e.run.apply(e,arguments),e.switchingKernels?(e.switchingKernels=!1,e.onRequestSwitchKernel(arguments,e)):e.renderKernels()}:e.renderOutput?function(){return e.run.apply(e,arguments),e.switchingKernels?(e.switchingKernels=!1,e.onRequestSwitchKernel(arguments,e)):e.renderOutput()}:function(){return e.run.apply(e,arguments)}).apply(e,arguments)};const n=function(){return t.apply(e,arguments)};return n.exec=function(){return new Promise((e,n)=>{try{e(t.apply(this,arguments))}catch(e){n(e)}})},n.replaceKernel=function(t){i(e=t,n),n.kernel=e},i(e,n),n.kernel=e,n}}},{"./utils":111}],109:[function(e,t,n){t.exports={name:"triangle-noise-noise",onBeforeRun:e=>{e.setUniform1f("triangle_noise_seed",Math.random())},functionMatch:"Math.random()",functionReplace:"n4rand(vTexCoord)",functionReturnType:"Number",source:"\n\nuniform highp float triangle_noise_seed;\nhighp float triangle_noise_shift = 0.000001;\n\n//https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0;1[\nfloat nrand( vec2 n )\n{\n return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);\n}\n//note: remaps v to [0;1] in interval [a;b]\nfloat remap( float a, float b, float v )\n{\n return clamp( (v-a) / (b-a), 0.0, 1.0 );\n}\n\nfloat n4rand( vec2 n )\n{\n float t = fract( triangle_noise_seed + triangle_noise_shift );\n float nrnd0 = nrand( n + 0.07*t );\n float nrnd1 = nrand( n + 0.11*t ); \n float nrnd2 = nrand( n + 0.13*t );\n float nrnd3 = nrand( n + 0.17*t );\n float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0;\n triangle_noise_shift = result + 0.000001;\n return result;\n}"}},{}],110:[function(e,t,n){t.exports={Texture:class{constructor(e){const{texture:t,size:n,dimensions:r,output:i,context:s,type:a="NumberTexture"}=e;if(!i)throw new Error('settings property "output" required.');if(!s)throw new Error('settings property "context" required.');this.texture=t,this.size=n,this.dimensions=r,this.output=i,this.context=s,this.kernel=null,this.type=a}toArray(){throw new Error(`Not implemented on ${this.constructor.name}`)}delete(){return this.context.deleteTexture(this.texture)}}}},{}],111:[function(e,t,n){const r=e("acorn"),{Input:i}=e("./input"),{Texture:s}=e("./texture"),a=/function ([^(]*)/,o=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,u=/([^\s,]+)/g,l={systemEndianness:()=>c,getSystemEndianness(){const e=new ArrayBuffer(4),t=new Uint32Array(e),n=new Uint8Array(e);if(t[0]=3735928559,239===n[0])return"LE";if(222===n[0])return"BE";throw new Error("unknown endianness")},isFunction:e=>"function"==typeof e,isFunctionString:e=>"string"==typeof e&&"function"===e.slice(0,"function".length).toLowerCase(),getFunctionNameFromString:e=>a.exec(e)[1].trim(),getFunctionBodyFromString:e=>e.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString(e){const t=e.replace(o,"");let n=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(u);return null===n&&(n=[]),n},clone(e){if(null===e||"object"!=typeof e||e.hasOwnProperty("isActiveClone"))return e;const t=e.constructor();for(let n in e)Object.prototype.hasOwnProperty.call(e,n)&&(e.isActiveClone=null,t[n]=l.clone(e[n]),delete e.isActiveClone);return t},isArray:e=>!isNaN(e.length),getVariableType(e,t){if(l.isArray(e))return"IMG"===e[0].nodeName?"HTMLImageArray":"Array";switch(e.constructor){case Boolean:return"Boolean";case Number:return t&&Number.isInteger(e)?"Integer":"Float";case s:return e.type;case i:return"Input"}switch(e.nodeName){case"IMG":return"HTMLImage";case"VIDEO":return"HTMLVideo"}return e.hasOwnProperty("type")?e.type:"Unknown"},getKernelTextureSize(e,t){let[n,r,i]=t,s=(n||1)*(r||1)*(i||1);return e.optimizeFloatMemory&&"single"===e.precision&&(n=s=Math.ceil(s/4)),r>1&&n*r===s?new Int32Array([n,r]):l.closestSquareDimensions(s)},closestSquareDimensions(e){const t=Math.sqrt(e);let n=Math.ceil(t),r=Math.floor(t);for(;n*rMath.floor((e+t-1)/t)*t,getDimensions(e,t){let n;if(l.isArray(e)){const t=[];let r=e;for(;l.isArray(r);)t.push(r.length),r=r[0];n=t.reverse()}else if(e instanceof s)n=e.output;else{if(!(e instanceof i))throw new Error(`Unknown dimensions of ${e}`);n=e.size}if(t)for(n=Array.from(n);n.length<3;)n.push(1);return new Int32Array(n)},flatten2dArrayTo(e,t){let n=0;for(let r=0;re.length>0?e.join(";\n")+";\n":"\n",warnDeprecated(e,t,n){n?console.warn(`You are using a deprecated ${e} "${t}". It has been replaced with "${n}". Fixing, but please upgrade as it will soon be removed.`):console.warn(`You are using a deprecated ${e} "${t}". It has been removed. Fixing, but please upgrade as it will soon be removed.`)},functionToIFunction(e,t){if(t=t||{},"string"!=typeof e&&"function"!=typeof e)throw new Error("source not a string or function");const n="string"==typeof e?e:e.toString();let r=[];return{source:n,argumentTypes:r=Array.isArray(t.argumentTypes)?t.argumentTypes:"object"==typeof t.argumentTypes?l.getArgumentNamesFromString(n).map(e=>t.argumentTypes[e])||[]:t.argumentTypes||[],returnType:t.returnType||null}},flipPixels:(e,t,n)=>{const r=n/2|0,i=4*t,s=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee.subarray(0,t),erect2DPackedFloat:(e,t,n)=>{const r=new Array(n);for(let i=0;i{const i=new Array(r);for(let s=0;se.subarray(0,t),erectMemoryOptimized2DFloat:(e,t,n)=>{const r=new Array(n);for(let i=0;i{const i=new Array(r);for(let s=0;s{const n=new Float32Array(t);let r=0;for(let i=0;i{const r=new Array(n);let i=0;for(let s=0;s{const i=new Array(r);let s=0;for(let a=0;a{const n=new Array(t),r=4*t;let i=0;for(let t=0;t{const r=new Array(n),i=4*t;for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const n=new Array(t),r=4*t;let i=0;for(let t=0;t{const r=4*t,i=new Array(n);for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const n=new Array(e),r=4*t;let i=0;for(let t=0;t{const r=4*t,i=new Array(n);for(let s=0;s{const i=4*t,s=new Array(r);for(let a=0;a{const{findDependency:n,thisLookup:i,doNotDefine:s}=t;let a=t.flattened;a||(a=t.flattened={});const o=r.parse(e),u=[];const c=function e(t){if(Array.isArray(t)){const n=[];for(let r=0;rt.id.properties.map(e))[0];if(/this/.test(n)){const e=[],n=r.map(i);for(let i=0;ie(t.id)).join(", ")} ] = ${e(t.declarations[0].init)}`}return s&&-1!==s.indexOf(t.declarations[0].id.name)?"":`${t.kind} ${t.declarations[0].id.name} = ${e(t.declarations[0].init)}`;case"CallExpression":if("subarray"===t.callee.property.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("gl"===t.callee.object.name||"context"===t.callee.object.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("ThisExpression"===t.callee.object.type)return u.push(n("this",t.callee.property.name)),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;if(t.callee.object.name){const r=n(t.callee.object.name,t.callee.property.name);return null===r?`${t.callee.object.name}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`:(u.push(r),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`)}if("MemberExpression"===t.callee.object.type)return`${e(t.callee.object)}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;throw new Error("unknown ast.callee");case"ReturnStatement":return`return ${e(t.argument)}`;case"BinaryExpression":return`(${e(t.left)}${t.operator}${e(t.right)})`;case"UnaryExpression":return t.prefix?`${t.operator} ${e(t.argument)}`:`${e(t.argument)} ${t.operator}`;case"ExpressionStatement":return`(${e(t.expression)})`;case"ArrowFunctionExpression":return`(${t.params.map(e).join(", ")}) => ${e(t.body)}`;case"Literal":return t.raw;case"Identifier":return t.name;case"MemberExpression":return"ThisExpression"===t.object.type?i(t.property.name):t.computed?`${e(t.object)}[${e(t.property)}]`:e(t.object)+"."+e(t.property);case"ThisExpression":return"this";case"NewExpression":return`new ${e(t.callee)}(${t.arguments.map(t=>e(t)).join(", ")})`;case"ForStatement":return`for (${e(t.init)};${e(t.test)};${e(t.update)}) ${e(t.body)}`;case"AssignmentExpression":return`${e(t.left)}${t.operator}${e(t.right)}`;case"UpdateExpression":return`${e(t.argument)}${t.operator}`;case"IfStatement":return`if (${e(t.test)}) ${e(t.consequent)}`;case"ThrowStatement":return`throw ${e(t.argument)}`;case"ObjectPattern":return t.properties.map(e).join(", ");case"ArrayPattern":return t.elements.map(e).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${e(t.test)}?${e(t.consequent)}:${e(t.alternate)}`;case"Property":if("init"===t.kind)return e(t.key)}throw new Error(`unhandled ast.type of ${t.type}`)}(o);if(u.length>0){const e=[];for(let n=0;n{const n=new GPU({mode:t}),r=n.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].r},{output:[e.width,e.height],precision:"unsigned",argumentTypes:["HTMLImage"]}),i=n.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].g},{output:[e.width,e.height],precision:"unsigned",argumentTypes:["HTMLImage"]}),s=n.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].b},{output:[e.width,e.height],precision:"unsigned",argumentTypes:["HTMLImage"]}),a=n.createKernel(function(e){return 255*e[this.thread.y][this.thread.x].a},{output:[e.width,e.height],precision:"unsigned",argumentTypes:["HTMLImage"]}),o=[r(e),i(e),s(e),a(e)];return o.rKernel=r,o.gKernel=i,o.bKernel=s,o.aKernel=a,o.gpu=n,o},splitRGBAToCanvases:(t,n,r,i)=>{const{GPU:s}=e("./gpu.js"),a=new s({mode:i}),o=a.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(t.r/255,0,0,255)},{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});o(t);const u=new s({mode:i}),l=u.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,t.g/255,0,255)},{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});l(t);const c=new s({mode:i}),h=c.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(0,0,t.b/255,255)},{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});h(t);const p=new s({mode:i}),d=p.createKernel(function(e){const t=e[this.thread.y][this.thread.x];this.color(255,255,255,t.a/255)},{output:[n,r],graphical:!0,argumentTypes:{v:"Array2D(4)"}});return d(t),a.destroy(),u.destroy(),c.destroy(),p.destroy(),[o.canvas,l.canvas,h.canvas,d.canvas]}},c=l.getSystemEndianness();t.exports={utils:l}},{"./gpu.js":105,"./input":107,"./texture":110,acorn:1}]},{},[104])(104)}); \ No newline at end of file +var GPU=function(e){"use strict";function t(e){const t=new Array(e.length);for(let r=0;r{e.output=u(t),e.graphical&&o(e)},e.toJSON=()=>{throw new Error("Not usable with gpuMock")},e.setConstants=t=>(e.constants=t,e),e.setGraphical=t=>(e.graphical=t,e),e.setCanvas=t=>(e.canvas=t,e),e.setContext=t=>(e.context=t,e),e.exec=function(){return new Promise((t,r)=>{try{t(e.apply(e,arguments))}catch(e){r(e)}})},e.getPixels=t=>{const{x:r,y:n}=e.output;return t?function(e,t,r){const n=r/2|0,i=4*t,s=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee,e.setOptimizeFloatMemory=()=>e,e.setArgumentTypes=()=>e,e.setDebug=()=>e,e.setLoopMaxIterations=()=>e,e.setPipeline=()=>e,e.setPrecision=()=>e,e.setImmutable=()=>e,e.setFunctions=()=>e,e.addSubKernel=()=>e,e.destroy=()=>{},e.validateSettings=()=>{},e.graphical&&e.output&&o(e),e}function o(e){const{x:t,y:r}=e.output;if(e.context&&e.context.createImageData){const n=new Uint8ClampedArray(t*r*4);e._imageData=e.context.createImageData(t,r),e._colorData=n}else{const n=new Uint8ClampedArray(t*r*4);e._imageData={data:n},e._colorData=n}}function u(e){let t=null;if(e.length)if(3===e.length){const[r,n,i]=e;t={x:r,y:n,z:i}}else if(2===e.length){const[r,n]=e;t={x:r,y:n}}else{const[r]=e;t={x:r}}else t=e;return t}var l=function(e,t={}){const o=t.output?u(t.output):null;function l(){return l.output.z?s.apply(l,arguments):l.output.y?l.graphical?i.apply(l,arguments):n.apply(l,arguments):r.apply(l,arguments)}return l._fn=e,l.constants=t.constants||null,l.context=t.context||null,l.canvas=t.canvas||null,l.graphical=t.graphical||!1,l._imageData=null,l._colorData=null,l.output=o,l.thread={x:0,y:0,z:0},a(l)};const h=/([^\s,]+)/g,c=/function ([^(]*)/,p=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;function d(e){return"function"==typeof e}function m(e){return c.exec(e)[1].trim()}function g(e,t){if(t=t||{},"string"!=typeof e&&"function"!=typeof e)throw new Error("source not a string or function");const r="string"==typeof e?e:e.toString();let n=[];return{source:r,argumentTypes:n=Array.isArray(t.argumentTypes)?t.argumentTypes:"object"==typeof t.argumentTypes?y(r).map(e=>t.argumentTypes[e])||[]:t.argumentTypes||[],returnType:t.returnType||null}}function f(e,t,r){const n=r?`It has been replaced with "${r}"`:"It has been removed";console.warn(`You are using a deprecated ${e} "${t}". ${n}. Fixing, but please upgrade as it will soon be removed.`)}function x(e){return"string"==typeof e&&"function"===e.slice(0,"function".length).toLowerCase()}function y(e){const t=e.replace(p,"");let r=t.slice(t.indexOf("(")+1,t.indexOf(")")).match(h);return null===r&&(r=[]),r}function T(e){return!isNaN(e.length)}function b(e,t,r){const n=new Array(r);for(let i=0;ie.substring(e.indexOf("{")+1,e.lastIndexOf("}")),getArgumentNamesFromString:y,clone(e){if(null===e||"object"!=typeof e||e.hasOwnProperty("isActiveClone"))return e;const t=e.constructor();for(let r in e)Object.prototype.hasOwnProperty.call(e,r)&&(e.isActiveClone=null,t[r]=R.clone(e[r]),delete e.isActiveClone);return t},isArray:T,getVariableType:w,getKernelTextureSize(e,t){let[r,n,i]=t,s=(r||1)*(n||1)*(i||1);return e.optimizeFloatMemory&&"single"===e.precision&&(r=s=Math.ceil(s/4)),n>1&&r*n===s?new Int32Array([r,n]):R.closestSquareDimensions(s)},closestSquareDimensions(e){const t=Math.sqrt(e);let r=Math.ceil(t),n=Math.floor(t);for(;r*nMath.floor((e+t-1)/t)*t,getDimensions(e,t){let r;if(T(e)){const t=[];let n=e;for(;T(n);)t.push(n.length),n=n[0];r=t.reverse()}else if(e instanceof v)r=e.output;else{if(!(e instanceof _))throw new Error(`Unknown dimensions of ${e}`);r=e.size}if(t)for(r=Array.from(r);r.length<3;)r.push(1);return new Int32Array(r)},flatten2dArrayTo(e,t){let r=0;for(let n=0;ne.length>0?e.join(";\n")+";\n":"\n",warnDeprecated:f,functionToIFunction:g,flipPixels(e,t,r){const n=r/2|0,i=4*t,s=new Uint8ClampedArray(4*t),a=e.slice(0);for(let e=0;ee.subarray(0,t),erect2DPackedFloat:(e,t,r)=>{const n=new Array(r);for(let i=0;i{const i=new Array(n);for(let s=0;se.subarray(0,t),erectMemoryOptimized2DFloat:b,erectMemoryOptimized3DFloat:A,erectFloat:(e,t)=>{const r=new Float32Array(t);let n=0;for(let i=0;i{const n=new Array(r);let i=0;for(let s=0;s{const i=new Array(n);let s=0;for(let a=0;a{const r=new Array(t),n=4*t;let i=0;for(let t=0;t{const n=new Array(r),i=4*t;for(let s=0;s{const i=4*t,s=new Array(n);for(let a=0;a{const r=new Array(t),n=4*t;let i=0;for(let t=0;t{const n=4*t,i=new Array(r);for(let s=0;s{const i=4*t,s=new Array(n);for(let a=0;a{const r=new Array(e),n=4*t;let i=0;for(let t=0;t{const n=4*t,i=new Array(r);for(let s=0;s{const i=4*t,s=new Array(n);for(let a=0;a{const{findDependency:n,thisLookup:i,doNotDefine:s}=r;let a=r.flattened;a||(a=r.flattened={});const o=e.parse(t),u=[];const l=function e(t){if(Array.isArray(t)){const r=[];for(let n=0;nt.id.properties.map(e))[0];if(/this/.test(r)){const e=[],r=n.map(i);for(let i=0;ie(t.id)).join(", ")} ] = ${e(t.declarations[0].init)}`}return s&&-1!==s.indexOf(t.declarations[0].id.name)?"":`${t.kind} ${t.declarations[0].id.name} = ${e(t.declarations[0].init)}`;case"CallExpression":if("subarray"===t.callee.property.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("gl"===t.callee.object.name||"context"===t.callee.object.name)return`${e(t.callee.object)}.${e(t.callee.property)}(${t.arguments.map(t=>e(t)).join(", ")})`;if("ThisExpression"===t.callee.object.type)return u.push(n("this",t.callee.property.name)),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;if(t.callee.object.name){const r=n(t.callee.object.name,t.callee.property.name);return null===r?`${t.callee.object.name}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`:(u.push(r),`${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`)}if("MemberExpression"===t.callee.object.type)return`${e(t.callee.object)}.${t.callee.property.name}(${t.arguments.map(t=>e(t)).join(", ")})`;throw new Error("unknown ast.callee");case"ReturnStatement":return`return ${e(t.argument)}`;case"BinaryExpression":return`(${e(t.left)}${t.operator}${e(t.right)})`;case"UnaryExpression":return t.prefix?`${t.operator} ${e(t.argument)}`:`${e(t.argument)} ${t.operator}`;case"ExpressionStatement":return`(${e(t.expression)})`;case"ArrowFunctionExpression":return`(${t.params.map(e).join(", ")}) => ${e(t.body)}`;case"Literal":return t.raw;case"Identifier":return t.name;case"MemberExpression":return"ThisExpression"===t.object.type?i(t.property.name):t.computed?`${e(t.object)}[${e(t.property)}]`:e(t.object)+"."+e(t.property);case"ThisExpression":return"this";case"NewExpression":return`new ${e(t.callee)}(${t.arguments.map(t=>e(t)).join(", ")})`;case"ForStatement":return`for (${e(t.init)};${e(t.test)};${e(t.update)}) ${e(t.body)}`;case"AssignmentExpression":return`${e(t.left)}${t.operator}${e(t.right)}`;case"UpdateExpression":return`${e(t.argument)}${t.operator}`;case"IfStatement":return`if (${e(t.test)}) ${e(t.consequent)}`;case"ThrowStatement":return`throw ${e(t.argument)}`;case"ObjectPattern":return t.properties.map(e).join(", ");case"ArrayPattern":return t.elements.map(e).join(", ");case"DebuggerStatement":return"debugger;";case"ConditionalExpression":return`${e(t.test)}?${e(t.consequent)}:${e(t.alternate)}`;case"Property":if("init"===t.kind)return e(t.key)}throw new Error(`unhandled ast.type of ${t.type}`)}(o);if(u.length>0){const e=[];for(let t=0;tg(e));continue}break;case"graphical":e[t]&&!e.hasOwnProperty("precision")&&(this.precision="unsigned"),this[t]=e[t];continue}this[t]=e[t]}this.canvas||(this.canvas=this.initCanvas()),this.context||(this.context=this.initContext()),this.plugins||(this.plugins=this.initPlugins(e))}build(){throw new Error(`"build" not defined on ${this.constructor.name}`)}run(){throw new Error(`"run" not defined on ${this.constructor.name}`)}initCanvas(){throw new Error(`"initCanvas" not defined on ${this.constructor.name}`)}initContext(){throw new Error(`"initContext" not defined on ${this.constructor.name}`)}initPlugins(e){throw new Error(`"initPlugins" not defined on ${this.constructor.name}`)}setupArguments(e){if(this.kernelArguments=[],this.argumentTypes)for(let e=0;eg(e)):this.functions=e,this}setNativeFunctions(e){return this.nativeFunctions=e,this}setInjectedNative(e){return this.injectedNative=e,this}setPipeline(e){return this.pipeline=e,this}setPrecision(e){return this.precision=e,this}setOutputToTexture(e){return f("method","setOutputToTexture","setPipeline"),this.pipeline=e,this}setImmutable(e){return this.immutable=e,this}setCanvas(e){return this.canvas=e,this}setStrictIntegers(e){return this.strictIntegers=e,this}setDynamicOutput(e){return this.dynamicOutput=e,this}setHardcodeConstants(e){return f("method","setHardcodeConstants"),this.setDynamicOutput(e),this.setDynamicArguments(e),this}setDynamicArguments(e){return this.dynamicArguments=e,this}setUseLegacyEncoder(e){return this.useLegacyEncoder=e,this}setWarnVarUsage(e){return this.warnVarUsage=e,this}getCanvas(){return f("method","getCanvas"),this.canvas}getWebGl(){return f("method","getWebGl"),this.context}setContext(e){return this.context=e,this}setArgumentTypes(e){if(Array.isArray(e))this.argumentTypes=e;else{this.argumentTypes=[];for(const t in e){const r=this.argumentNames.indexOf(t);if(-1===r)throw new Error(`unable to find argument ${t}`);this.argumentTypes[r]=e[t]}}return this}setTactic(e){return this.tactic=e,this}requestFallback(e){if(!this.onRequestFallback)throw new Error(`"onRequestFallback" not defined on ${this.constructor.name}`);return this.fallbackRequested=!0,this.onRequestFallback(e)}validateSettings(){throw new Error(`"validateSettings" not defined on ${this.constructor.name}`)}addSubKernel(e){if(null===this.subKernels&&(this.subKernels=[]),!e.source)throw new Error('subKernel missing "source" property');if(!e.property&&isNaN(e.property))throw new Error('subKernel missing "property" property');if(!e.name)throw new Error('subKernel missing "name" property');return this.subKernels.push(e),this}destroy(e){throw new Error(`"destroy" called on ${this.constructor.name}`)}getBitRatio(e){if("single"===this.precision)return 4;if(Array.isArray(e[0]))return this.getBitRatio(e[0]);if(e.constructor===_)return this.getBitRatio(e.value);switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:return 1;case Uint16Array:case Int16Array:return 2;case Float32Array:case Int32Array:default:return 4}}getPixels(){throw new Error(`"getPixels" called on ${this.constructor.name}`)}checkOutput(){if(!this.output||!T(this.output))throw new Error("kernel.output not an array");if(this.output.length<1)throw new Error("kernel.output is empty, needs at least 1 value");for(let e=0;ee.name):null,returnType:this.returnType}}}}class F{static fromKernel(e,t,r){const{kernelArguments:n,kernelConstants:i,argumentNames:s,argumentSizes:a,argumentBitRatios:o,constants:u,constantBitRatios:l,debug:h,loopMaxIterations:c,nativeFunctions:p,output:d,optimizeFloatMemory:m,precision:g,plugins:f,source:x,subKernels:y,functions:T,leadingReturnStatement:b,followingReturnStatement:A,dynamicArguments:E,dynamicOutput:S,warnVarUsage:_}=e,v=new Array(n.length),D={};for(let e=0;eG.needsArgumentType(e,t),w=(e,t,r)=>{G.assignArgumentType(e,t,r)},R=(e,t,r)=>G.lookupReturnType(e,t,r),I=e=>G.lookupFunctionArgumentTypes(e),z=(e,t)=>G.lookupFunctionArgumentName(e,t),O=(e,t)=>G.lookupFunctionArgumentBitRatio(e,t),C=(e,t,r,n)=>{G.assignArgumentType(e,t,r,n)},N=(e,t,r,n)=>{G.trackArgumentSynonym(e,t,r,n)},k=(e,t,r)=>G.lookupArgumentSynonym(e,t,r),M=(e,t,r)=>{G.trackFunctionCall(e,t,r)},U=Object.assign({isRootKernel:!1,onNestedFunction:(e,r)=>{const n=[];for(let t=0;tnew t(e.source,{returnType:e.returnType,argumentTypes:e.argumentTypes,output:d,plugins:f,constants:u,constantTypes:D,constantBitRatios:l,optimizeFloatMemory:m,precision:g,lookupReturnType:R,lookupFunctionArgumentTypes:I,lookupFunctionArgumentName:z,lookupFunctionArgumentBitRatio:O,needsArgumentType:$,assignArgumentType:w,triggerImplyArgumentType:C,triggerTrackArgumentSynonym:N,lookupArgumentSynonym:k,onFunctionCall:M})));let K=null;y&&(K=y.map(e=>{const{name:r,source:n}=e;return new t(n,Object.assign({},U,{name:r,isSubKernel:!0,isRootKernel:!1}))}));const G=new F({kernel:e,rootNode:L,functionNodes:V,nativeFunctions:p,subKernelNodes:K});return G}constructor(e){if(e=e||{},this.kernel=e.kernel,this.rootNode=e.rootNode,this.functionNodes=e.functionNodes||[],this.subKernelNodes=e.subKernelNodes||[],this.nativeFunctions=e.nativeFunctions||[],this.functionMap={},this.nativeFunctionNames=[],this.lookupChain=[],this.argumentChain=[],this.functionNodeDependencies={},this.functionCalls={},this.rootNode&&(this.functionMap.kernel=this.rootNode),this.functionNodes)for(let e=0;e-1)return-1===t.indexOf(e)&&t.push(e),t;const r=this.functionMap[e];if(r){const n=t.indexOf(e);if(-1===n){t.push(e),r.toString();for(let e=0;e-1){t.push(this.nativeFunctions[i].source);continue}const s=this.functionMap[n];s&&t.push(s.toString())}return t}toJSON(){return this.traceFunctionCalls(this.rootNode.name).reverse().map(e=>{const t=this.nativeFunctions.indexOf(e);if(t>-1)return{name:e,source:this.nativeFunctions[t].source};if(this.functionMap[e])return this.functionMap[e].toJSON();throw new Error(`function ${e} not found`)})}fromJSON(e,t){this.functionMap={};for(let r=0;r0){const i=t.arguments;for(let t=0;t0?this.runningContexts[this.runningContexts.length-1]:null}newContext(e){const t=Object.assign({},this.currentContext);this.contexts.push(t),this.runningContexts.push(t),e(),this.runningContexts.pop()}scan(e){if(Array.isArray(e))for(let t=0;t{this.scan(e.body)});break;case"AssignmentExpression":case"LogicalExpression":case"BinaryExpression":this.scan(e.left),this.scan(e.right);break;case"UpdateExpression":case"UnaryExpression":this.scan(e.argument);break;case"VariableDeclaration":this.scan(e.declarations);break;case"VariableDeclarator":const{currentContext:t}=this,r={ast:e,context:t,name:e.id.name,origin:"declaration",forceInteger:this.inLoopInit,assignable:!this.inLoopInit&&!t.hasOwnProperty(e.id.name)};t[e.id.name]=r,this.declarations.push(r),this.scan(e.id),this.scan(e.init);break;case"FunctionExpression":case"FunctionDeclaration":0===this.runningContexts.length?this.scan(e.body):this.functions.push(e);break;case"IfStatement":this.scan(e.test),this.scan(e.consequent),e.alternate&&this.scan(e.alternate);break;case"ForStatement":this.newContext(()=>{this.inLoopInit=!0,this.scan(e.init),this.inLoopInit=!1,this.scan(e.test),this.scan(e.update),this.newContext(()=>{this.scan(e.body)})});break;case"DoWhileStatement":case"WhileStatement":this.newContext(()=>{this.scan(e.body),this.scan(e.test)});break;case"Identifier":this.identifiers.push({context:this.currentContext,ast:e});break;case"ReturnStatement":this.returnStatements.push(e),this.scan(e.argument);break;case"MemberExpression":this.scan(e.object),this.scan(e.property);break;case"ExpressionStatement":this.scan(e.expression);break;case"CallExpression":this.functionCalls.push({context:this.currentContext,ast:e}),this.scan(e.arguments);break;case"ArrayExpression":this.scan(e.elements);break;case"ConditionalExpression":this.scan(e.test),this.scan(e.alternate),this.scan(e.consequent);break;case"SwitchStatement":this.scan(e.discriminant),this.scan(e.cases);break;case"SwitchCase":this.scan(e.test),this.scan(e.consequent);break;case"ThisExpression":this.scan(e.left),this.scan(e.right);break;case"Literal":case"DebuggerStatement":case"EmptyStatement":case"BreakStatement":case"ContinueStatement":break;default:throw new Error(`unhandled type "${e.type}"`)}}}class O{constructor(e,t){if(!e&&!t.ast)throw new Error("source parameter is missing");if(t=t||{},this.source=e,this.ast=null,this.name="string"==typeof e?t.isRootKernel?"kernel":t.name||m(e):null,this.calledFunctions=[],this.constants={},this.constantTypes={},this.constantBitRatios={},this.isRootKernel=!1,this.isSubKernel=!1,this.debug=null,this.declarations=null,this.functions=null,this.identifiers=null,this.contexts=null,this.functionCalls=null,this.states=[],this.needsArgumentType=null,this.assignArgumentType=null,this.lookupReturnType=null,this.lookupFunctionArgumentTypes=null,this.lookupFunctionArgumentBitRatio=null,this.triggerImplyArgumentType=null,this.triggerImplyArgumentBitRatio=null,this.onNestedFunction=null,this.onFunctionCall=null,this.optimizeFloatMemory=null,this.precision=null,this.loopMaxIterations=null,this.argumentNames="string"==typeof this.source?y(this.source):null,this.argumentTypes=[],this.argumentSizes=[],this.argumentBitRatios=null,this.returnType=null,this.output=[],this.plugins=null,this.leadingReturnStatement=null,this.followingReturnStatement=null,this.dynamicOutput=null,this.dynamicArguments=null,this.strictTypingChecking=!1,this.fixIntegerDivisionAccuracy=null,this.warnVarUsage=!0,t)for(const e in t)t.hasOwnProperty(e)&&this.hasOwnProperty(e)&&(this[e]=t[e]);this.literalTypes={},this.validate(),this._string=null,this._internalVariableNames={}}validate(){if("string"!=typeof this.source&&!this.ast)throw new Error("this.source not a string");if(!this.ast&&!x(this.source))throw new Error("this.source not a function string");if(!this.name)throw new Error("this.name could not be set");if(this.argumentTypes.length>0&&this.argumentTypes.length!==this.argumentNames.length)throw new Error(`argumentTypes count of ${this.argumentTypes.length} exceeds ${this.argumentNames.length}`);if(this.output.length<1)throw new Error("this.output is not big enough")}isIdentifierConstant(e){return!!this.constants&&this.constants.hasOwnProperty(e)}isInput(e){return"Input"===this.argumentTypes[this.argumentNames.indexOf(e)]}pushState(e){this.states.push(e)}popState(e){if(this.state!==e)throw new Error(`Cannot popState ${e} when in ${this.state}`);this.states.pop()}isState(e){return this.state===e}get state(){return this.states[this.states.length-1]}astMemberExpressionUnroll(e){if("Identifier"===e.type)return e.name;if("ThisExpression"===e.type)return"this";if("MemberExpression"===e.type&&e.object&&e.property)return e.object.hasOwnProperty("name")&&"_"===e.object.name[0]?this.astMemberExpressionUnroll(e.property):this.astMemberExpressionUnroll(e.object)+"."+this.astMemberExpressionUnroll(e.property);if(e.hasOwnProperty("expressions")){const t=e.expressions[0];if("Literal"===t.type&&0===t.value&&2===e.expressions.length)return this.astMemberExpressionUnroll(e.expressions[1])}throw this.astErrorOutput("Unknown astMemberExpressionUnroll",e)}getJsAST(t){if(this.ast)return this.ast;if("object"==typeof this.source)return this.traceFunctionAST(this.source),this.ast=this.source;const r=t&&t.hasOwnProperty("parse")?t.parse:e.parse;if(null===t)throw new Error("Missing JS to AST parser");const n=Object.freeze(r(`const parser_${this.name} = ${this.source};`,{locations:!0})),i=n.body[0].declarations[0].init;if(this.traceFunctionAST(i),!n)throw new Error("Failed to parse JS code");return this.ast=i}traceFunctionAST(e){const{contexts:t,declarations:r,functions:n,identifiers:i,functionCalls:s}=new z(e);this.contexts=t,this.identifiers=i,this.functionCalls=s,this.declarations=[],this.functions=n;for(let e=0;e":case"<":return"Boolean";case"&":case"|":case"^":case"<<":case">>":case">>>":return"Integer"}const r=this.getType(e.left);if(this.isState("skip-literal-correction"))return r;if("LiteralInteger"===r){const t=this.getType(e.right);return"LiteralInteger"===t?e.left.value%1==0?"Integer":"Float":t}return C[r]||r;case"UpdateExpression":return this.getType(e.argument);case"UnaryExpression":return"~"===e.operator?"Integer":this.getType(e.argument);case"VariableDeclaration":{const t=e.declarations;let r;for(let e=0;e-1}isAstMathFunction(e){return"CallExpression"===e.type&&e.callee&&"MemberExpression"===e.callee.type&&e.callee.object&&"Identifier"===e.callee.object.type&&"Math"===e.callee.object.name&&e.callee.property&&"Identifier"===e.callee.property.type&&["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","log2","max","min","pow","random","round","sign","sin","sqrt","tan"].indexOf(e.callee.property.name)>-1}isAstVariable(e){return"Identifier"===e.type||"MemberExpression"===e.type}isSafe(e){return this.isSafeDependencies(this.getDependencies(e))}isSafeDependencies(e){return!e||!e.every||e.every(e=>e.isSafe)}getDependencies(e,t,r){if(t||(t=[]),!e)return null;if(Array.isArray(e)){for(let n=0;n-1/0&&e.value<1/0&&!isNaN(e.value))});break;case"VariableDeclarator":return this.getDependencies(e.init,t,r);case"Identifier":const n=this.getDeclaration(e);if(n)t.push({name:e.name,origin:"declaration",isSafe:!r&&this.isSafeDependencies(n.dependencies)});else if(this.argumentNames.indexOf(e.name)>-1)t.push({name:e.name,origin:"argument",isSafe:!1});else if(this.strictTypingChecking)throw new Error(`Cannot find identifier origin "${e.name}"`);break;case"FunctionDeclaration":return this.getDependencies(e.body.body[e.body.body.length-1],t,r);case"ReturnStatement":return this.getDependencies(e.argument,t);case"BinaryExpression":return r="/"===e.operator||"*"===e.operator,this.getDependencies(e.left,t,r),this.getDependencies(e.right,t,r),t;case"UnaryExpression":case"UpdateExpression":return this.getDependencies(e.argument,t,r);case"VariableDeclaration":return this.getDependencies(e.declarations,t,r);case"ArrayExpression":return t.push({origin:"declaration",isSafe:!0}),t;case"CallExpression":return t.push({origin:"function",isSafe:!0}),t;case"MemberExpression":const i=this.getMemberExpressionDetails(e);switch(i.signature){case"value[]":this.getDependencies(e.object,t,r);break;case"value[][]":this.getDependencies(e.object.object,t,r);break;case"value[][][]":this.getDependencies(e.object.object.object,t,r);break;case"this.output.value":this.dynamicOutput&&t.push({name:i.name,origin:"output",isSafe:!1})}if(i)return i.property&&this.getDependencies(i.property,t,r),i.xProperty&&this.getDependencies(i.xProperty,t,r),i.yProperty&&this.getDependencies(i.yProperty,t,r),i.zProperty&&this.getDependencies(i.zProperty,t,r),t;default:throw this.astErrorOutput(`Unhandled type ${e.type} in getDependencies`,e)}return t}getVariableSignature(e){if(!this.isAstVariable(e))throw new Error(`ast of type "${e.type}" is not a variable signature`);if("Identifier"===e.type)return"value";const t=[];for(;e;)e.computed?t.push("[]"):"ThisExpression"===e.type?t.unshift("this"):e.property&&e.property.name?"x"===e.property.name||"y"===e.property.name||"z"===e.property.name?t.unshift(".value"):"constants"===e.property.name||"thread"===e.property.name||"output"===e.property.name?t.unshift("."+e.property.name):t.unshift(".value"):e.name?t.unshift("value"):e.callee&&e.callee.name?t.unshift("fn()"):e.elements?t.unshift("[]"):t.unshift("unknown"),e=e.object;const r=t.join("");return["value","value[]","value[][]","value[][][]","value[][][][]","value.value","value.thread.value","this.thread.value","this.output.value","this.constants.value","this.constants.value[]","this.constants.value[][]","this.constants.value[][][]","this.constants.value[][][][]","fn()[]","fn()[][]","fn()[][][]","[][]"].indexOf(r)>-1?r:null}build(){return this.toString().length>0}astGeneric(e,t){if(null===e)throw this.astErrorOutput("NULL ast",e);if(Array.isArray(e)){for(let r=0;r0?n[n.length-1]:0;return new Error(`${e} on line ${n.length}, position ${i.length}:\n ${r}`)}astDebuggerStatement(e,t){return t}astConditionalExpression(e,t){if("ConditionalExpression"!==e.type)throw this.astErrorOutput("Not a conditional expression",e);return t.push("("),this.astGeneric(e.test,t),t.push("?"),this.astGeneric(e.consequent,t),t.push(":"),this.astGeneric(e.alternate,t),t.push(")"),t}astFunction(e,t){throw new Error(`"astFunction" not defined on ${this.constructor.name}`)}astFunctionDeclaration(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}astFunctionExpression(e,t){return this.isChildFunction(e)?t:this.astFunction(e,t)}isChildFunction(e){for(let t=0;t0&&t.push(","),this.astGeneric(e.expressions,t);return t}astUnaryExpression(e,t){return this.checkAndUpconvertBitwiseUnary(e,t)?t:(e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t)}checkAndUpconvertBitwiseUnary(e,t){}astUpdateExpression(e,t){return e.prefix?(t.push(e.operator),this.astGeneric(e.argument,t)):(this.astGeneric(e.argument,t),t.push(e.operator)),t}astLogicalExpression(e,t){return t.push("("),this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t.push(")"),t}astMemberExpression(e,t){return t}astCallExpression(e,t){return t}astArrayExpression(e,t){return t}getMemberExpressionDetails(e){if("MemberExpression"!==e.type)throw this.astErrorOutput(`Expression ${e.type} not a MemberExpression`,e);let t=null,r=null;const n=this.getVariableSignature(e);switch(n){case"value":return null;case"value.thread.value":case"this.thread.value":case"this.output.value":return{signature:n,type:"Integer",name:e.property.name};case"value[]":if("string"!=typeof e.object.name)throw this.astErrorOutput("Unexpected expression",e);return{name:t=e.object.name,origin:"user",signature:n,type:this.getVariableType(e.object),xProperty:e.property};case"value[][]":if("string"!=typeof e.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return{name:t=e.object.object.name,origin:"user",signature:n,type:this.getVariableType(e.object.object),yProperty:e.object.property,xProperty:e.property};case"value[][][]":if("string"!=typeof e.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return{name:t=e.object.object.object.name,origin:"user",signature:n,type:this.getVariableType(e.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value[][][][]":if("string"!=typeof e.object.object.object.object.name)throw this.astErrorOutput("Unexpected expression",e);return{name:t=e.object.object.object.object.name,origin:"user",signature:n,type:this.getVariableType(e.object.object.object.object),zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"value.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(this.isAstMathVariable(e))return{name:t=e.property.name,origin:"Math",type:"Number",signature:n};switch(e.property.name){case"r":case"g":case"b":case"a":return{name:t=e.object.name,property:e.property.name,origin:"user",signature:n,type:"Number"};default:throw this.astErrorOutput("Unexpected expression",e)}case"this.constants.value":if("string"!=typeof e.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.property.name,!(r=this.getConstantType(t)))throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n};case"this.constants.value[]":if("string"!=typeof e.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.property.name,!(r=this.getConstantType(t)))throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,xProperty:e.property};case"this.constants.value[][]":if("string"!=typeof e.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.property.name,!(r=this.getConstantType(t)))throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,yProperty:e.object.property,xProperty:e.property};case"this.constants.value[][][]":if("string"!=typeof e.object.object.object.property.name)throw this.astErrorOutput("Unexpected expression",e);if(t=e.object.object.object.property.name,!(r=this.getConstantType(t)))throw this.astErrorOutput("Constant has no type",e);return{name:t,type:r,origin:"constants",signature:n,zProperty:e.object.object.property,yProperty:e.object.property,xProperty:e.property};case"fn()[]":case"[][]":return{signature:n,property:e.property};default:throw this.astErrorOutput("Unexpected expression",e)}}findIdentifierOrigin(e){const t=[this.ast];for(;t.length>0;){const r=t[0];if("VariableDeclarator"===r.type&&r.id&&r.id.name&&r.id.name===e.name)return r;if(t.shift(),r.argument)t.push(r.argument);else if(r.body)t.push(r.body);else if(r.declarations)t.push(r.declarations);else if(Array.isArray(r))for(let e=0;e0;){const e=t.pop();if("ReturnStatement"===e.type)return e;if("FunctionDeclaration"!==e.type)if(e.argument)t.push(e.argument);else if(e.body)t.push(e.body);else if(e.declarations)t.push(e.declarations);else if(Array.isArray(e))for(let r=0;r0&&t.push(", "),t.push("user_"),t.push(r)}t.push(") {\n")}for(let r=0;r0&&t.push(r.join(""),";\n"),t.push(`for (let ${e}=0;${e}0&&t.push(`if (!${n.join("")}) break;\n`),t.push(s.join("")),t.push(`\n${i.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),t.push("if ("),this.astGeneric(e.test,t),t.push(") {\n"),this.astGeneric(e.body,t),t.push("} else {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astDoWhileStatement(e,t){if("DoWhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);return t.push("for (let i = 0; i < LOOP_MAX; i++) {"),this.astGeneric(e.body,t),t.push("if (!"),this.astGeneric(e.test,t),t.push(") {\n"),t.push("break;\n"),t.push("}\n"),t.push("}\n"),t}astAssignmentExpression(e,t){const r=this.getDeclaration(e.left);if(r&&!r.assignable)throw new this.astErrorOutput(`Variable ${e.left.name} is not assignable here`,e);return this.astGeneric(e.left,t),t.push(e.operator),this.astGeneric(e.right,t),t}astBlockStatement(e,t){if(this.isState("loop-body")){this.pushState("block-body");for(let r=0;r0&&t.push(","),this.astGeneric(r[e],t);return this.isState("in-for-loop-init")||t.push(";"),t}astIfStatement(e,t){return t.push("if ("),this.astGeneric(e.test,t),t.push(")"),"BlockStatement"===e.consequent.type?this.astGeneric(e.consequent,t):(t.push(" {\n"),this.astGeneric(e.consequent,t),t.push("\n}\n")),e.alternate&&(t.push("else "),"BlockStatement"===e.alternate.type?this.astGeneric(e.alternate,t):(t.push(" {\n"),this.astGeneric(e.alternate,t),t.push("\n}\n"))),t}astSwitchStatement(e,t){const{discriminant:r,cases:n}=e;t.push("switch ("),this.astGeneric(r,t),t.push(") {\n");for(let e=0;e0&&(this.astGeneric(n[e].consequent,t),t.push("break;\n"))):(t.push("default:\n"),this.astGeneric(n[e].consequent,t),n[e].consequent&&n[e].consequent.length>0&&t.push("break;\n"));t.push("\n}")}astThisExpression(e,t){return t.push("_this"),t}astMemberExpression(e,t){const{signature:r,type:n,property:i,xProperty:s,yProperty:a,zProperty:o,name:u,origin:l}=this.getMemberExpressionDetails(e);switch(r){case"this.thread.value":return t.push(`_this.thread.${u}`),t;case"this.output.value":switch(u){case"x":t.push("outputX");break;case"y":t.push("outputY");break;case"z":t.push("outputZ");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value.value":if("Math"===l)return t.push(Math[u]),t;switch(i){case"r":return t.push(`user_${u}[0]`),t;case"g":return t.push(`user_${u}[1]`),t;case"b":return t.push(`user_${u}[2]`),t;case"a":return t.push(`user_${u}[3]`),t}break;case"this.constants.value":case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":break;case"fn()[]":return this.astGeneric(e.object,t),t.push("["),this.astGeneric(e.property,t),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!e.computed)switch(n){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${l}_${u}`),t}const h=`${l}_${u}`;switch(n){case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLImageArray":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"HTMLImage":default:let e,r;if("constants"===l){const t=this.constants[u];e=(r="Input"===this.constantTypes[u])?t.size:null}else e=(r=this.isInput(u))?this.argumentSizes[this.argumentNames.indexOf(u)]:null;t.push(`${h}`),o&&a?r?(t.push("[("),this.astGeneric(o,t),t.push(`*${this.dynamicArguments?"(outputY * outputX)":e[1]*e[0]})+(`),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(o,t),t.push("]"),t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):a?r?(t.push("[("),this.astGeneric(a,t),t.push(`*${this.dynamicArguments?"outputX":e[0]})+`),this.astGeneric(s,t),t.push("]")):(t.push("["),this.astGeneric(a,t),t.push("]"),t.push("["),this.astGeneric(s,t),t.push("]")):void 0!==s&&(t.push("["),this.astGeneric(s,t),t.push("]"))}return t}astCallExpression(e,t){if("CallExpression"!==e.type)throw this.astErrorOutput("Unknown CallExpression",e);let r=this.astMemberExpressionUnroll(e.callee);this.calledFunctions.indexOf(r)<0&&this.calledFunctions.push(r);this.isAstMathFunction(e);this.onFunctionCall&&this.onFunctionCall(this.name,r,e.arguments),t.push(r),t.push("(");const n=this.lookupFunctionArgumentTypes(r)||[];for(let i=0;i0&&t.push(", "),this.astGeneric(s,t)}return t.push(")"),t}astArrayExpression(e,t){const r=e.elements.length;t.push("new Float32Array([");for(let n=0;n0&&t.push(", ");const r=e.elements[n];this.astGeneric(r,t)}return t.push("])"),t}astDebuggerStatement(e,t){return t.push("debugger;"),t}}function k(e,t){const r=[],n=[],i=[],s=!/^function/.test(e.color.toString());if(r.push(" const { context, canvas, constants: incomingConstants } = settings;",` const output = new Int32Array(${JSON.stringify(Array.from(e.output))});`,` const _constantTypes = ${JSON.stringify(e.constantTypes)};`,` const _constants = ${function(e,t){const r=[];for(const n in t){if(!t.hasOwnProperty(n))continue;const i=t[n],s=e[n];switch(i){case"Number":case"Integer":case"Float":case"Boolean":r.push(`${n}:${s}`);break;case"Array(2)":case"Array(3)":case"Array(4)":r.push(`${n}:new ${s.constructor.name}(${JSON.stringify(Array.from(s))})`)}}return`{ ${r.join()} }`}(e.constants,e.constantTypes)};`),n.push(" constants: _constants,"," context,"," output,"," thread: {x: 0, y: 0, z: 0},"),e.graphical){r.push(` const _imageData = context.createImageData(${e.output[0]}, ${e.output[1]});`),r.push(` const _colorData = new Uint8ClampedArray(${e.output[0]} * ${e.output[1]} * 4);`);const t=R.flattenFunctionToString((s?"function ":"")+e.color.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:(e,t)=>null}),a=R.flattenFunctionToString((s?"function ":"")+e.getPixels.toString(),{thisLookup:t=>{switch(t){case"_colorData":return"_colorData";case"_imageData":return"_imageData";case"output":return"output";case"thread":return"this.thread"}return JSON.stringify(e[t])},findDependency:()=>null});n.push(" _imageData,"," _colorData,",` color: ${t},`),i.push(` kernel.getPixels = ${a};`)}const a=[],o=Object.keys(e.constantTypes);for(let t=0;t"this"===t?(s?"function ":"")+e[r].toString():null,thisLookup:e=>{switch(e){case"canvas":return;case"context":return"context"}}});i.push(t),n.push(" _mediaTo2DArray,"),n.push(" _imageTo3DArray,")}else if(-1!==e.argumentTypes.indexOf("HTMLImage")||-1!==a.indexOf("HTMLImage")){const t=R.flattenFunctionToString((s?"function ":"")+e._mediaTo2DArray.toString(),{findDependency:(e,t)=>null,thisLookup:e=>{switch(e){case"canvas":return"settings.canvas";case"context":return"settings.context"}throw new Error("unhandled thisLookup")}});i.push(t),n.push(" _mediaTo2DArray,")}return`function(settings) {\n${r.join("\n")}\n for (const p in _constantTypes) {\n if (!_constantTypes.hasOwnProperty(p)) continue;\n const type = _constantTypes[p];\n switch (type) {\n case 'Number':\n case 'Integer':\n case 'Float':\n case 'Boolean':\n case 'Array(2)':\n case 'Array(3)':\n case 'Array(4)':\n if (incomingConstants.hasOwnProperty(p)) {\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\n }\n continue;\n }\n if (!incomingConstants.hasOwnProperty(p)) {\n throw new Error('constant ' + p + ' not found');\n }\n _constants[p] = incomingConstants[p];\n }\n const kernel = (function() {\n${e._kernelString}\n })\n .apply({ ${n.join("\n")} });\n ${i.join("\n")}\n return kernel;\n}`}class M extends I{static getFeatures(){return this.features}static get features(){return Object.freeze({kernelMap:!0,isIntegerDivisionAccurate:!0})}static get isSupported(){return!0}static isContextMatch(e){return!1}static get mode(){return"cpu"}static nativeFunctionArguments(){return null}static nativeFunctionReturnType(){return null}static combineKernels(e){return e}constructor(e,t){super(e,t),this.mergeSettings(e.settings||t),this._imageData=null,this._colorData=null,this._kernelString=null,this.thread={x:0,y:0,z:0},this.translatedSources=null}initCanvas(){return"undefined"!=typeof document?document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas?new OffscreenCanvas(0,0):void 0}initContext(){return this.canvas?this.canvas.getContext("2d"):null}initPlugins(e){return[]}validateSettings(e){if(!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=R.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=R.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical&&2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");this.checkOutput()}translateSource(){if(this.leadingReturnStatement=this.output.length>1?"resultX[x] = ":"result[x] = ",this.subKernels){const e=[];for(let t=0;t1?`resultX_${r}[x] = subKernelResult_${r};\n`:`result_${r}[x] = subKernelResult_${r};\n`)}this.followingReturnStatement=e.join("")}const e=F.fromKernel(this,N);this.translatedSources=e.getPrototypes("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType())}build(){if(this.setupConstants(),this.setupArguments(arguments),this.validateSettings(arguments),this.translateSource(),this.graphical){const{canvas:e,output:t}=this;if(!e)throw new Error("no canvas available for using graphical output");const r=t[0],n=t[1]||1;e.width=r,e.height=n,this._imageData=this.context.createImageData(r,n),this._colorData=new Uint8ClampedArray(r*n*4)}const e=this.getKernelString();this.kernelString=e,this.debug&&(console.log("Function output:"),console.log(e));try{this.run=new Function([],e).bind(this)()}catch(e){console.error("An error occurred compiling the javascript: ",e)}}color(e,t,r,n){void 0===n&&(n=1),e=Math.floor(255*e),t=Math.floor(255*t),r=Math.floor(255*r),n=Math.floor(255*n);const i=this.output[0],s=this.output[1],a=this.thread.x+(s-this.thread.y-1)*i;this._colorData[4*a+0]=e,this._colorData[4*a+1]=t,this._colorData[4*a+2]=r,this._colorData[4*a+3]=n}getKernelString(){if(null!==this._kernelString)return this._kernelString;let e=null,{translatedSources:t}=this;return t.length>1?t=t.filter(t=>/^function/.test(t)?t:(e=t,!1)):e=t.shift(),this._kernelString=` const LOOP_MAX = ${this._getLoopMaxString()};\n ${this.injectedNative||""}\n const _this = this;\n ${this._processConstants()}\n return (${this.argumentNames.map(e=>"user_"+e).join(", ")}) => {\n ${this._processArguments()}\n ${this.graphical?this._graphicalKernelBody(e):this._resultKernelBody(e)}\n ${t.length>0?t.join("\n"):""}\n };`}toString(){return k(this)}_getLoopMaxString(){return this.loopMaxIterations?` ${parseInt(this.loopMaxIterations)};`:" 1000;"}_processConstants(){if(!this.constants)return"";const e=[];for(let t in this.constants){switch(this.constantTypes[t]){case"HTMLImage":case"HTMLVideo":e.push(` const constants_${t} = this._mediaTo2DArray(this.constants.${t});\n`);break;case"HTMLImageArray":e.push(` const constants_${t} = this._imageTo3DArray(this.constants.${t});\n`);break;case"Input":e.push(` const constants_${t} = this.constants.${t}.value;\n`);break;default:e.push(` const constants_${t} = this.constants.${t};\n`)}}return e.join("")}_processArguments(){const e=[];for(let t=0;t0?e.width:e.videoWidth,n=e.height>0?e.height:e.videoHeight;t.width=0;e--){const t=a[e]=new Array(r);for(let e=0;e`const result_${e.name} = new ${t}(outputX);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n ${e}\n }`}_resultKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const result = new Array(outputY);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n const resultX = result[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_graphicalKernel2DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputY);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.z = 0;\n this.thread.y = y;\n ${this._mapSubKernels(e=>`const resultX_${e.name} = result_${e.name}[y] = new ${t}(outputX);\n`).join("")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }`}_resultKernel3DLoop(e){const t=this._getKernelResultTypeConstructorString();return` const outputX = _this.output[0];\n const outputY = _this.output[1];\n const outputZ = _this.output[2];\n const result = new Array(outputZ);\n ${this._mapSubKernels(e=>`const result_${e.name} = new Array(outputZ);\n`).join(" ")}\n ${this._mapSubKernels(e=>`let subKernelResult_${e.name};\n`).join(" ")}\n for (let z = 0; z < outputZ; z++) {\n this.thread.z = z;\n const resultY = result[z] = new Array(outputY);\n ${this._mapSubKernels(e=>`const resultY_${e.name} = result_${e.name}[z] = new Array(outputY);\n`).join(" ")}\n for (let y = 0; y < outputY; y++) {\n this.thread.y = y;\n const resultX = resultY[y] = new ${t}(outputX);\n ${this._mapSubKernels(e=>`const resultX_${e.name} = resultY_${e.name}[y] = new ${t}(outputX);\n`).join(" ")}\n for (let x = 0; x < outputX; x++) {\n this.thread.x = x;\n ${e}\n }\n }\n }`}_kernelOutput(){return this.subKernels?`\n return {\n result: result,\n ${this.subKernels.map(e=>`${e.property}: result_${e.name}`).join(",\n ")}\n };`:"\n return result;"}_mapSubKernels(e){return null===this.subKernels?[""]:this.subKernels.map(e)}destroy(e){e&&delete this.canvas}static destroyContext(e){}toJSON(){const e=super.toJSON();return e.functionNodes=F.fromKernel(this,N).toJSON(),e}setOutput(e){super.setOutput(e);const[t,r]=this.output;this.graphical&&(this._imageData=this.context.createImageData(t,r),this._colorData=new Uint8ClampedArray(t*r*4))}}class U extends v{constructor(e){super(e),this.type="ArrayTexture(1)"}renderRawOutput(){const{context:e}=this,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const r=new Float32Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.FLOAT,r),r}renderValues(){return this.renderRawOutput()}toArray(){return R.erectFloat(this.renderValues(),this.output[0])}}class P extends U{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return R.erectArray2(this.renderValues(),this.output[0],this.output[1])}}class L extends U{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return R.erect2DArray2(this.renderValues(),this.output[0],this.output[1])}}class V extends U{constructor(e){super(e),this.type="ArrayTexture(2)"}toArray(){return R.erect3DArray2(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class K extends U{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return R.erectArray3(this.renderValues(),this.output[0])}}class G extends U{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return R.erect2DArray3(this.renderValues(),this.output[0],this.output[1])}}class B extends U{constructor(e){super(e),this.type="ArrayTexture(3)"}toArray(){return R.erect3DArray3(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class X extends U{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return R.erectArray4(this.renderValues(),this.output[0])}}class j extends U{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return R.erect2DArray4(this.renderValues(),this.output[0],this.output[1])}}class H extends U{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return R.erect3DArray4(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class W extends U{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return R.erect2DFloat(this.renderValues(),this.output[0],this.output[1])}}class q extends U{constructor(e){super(e),this.type="ArrayTexture(1)"}toArray(){return R.erect3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class Y extends U{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return R.erectMemoryOptimizedFloat(this.renderValues(),this.output[0])}}class J extends U{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return R.erectMemoryOptimized2DFloat(this.renderValues(),this.output[0],this.output[1])}}class Z extends U{constructor(e){super(e),this.type="MemoryOptimizedNumberTexture"}toArray(){return R.erectMemoryOptimized3DFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class Q extends v{constructor(e){super(e),this.type="NumberTexture"}renderRawOutput(){const{context:e}=this,t=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,t),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,this.texture,0);const r=new Uint8Array(this.size[0]*this.size[1]*4);return e.readPixels(0,0,this.size[0],this.size[1],e.RGBA,e.UNSIGNED_BYTE,r),r}renderValues(){return new Float32Array(this.renderRawOutput().buffer)}toArray(){return R.erectPackedFloat(this.renderValues(),this.output[0])}}class ee extends Q{constructor(e){super(e),this.type="NumberTexture"}toArray(){return R.erect2DPackedFloat(this.renderValues(),this.output[0],this.output[1])}}class te extends Q{constructor(e){super(e),this.type="NumberTexture"}toArray(){return R.erect3DPackedFloat(this.renderValues(),this.output[0],this.output[1],this.output[2])}}class re extends Q{constructor(e){super(e),this.type="ArrayTexture(4)"}toArray(){return this.renderValues()}}class ne extends I{static get mode(){return"gpu"}static getIsFloatRead(){const e=new this("function kernelFunction() {\n return 1;\n }",{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[1],precision:"single",returnType:"Number",tactic:"speed"});e.build(),e.run();const t=e.renderOutput();return e.destroy(!0),1===t[0]}static getIsIntegerDivisionAccurate(){const e=new this(function(e,t){return e[this.thread.x]/t[this.thread.x]}.toString(),{context:this.testContext,canvas:this.testCanvas,validate:!1,output:[2],returnType:"Number",precision:"unsigned",tactic:"speed"}),t=[[6,6030401],[3,3991]];e.build.apply(e,t),e.run.apply(e,t);const r=e.renderOutput();return e.destroy(!0),2===r[0]&&1511===r[1]}static get testCanvas(){throw new Error(`"testCanvas" not defined on ${this.name}`)}static get testContext(){throw new Error(`"testContext" not defined on ${this.name}`)}static get features(){throw new Error(`"features" not defined on ${this.name}`)}static setupFeatureChecks(){throw new Error(`"setupFeatureChecks" not defined on ${this.name}`)}setFixIntegerDivisionAccuracy(e){return this.fixIntegerDivisionAccuracy=e,this}setPrecision(e){return this.precision=e,this}setFloatTextures(e){return R.warnDeprecated("method","setFloatTextures","setOptimizeFloatMemory"),this.floatTextures=e,this}static nativeFunctionArguments(e){const t=[],r=[],n=[],i=/^[a-zA-Z_]/,s=/[a-zA-Z_0-9]/;let a=0,o=null,u=null;for(;a0?n[n.length-1]:null;if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"*"!==h)if("MULTI_LINE_COMMENT"!==c||"*"!==l||"/"!==h)if("FUNCTION_ARGUMENTS"!==c||"/"!==l||"/"!==h)if("COMMENT"!==c||"\n"!==l)if(null!==c||"("!==l){if("FUNCTION_ARGUMENTS"===c){if(")"===l){n.pop();break}if("f"===l&&"l"===h&&"o"===e[a+2]&&"a"===e[a+3]&&"t"===e[a+4]&&" "===e[a+5]){n.push("DECLARE_VARIABLE"),u="float",o="",a+=6;continue}if("i"===l&&"n"===h&&"t"===e[a+2]&&" "===e[a+3]){n.push("DECLARE_VARIABLE"),u="int",o="",a+=4;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"2"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec2",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"3"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec3",o="",a+=5;continue}if("v"===l&&"e"===h&&"c"===e[a+2]&&"4"===e[a+3]&&" "===e[a+4]){n.push("DECLARE_VARIABLE"),u="vec4",o="",a+=5;continue}}else if("DECLARE_VARIABLE"===c){if(""===o){if(" "===l){a++;continue}if(!i.test(l))throw new Error("variable name is not expected string")}o+=l,s.test(h)||(n.pop(),r.push(o),t.push(se[u]))}a++}else n.push("FUNCTION_ARGUMENTS"),a++;else n.pop(),a++;else n.push("COMMENT"),a+=2;else n.pop(),a+=2;else n.push("MULTI_LINE_COMMENT"),a+=2}if(n.length>0)throw new Error("GLSL function was not parsable");return{argumentNames:r,argumentTypes:t}}static nativeFunctionReturnType(e){return se[e.match(/int|float|vec[2-4]/)[0]]}static combineKernels(e,t){e.apply(null,arguments);const{texSize:r,context:n,threadDim:i}=t.texSize;let s;if("single"===t.precision){const e=r[0],t=Math.ceil(r[1]/4);s=new Float32Array(e*t*4*4),n.readPixels(0,0,e,4*t,n.RGBA,n.FLOAT,s)}else{const e=new Uint8Array(r[0]*r[1]*4);n.readPixels(0,0,r[0],r[1],n.RGBA,n.UNSIGNED_BYTE,e),s=new Float32Array(e.buffer)}if(s=s.subarray(0,i[0]*i[1]*i[2]),1===t.output.length)return s;if(2===t.output.length)return R.splitArray(s,t.output[0]);if(3===t.output.length){return R.splitArray(s,t.output[0]*t.output[1]).map((function(e){return R.splitArray(e,t.output[0])}))}}constructor(e,t){super(e,t),this.transferValues=null,this.formatValues=null,this.TextureConstructor=null,this.renderOutput=null,this.renderRawOutput=null,this.texSize=null,this.translatedSource=null,this.renderStrategy=null,this.compiledFragmentShader=null,this.compiledVertexShader=null}checkTextureSize(){const{features:e}=this.constructor;if(this.texSize[0]>e.maxTextureSize||this.texSize[1]>e.maxTextureSize)throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${e.maxTextureSize},${e.maxTextureSize}]`)}translateSource(){throw new Error(`"translateSource" not defined on ${this.constructor.name}`)}pickRenderStrategy(e){if(this.graphical)return this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=e=>e,this.TextureConstructor=re,null;if("unsigned"===this.precision)if(this.renderRawOutput=this.readPackedPixelsToUint8Array,this.transferValues=this.readPackedPixelsToFloat32Array,this.pipeline)switch(this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=te,this.renderStrategy=ie.PackedPixelTo3DFloat,null):this.output[1]>0?(this.TextureConstructor=ee,this.renderStrategy=ie.PackedPixelTo2DFloat,null):(this.TextureConstructor=Q,this.renderStrategy=ie.PackedPixelToFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else switch(null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.renderOutput=this.renderValues,this.output[2]>0?(this.TextureConstructor=te,this.renderStrategy=ie.PackedPixelTo3DFloat,this.formatValues=R.erect3DPackedFloat,null):this.output[1]>0?(this.TextureConstructor=ee,this.renderStrategy=ie.PackedPixelTo2DFloat,this.formatValues=R.erect2DPackedFloat,null):(this.TextureConstructor=Q,this.renderStrategy=ie.PackedPixelToFloat,this.formatValues=R.erectPackedFloat,null);case"Array(2)":case"Array(3)":case"Array(4)":return this.requestFallback(e)}else{if("single"!==this.precision)throw new Error(`unhandled precision of "${this.precision}"`);if(this.renderRawOutput=this.readFloatPixelsToFloat32Array,this.transferValues=this.readFloatPixelsToFloat32Array,this.pipeline)switch(this.renderStrategy=ie.FloatTexture,this.renderOutput=this.renderTexture,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToTextures),this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.optimizeFloatMemory?this.output[2]>0?(this.TextureConstructor=Z,null):this.output[1]>0?(this.TextureConstructor=J,null):(this.TextureConstructor=Y,null):this.output[2]>0?(this.TextureConstructor=q,null):this.output[1]>0?(this.TextureConstructor=W,null):(this.TextureConstructor=U,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=V,null):this.output[1]>0?(this.TextureConstructor=L,null):(this.TextureConstructor=P,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=B,null):this.output[1]>0?(this.TextureConstructor=G,null):(this.TextureConstructor=K,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=H,null):this.output[1]>0?(this.TextureConstructor=j,null):(this.TextureConstructor=X,null)}if(this.renderOutput=this.renderValues,null!==this.subKernels&&(this.renderKernels=this.renderKernelsToArrays),this.optimizeFloatMemory)switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=Z,this.renderStrategy=ie.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat,this.formatValues=R.erectMemoryOptimized3DFloat,null):this.output[1]>0?(this.TextureConstructor=J,this.renderStrategy=ie.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat,this.formatValues=R.erectMemoryOptimized2DFloat,null):(this.TextureConstructor=Y,this.renderStrategy=ie.MemoryOptimizedFloatPixelToMemoryOptimizedFloat,this.formatValues=R.erectMemoryOptimizedFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=V,this.renderStrategy=ie.FloatPixelTo3DArray2,this.formatValues=R.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=L,this.renderStrategy=ie.FloatPixelTo2DArray2,this.formatValues=R.erect2DArray2,null):(this.TextureConstructor=P,this.renderStrategy=ie.FloatPixelToArray2,this.formatValues=R.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=B,this.renderStrategy=ie.FloatPixelTo3DArray3,this.formatValues=R.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=G,this.renderStrategy=ie.FloatPixelTo2DArray3,this.formatValues=R.erect2DArray3,null):(this.TextureConstructor=K,this.renderStrategy=ie.FloatPixelToArray3,this.formatValues=R.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=H,this.renderStrategy=ie.FloatPixelTo3DArray4,this.formatValues=R.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=j,this.renderStrategy=ie.FloatPixelTo2DArray4,this.formatValues=R.erect2DArray4,null):(this.TextureConstructor=X,this.renderStrategy=ie.FloatPixelToArray4,this.formatValues=R.erectArray4,null)}else switch(this.returnType){case"LiteralInteger":case"Float":case"Number":case"Integer":return this.output[2]>0?(this.TextureConstructor=q,this.renderStrategy=ie.FloatPixelTo3DFloat,this.formatValues=R.erect3DFloat,null):this.output[1]>0?(this.TextureConstructor=W,this.renderStrategy=ie.FloatPixelTo2DFloat,this.formatValues=R.erect2DFloat,null):(this.TextureConstructor=U,this.renderStrategy=ie.FloatPixelToFloat,this.formatValues=R.erectFloat,null);case"Array(2)":return this.output[2]>0?(this.TextureConstructor=V,this.renderStrategy=ie.FloatPixelTo3DArray2,this.formatValues=R.erect3DArray2,null):this.output[1]>0?(this.TextureConstructor=L,this.renderStrategy=ie.FloatPixelTo2DArray2,this.formatValues=R.erect2DArray2,null):(this.TextureConstructor=P,this.renderStrategy=ie.FloatPixelToArray2,this.formatValues=R.erectArray2,null);case"Array(3)":return this.output[2]>0?(this.TextureConstructor=B,this.renderStrategy=ie.FloatPixelTo3DArray3,this.formatValues=R.erect3DArray3,null):this.output[1]>0?(this.TextureConstructor=G,this.renderStrategy=ie.FloatPixelTo2DArray3,this.formatValues=R.erect2DArray3,null):(this.TextureConstructor=K,this.renderStrategy=ie.FloatPixelToArray3,this.formatValues=R.erectArray3,null);case"Array(4)":return this.output[2]>0?(this.TextureConstructor=H,this.renderStrategy=ie.FloatPixelTo3DArray4,this.formatValues=R.erect3DArray4,null):this.output[1]>0?(this.TextureConstructor=j,this.renderStrategy=ie.FloatPixelTo2DArray4,this.formatValues=R.erect2DArray4,null):(this.TextureConstructor=X,this.renderStrategy=ie.FloatPixelToArray4,this.formatValues=R.erectArray4,null)}}throw new Error(`unhandled return type "${this.returnType}"`)}getKernelString(){throw new Error("abstract method call")}getMainResultTexture(){switch(this.returnType){case"LiteralInteger":case"Float":case"Integer":case"Number":return this.getMainResultNumberTexture();case"Array(2)":return this.getMainResultArray2Texture();case"Array(3)":return this.getMainResultArray3Texture();case"Array(4)":return this.getMainResultArray4Texture();default:throw new Error(`unhandled returnType type ${this.returnType}`)}}getMainResultKernelNumberTexture(){throw new Error("abstract method call")}getMainResultSubKernelNumberTexture(){throw new Error("abstract method call")}getMainResultKernelArray2Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray2Texture(){throw new Error("abstract method call")}getMainResultKernelArray3Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray3Texture(){throw new Error("abstract method call")}getMainResultKernelArray4Texture(){throw new Error("abstract method call")}getMainResultSubKernelArray4Texture(){throw new Error("abstract method call")}getMainResultGraphical(){throw new Error("abstract method call")}getMainResultMemoryOptimizedFloats(){throw new Error("abstract method call")}getMainResultPackedPixels(){throw new Error("abstract method call")}getMainResultString(){return this.graphical?this.getMainResultGraphical():"single"===this.precision?this.optimizeFloatMemory?this.getMainResultMemoryOptimizedFloats():this.getMainResultTexture():this.getMainResultPackedPixels()}getMainResultNumberTexture(){return R.linesToString(this.getMainResultKernelNumberTexture())+R.linesToString(this.getMainResultSubKernelNumberTexture())}getMainResultArray2Texture(){return R.linesToString(this.getMainResultKernelArray2Texture())+R.linesToString(this.getMainResultSubKernelArray2Texture())}getMainResultArray3Texture(){return R.linesToString(this.getMainResultKernelArray3Texture())+R.linesToString(this.getMainResultSubKernelArray3Texture())}getMainResultArray4Texture(){return R.linesToString(this.getMainResultKernelArray4Texture())+R.linesToString(this.getMainResultSubKernelArray4Texture())}getFloatTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp float;\n";case"performance":return"precision highp float;\n";case"balanced":default:return"precision mediump float;\n"}}getIntTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp int;\n";case"performance":return"precision highp int;\n";case"balanced":default:return"precision mediump int;\n"}}getSampler2DTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp sampler2D;\n";case"performance":return"precision highp sampler2D;\n";case"balanced":default:return"precision mediump sampler2D;\n"}}getSampler2DArrayTacticDeclaration(){switch(this.tactic){case"speed":return"precision lowp sampler2DArray;\n";case"performance":return"precision highp sampler2DArray;\n";case"balanced":default:return"precision mediump sampler2DArray;\n"}}renderTexture(){return new this.TextureConstructor({texture:this.outputTexture,size:this.texSize,dimensions:this.threadDim,output:this.output,context:this.context})}readPackedPixelsToUint8Array(){if("unsigned"!==this.precision)throw new Error('Requires this.precision to be "unsigned"');const{texSize:e,context:t}=this,r=new Uint8Array(e[0]*e[1]*4);return t.readPixels(0,0,e[0],e[1],t.RGBA,t.UNSIGNED_BYTE,r),r}readPackedPixelsToFloat32Array(){return new Float32Array(this.readPackedPixelsToUint8Array().buffer)}readFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,r=e[0],n=e[1],i=new Float32Array(r*n*4);return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,i),i}readMemoryOptimizedFloatPixelsToFloat32Array(){if("single"!==this.precision)throw new Error('Requires this.precision to be "single"');const{texSize:e,context:t}=this,r=e[0],n=e[1],i=new Float32Array(r*n*4);return t.readPixels(0,0,r,n,t.RGBA,t.FLOAT,i),i}getPixels(e){const{context:t,output:r}=this,[n,i]=r,s=new Uint8Array(n*i*4);return t.readPixels(0,0,n,i,t.RGBA,t.UNSIGNED_BYTE,s),new Uint8ClampedArray((e?s:R.flipPixels(s,n,i)).buffer)}renderKernelsToArrays(){const e={result:this.renderOutput()};for(let t=0;t0&&this._setupSubOutputTextures()}return this}renderValues(){return this.formatValues(this.transferValues(),this.output[0],this.output[1],this.output[2])}}const ie=Object.freeze({PackedPixelToUint8Array:Symbol("PackedPixelToUint8Array"),PackedPixelToFloat:Symbol("PackedPixelToFloat"),PackedPixelTo2DFloat:Symbol("PackedPixelTo2DFloat"),PackedPixelTo3DFloat:Symbol("PackedPixelTo3DFloat"),PackedTexture:Symbol("PackedTexture"),FloatPixelToFloat32Array:Symbol("FloatPixelToFloat32Array"),FloatPixelToFloat:Symbol("FloatPixelToFloat"),FloatPixelTo2DFloat:Symbol("FloatPixelTo2DFloat"),FloatPixelTo3DFloat:Symbol("FloatPixelTo3DFloat"),FloatPixelToArray2:Symbol("FloatPixelToArray2"),FloatPixelTo2DArray2:Symbol("FloatPixelTo2DArray2"),FloatPixelTo3DArray2:Symbol("FloatPixelTo3DArray2"),FloatPixelToArray3:Symbol("FloatPixelToArray3"),FloatPixelTo2DArray3:Symbol("FloatPixelTo2DArray3"),FloatPixelTo3DArray3:Symbol("FloatPixelTo3DArray3"),FloatPixelToArray4:Symbol("FloatPixelToArray4"),FloatPixelTo2DArray4:Symbol("FloatPixelTo2DArray4"),FloatPixelTo3DArray4:Symbol("FloatPixelTo3DArray4"),FloatTexture:Symbol("FloatTexture"),MemoryOptimizedFloatPixelToMemoryOptimizedFloat:Symbol("MemoryOptimizedFloatPixelToFloat"),MemoryOptimizedFloatPixelToMemoryOptimized2DFloat:Symbol("MemoryOptimizedFloatPixelTo2DFloat"),MemoryOptimizedFloatPixelToMemoryOptimized3DFloat:Symbol("MemoryOptimizedFloatPixelTo3DFloat")}),se={int:"Integer",float:"Number",vec2:"Array(2)",vec3:"Array(3)",vec4:"Array(4)"};class ae extends O{constructor(e,t){super(e,t),t&&t.hasOwnProperty("fixIntegerDivisionAccuracy")&&(this.fixIntegerDivisionAccuracy=t.fixIntegerDivisionAccuracy)}astFunction(e,t){if(this.isRootKernel)t.push("void");else{if(!this.returnType){this.findLastReturn()&&(this.returnType=this.getType(e.body),"LiteralInteger"===this.returnType&&(this.returnType="Number"))}const{returnType:r}=this;if(r){const e=oe[r];if(!e)throw new Error(`unknown type ${r}`);t.push(e)}else t.push("void")}if(t.push(" "),t.push(this.name),t.push("("),!this.isRootKernel)for(let r=0;r0&&t.push(", ");let i=this.argumentTypes[this.argumentNames.indexOf(n)];if(!i)throw this.astErrorOutput(`Unknown argument ${n} type`,e);"LiteralInteger"===i&&(this.argumentTypes[r]=i="Number");const s=oe[i];if(!s)throw this.astErrorOutput("Unexpected expression",e);t.push(s),t.push(" "),t.push("user_"),t.push(n)}t.push(") {\n");for(let r=0;r"===e.operator||"<"===e.operator&&"Literal"===e.right.type)&&!Number.isInteger(e.right.value)){this.pushState("building-float"),this.castValueToFloat(e.left,t),t.push(ue[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-float");break}if(this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.pushState("casting-to-integer"),"Literal"===e.right.type){const r=[];if(this.astGeneric(e.right,r),"Integer"!==this.getType(e.right))throw this.astErrorOutput("Unhandled binary expression with literal",e);t.push(r.join(""))}else t.push("int("),this.astGeneric(e.right,t),t.push(")");this.popState("casting-to-integer"),this.popState("building-integer");break;case"Integer & LiteralInteger":this.pushState("building-integer"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer");break;case"Number & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;case"Float & LiteralInteger":case"Number & LiteralInteger":this.isState("in-for-loop-test")?(this.pushState("building-integer"),t.push("int("),this.astGeneric(e.left,t),t.push(")"),t.push(ue[e.operator]||e.operator),this.castLiteralToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.castLiteralToFloat(e.right,t),this.popState("building-float"));break;case"LiteralInteger & Float":case"LiteralInteger & Number":this.isState("in-for-loop-test")||this.isState("in-for-loop-init")||this.isState("casting-to-integer")?(this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(ue[e.operator]||e.operator),this.castValueToInteger(e.right,t),this.popState("building-integer")):(this.pushState("building-float"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.pushState("casting-to-float"),this.astGeneric(e.right,t),this.popState("casting-to-float"),this.popState("building-float"));break;case"LiteralInteger & Integer":this.pushState("building-integer"),this.castLiteralToInteger(e.left,t),t.push(ue[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-integer");break;case"Boolean & Boolean":this.pushState("building-boolean"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.astGeneric(e.right,t),this.popState("building-boolean");break;case"Float & Integer":this.pushState("building-float"),this.astGeneric(e.left,t),t.push(ue[e.operator]||e.operator),this.castValueToFloat(e.right,t),this.popState("building-float");break;default:throw this.astErrorOutput(`Unhandled binary expression between ${i}`,e)}return t.push(")"),t}checkAndUpconvertOperator(e,t){const r=this.checkAndUpconvertBitwiseOperators(e,t);if(r)return r;const n={"%":"mod","**":"pow"}[e.operator];if(!n)return null;switch(t.push(n),t.push("("),this.getType(e.left)){case"Integer":this.castValueToFloat(e.left,t);break;case"LiteralInteger":this.castLiteralToFloat(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Integer":this.castValueToFloat(e.right,t);break;case"LiteralInteger":this.castLiteralToFloat(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseOperators(e,t){const r={"&":"bitwiseAnd","|":"bitwiseOr","^":"bitwiseXOR","<<":"bitwiseZeroFillLeftShift",">>":"bitwiseSignedRightShift",">>>":"bitwiseZeroFillRightShift"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.left)){case"Number":case"Float":this.castValueToInteger(e.left,t);break;case"LiteralInteger":this.castLiteralToInteger(e.left,t);break;default:this.astGeneric(e.left,t)}switch(t.push(","),this.getType(e.right)){case"Number":case"Float":this.castValueToInteger(e.right,t);break;case"LiteralInteger":this.castLiteralToInteger(e.right,t);break;default:this.astGeneric(e.right,t)}return t.push(")"),t}checkAndUpconvertBitwiseUnary(e,t){const r={"~":"bitwiseNot"}[e.operator];if(!r)return null;switch(t.push(r),t.push("("),this.getType(e.argument)){case"Number":case"Float":this.castValueToInteger(e.argument,t);break;case"LiteralInteger":this.castLiteralToInteger(e.argument,t);break;default:this.astGeneric(e.argument,t)}return t.push(")"),t}castLiteralToInteger(e,t){return this.pushState("casting-to-integer"),this.astGeneric(e,t),this.popState("casting-to-integer"),t}castLiteralToFloat(e,t){return this.pushState("casting-to-float"),this.astGeneric(e,t),this.popState("casting-to-float"),t}castValueToInteger(e,t){return this.pushState("casting-to-integer"),t.push("int("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-integer"),t}castValueToFloat(e,t){return this.pushState("casting-to-float"),t.push("float("),this.astGeneric(e,t),t.push(")"),this.popState("casting-to-float"),t}astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const r=this.getType(e);return"Infinity"===e.name?t.push("3.402823466e+38"):"Boolean"===r&&this.argumentNames.indexOf(e.name)>-1?t.push(`bool(user_${e.name})`):t.push(`user_${e.name}`),t}astForStatement(e,t){if("ForStatement"!==e.type)throw this.astErrorOutput("Invalid for statement",e);const r=[],n=[],i=[],s=[];let a=null;if(e.init){this.pushState("in-for-loop-init"),this.astGeneric(e.init,r);const{declarations:t}=e.init;for(let e=0;e0&&t.push(r.join(""),";\n"),t.push(`for (int ${e}=0;${e}0&&t.push(`if (!${n.join("")}) break;\n`),t.push(s.join("")),t.push(`\n${i.join("")};`),t.push("}\n")}return t}astWhileStatement(e,t){if("WhileStatement"!==e.type)throw this.astErrorOutput("Invalid while statement",e);const r=this.getInternalVariableName("safeI");return t.push(`for (int ${r}=0;${r}e+1){u=!0,this.astGeneric(n[e].consequent,o);continue}t.push(" else {\n")}this.astGeneric(n[e].consequent,t),t.push("\n}")}return u&&(t.push(" else {"),t.push(o.join("")),t.push("}")),t}astThisExpression(e,t){return t.push("this"),t}astMemberExpression(e,t){const{property:r,name:n,signature:i,origin:s,type:a,xProperty:o,yProperty:u,zProperty:l}=this.getMemberExpressionDetails(e);switch(i){case"value.thread.value":case"this.thread.value":if("x"!==n&&"y"!==n&&"z"!==n)throw this.astErrorOutput("Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`",e);return t.push(`threadId.${n}`),t;case"this.output.value":if(this.dynamicOutput)switch(n){case"x":this.isState("casting-to-float")?t.push("float(uOutputDim.x)"):t.push("uOutputDim.x");break;case"y":this.isState("casting-to-float")?t.push("float(uOutputDim.y)"):t.push("uOutputDim.y");break;case"z":this.isState("casting-to-float")?t.push("float(uOutputDim.z)"):t.push("uOutputDim.z");break;default:throw this.astErrorOutput("Unexpected expression",e)}else switch(n){case"x":this.isState("casting-to-integer")?t.push(this.output[0]):t.push(this.output[0],".0");break;case"y":this.isState("casting-to-integer")?t.push(this.output[1]):t.push(this.output[1],".0");break;case"z":this.isState("casting-to-integer")?t.push(this.output[2]):t.push(this.output[2],".0");break;default:throw this.astErrorOutput("Unexpected expression",e)}return t;case"value":throw this.astErrorOutput("Unexpected expression",e);case"value[]":case"value[][]":case"value[][][]":case"value[][][][]":case"value.value":if("Math"===s)return t.push(Math[n]),t;switch(r){case"r":return t.push(`user_${n}.r`),t;case"g":return t.push(`user_${n}.g`),t;case"b":return t.push(`user_${n}.b`),t;case"a":return t.push(`user_${n}.a`),t}break;case"this.constants.value":if(void 0===o)switch(a){case"Array(2)":case"Array(3)":case"Array(4)":return t.push(`constants_${n}`),t}case"this.constants.value[]":case"this.constants.value[][]":case"this.constants.value[][][]":case"this.constants.value[][][][]":break;case"fn()[]":return this.astCallExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(r)),t.push("]"),t;case"[][]":return this.astArrayExpression(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(r)),t.push("]"),t;default:throw this.astErrorOutput("Unexpected expression",e)}if(!1===e.computed)switch(a){case"Number":case"Integer":case"Float":case"Boolean":return t.push(`${s}_${n}`),t}const h=`${s}_${n}`;switch(a){case"Array(2)":case"Array(3)":case"Array(4)":this.astGeneric(e.object,t),t.push("["),t.push(this.memberExpressionPropertyMarkup(o)),t.push("]");break;case"HTMLImageArray":t.push(`getImage3D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(1)":t.push(`getFloatFromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(2)":case"Array2D(2)":case"Array3D(2)":t.push(`getMemoryOptimizedVec2(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(2)":t.push(`getVec2FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(3)":case"Array2D(3)":case"Array3D(3)":t.push(`getMemoryOptimizedVec3(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(3)":t.push(`getVec3FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"Array1D(4)":case"Array2D(4)":case"Array3D(4)":t.push(`getMemoryOptimizedVec4(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"ArrayTexture(4)":case"HTMLImage":case"HTMLVideo":t.push(`getVec4FromSampler2D(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;case"NumberTexture":case"Array":case"Array2D":case"Array3D":case"Array4D":case"Input":case"Number":case"Float":case"Integer":if("single"===this.precision)t.push(`getMemoryOptimized32(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");else{const e="user"===s?this.lookupFunctionArgumentBitRatio(this.name,n):this.constantBitRatios[n];switch(e){case 1:t.push(`get8(${h}, ${h}Size, ${h}Dim, `);break;case 2:t.push(`get16(${h}, ${h}Size, ${h}Dim, `);break;case 4:case 0:t.push(`get32(${h}, ${h}Size, ${h}Dim, `);break;default:throw new Error(`unhandled bit ratio of ${e}`)}this.memberExpressionXYZ(o,u,l,t),t.push(")")}break;case"MemoryOptimizedNumberTexture":t.push(`getMemoryOptimized32(${h}, ${h}Size, ${h}Dim, `),this.memberExpressionXYZ(o,u,l,t),t.push(")");break;default:throw new Error(`unhandled member expression "${a}"`)}return t}astCallExpression(e,t){if(!e.callee)throw this.astErrorOutput("Unknown CallExpression",e);let r=null;const n=this.isAstMathFunction(e);if(!(r=n||e.callee.object&&"ThisExpression"===e.callee.object.type?e.callee.property.name:"SequenceExpression"!==e.callee.type||"Literal"!==e.callee.expressions[0].type||isNaN(e.callee.expressions[0].raw)?e.callee.name:e.callee.expressions[1].property.name))throw this.astErrorOutput("Unhandled function, couldn't find name",e);if("atan2"===r&&(r="atan"),this.calledFunctions.indexOf(r)<0&&this.calledFunctions.push(r),"random"===r&&this.plugins&&this.plugins.length>0)for(let e=0;e0&&t.push(", "),i){case"Integer":this.castValueToFloat(n,t);break;default:this.astGeneric(n,t)}}else{const n=this.lookupFunctionArgumentTypes(r)||[];for(let i=0;i0&&t.push(", ");const o=this.getType(s);switch(a||(this.triggerImplyArgumentType(r,i,o,this),a=o),o){case"Number":case"Float":if("Integer"===a){t.push("int("),this.astGeneric(s,t),t.push(")");continue}if("Number"===a||"Float"===a){this.astGeneric(s,t);continue}if("LiteralInteger"===a){this.castLiteralToFloat(s,t);continue}break;case"Integer":if("Number"===a||"Float"===a){t.push("float("),this.astGeneric(s,t),t.push(")");continue}if("Integer"===a){this.astGeneric(s,t);continue}break;case"LiteralInteger":if("Integer"===a){this.castLiteralToInteger(s,t);continue}if("Number"===a||"Float"===a){this.castLiteralToFloat(s,t);continue}if("LiteralInteger"===a){this.astGeneric(s,t);continue}break;case"Array(2)":case"Array(3)":case"Array(4)":if(a===o){if("Identifier"!==s.type)throw this.astErrorOutput(`Unhandled argument type ${s.type}`,e);this.triggerImplyArgumentBitRatio(this.name,s.name,r,i),t.push(`user_${s.name}`);continue}break;case"HTMLImage":case"HTMLImageArray":case"HTMLVideo":case"ArrayTexture(1)":case"ArrayTexture(2)":case"ArrayTexture(3)":case"ArrayTexture(4)":case"Array":case"Input":if(a===o){if("Identifier"!==s.type)throw this.astErrorOutput(`Unhandled argument type ${s.type}`,e);this.triggerImplyArgumentBitRatio(this.name,s.name,r,i),t.push(`user_${s.name},user_${s.name}Size,user_${s.name}Dim`);continue}}throw this.astErrorOutput(`Unhandled argument combination of ${o} and ${a} for argument named "${s.name}"`,e)}}return t.push(")"),t}astArrayExpression(e,t){const r=e.elements.length;t.push("vec"+r+"(");for(let n=0;n0&&t.push(", ");const r=e.elements[n];this.astGeneric(r,t)}return t.push(")"),t}memberExpressionXYZ(e,t,r,n){return r?n.push(this.memberExpressionPropertyMarkup(r),", "):n.push("0, "),t?n.push(this.memberExpressionPropertyMarkup(t),", "):n.push("0, "),n.push(this.memberExpressionPropertyMarkup(e)),n}memberExpressionPropertyMarkup(e){if(!e)throw new Error("Property not set");const t=[];switch(this.getType(e)){case"Number":case"Float":this.castValueToInteger(e,t);break;case"LiteralInteger":this.castLiteralToInteger(e,t);break;default:this.astGeneric(e,t)}return t.join("")}}const oe={Array:"sampler2D","Array(2)":"vec2","Array(3)":"vec3","Array(4)":"vec4",Array2D:"sampler2D",Array3D:"sampler2D",Boolean:"bool",Float:"float",Input:"sampler2D",Integer:"int",Number:"float",LiteralInteger:"float",NumberTexture:"sampler2D",MemoryOptimizedNumberTexture:"sampler2D","ArrayTexture(1)":"sampler2D","ArrayTexture(2)":"sampler2D","ArrayTexture(3)":"sampler2D","ArrayTexture(4)":"sampler2D",HTMLVideo:"sampler2D",HTMLImage:"sampler2D",HTMLImageArray:"sampler2DArray"},ue={"===":"==","!==":"!="};var le={name:"triangle-noise-noise",onBeforeRun:e=>{e.setUniform1f("triangle_noise_seed",Math.random())},functionMatch:"Math.random()",functionReplace:"n4rand(vTexCoord)",functionReturnType:"Number",source:"\n\nuniform highp float triangle_noise_seed;\nhighp float triangle_noise_shift = 0.000001;\n\n//https://www.shadertoy.com/view/4t2SDh\n//note: uniformly distributed, normalized rand, [0;1[\nfloat nrand( vec2 n )\n{\n return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);\n}\n//note: remaps v to [0;1] in interval [a;b]\nfloat remap( float a, float b, float v )\n{\n return clamp( (v-a) / (b-a), 0.0, 1.0 );\n}\n\nfloat n4rand( vec2 n )\n{\n float t = fract( triangle_noise_seed + triangle_noise_shift );\n float nrnd0 = nrand( n + 0.07*t );\n float nrnd1 = nrand( n + 0.11*t );\n float nrnd2 = nrand( n + 0.13*t );\n float nrnd3 = nrand( n + 0.17*t );\n float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0;\n triangle_noise_shift = result + 0.000001;\n return result;\n}"};const he="__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nvarying vec2 vTexCoord;\n\nvec4 round(vec4 x) {\n return floor(x + 0.5);\n}\n\nfloat round(float x) {\n return floor(x + 0.5);\n}\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n int result = 0;\n int n = 1;\n\n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n;\n }\n a = a / 2;\n n = n * 2;\n }\n return result;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x / y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\n return 0.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n if (channel == 0) return texel.r * 255.0;\n if (channel == 1) return texel.g * 255.0;\n if (channel == 2) return texel.b * 255.0;\n if (channel == 3) return texel.a * 255.0;\n return 0.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n\n mantissa = value*pow(2.0, -exponent)-1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return texel.r;\n if (channel == 1) return texel.g;\n if (channel == 2) return texel.b;\n if (channel == 3) return texel.a;\n return 0.0;\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture2D(tex, st / vec2(texSize));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture2D(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\nvoid color(sampler2D image) {\n actualColor = texture2D(image, vTexCoord);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}",ce="__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nattribute vec2 aPos;\nattribute vec2 aTexCoord;\n\nvarying vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}";var pe=function(e,t){return e(t={exports:{}},t.exports),t.exports}((function(e){function t(e,t={}){const{contextName:s="gl",throwGetError:a,useTrackablePrimitives:o,readPixelsFile:u,recording:l=[],variables:h={},onReadPixels:c,onUnrecognizedArgumentLookup:p}=t,d=new Proxy(e,{get:function(t,d){switch(d){case"addComment":return D;case"checkThrowError":return $;case"getReadPixelsVariableName":return f;case"insertVariable":return A;case"reset":return b;case"setIndent":return S;case"toString":return T;case"getContextVariableName":return I}if("function"==typeof e[d])return function(){switch(d){case"getError":return a?l.push(`${y}if (${s}.getError() !== ${s}.NONE) throw new Error('error');`):l.push(`${y}${s}.getError();`),e.getError();case"getExtension":{const t=`${s}Variables${m.length}`;l.push(`${y}const ${t} = ${s}.getExtension('${arguments[0]}');`);const n=e.getExtension(arguments[0]);if(n&&"object"==typeof n){const e=r(n,{getEntity:E,useTrackablePrimitives:o,recording:l,contextName:t,contextVariables:m,variables:h,indent:y,onUnrecognizedArgumentLookup:p});return m.push(e),e}return m.push(null),n}case"readPixels":const t=m.indexOf(arguments[6]);let i;if(-1===t){const e=R(arguments[6]);e?(i=e,l.push(`${y}${e}`)):(i=`${s}Variable${m.length}`,m.push(arguments[6]),l.push(`${y}const ${i} = new ${arguments[6].constructor.name}(${arguments[6].length});`))}else i=`${s}Variable${t}`;f=i;const d=[arguments[0],arguments[1],arguments[2],arguments[3],E(arguments[4]),E(arguments[5]),i];return l.push(`${y}${s}.readPixels(${d.join(", ")});`),u&&v(arguments[2],arguments[3]),c&&c(i,d),e.readPixels.apply(e,arguments);case"drawBuffers":return l.push(`${y}${s}.drawBuffers([${n(arguments[0],{contextName:s,contextVariables:m,getEntity:E,addVariable:_,variables:h,onUnrecognizedArgumentLookup:p})}]);`),e.drawBuffers(arguments[0])}let t=e[d].apply(e,arguments);switch(typeof t){case"undefined":return void l.push(`${y}${w(d,arguments)};`);case"number":case"boolean":if(o&&-1===m.indexOf(i(t))){l.push(`${y}const ${s}Variable${m.length} = ${w(d,arguments)};`),m.push(t=i(t));break}default:null===t?l.push(`${w(d,arguments)};`):l.push(`${y}const ${s}Variable${m.length} = ${w(d,arguments)};`),m.push(t)}return t};return g[e[d]]=d,e[d]}}),m=[],g={};let f,x=0,y="";return d;function T(){return l.join("\n")}function b(){for(;l.length>0;)l.pop()}function A(e,t){h[e]=t}function E(e){const t=g[e];return t?s+"."+t:e}function S(e){y=" ".repeat(e)}function _(e,t){const r=`${s}Variable${m.length}`;return l.push(`${y}const ${r} = ${t};`),m.push(e),r}function v(e,t){const r=`${s}Variable${m.length}`,n=`imageDatum${x}`;l.push(`${y}let ${n} = ["P3\\n# ${u}.ppm\\n", ${e}, ' ', ${t}, "\\n255\\n"].join("");`),l.push(`${y}for (let i = 0; i < ${n}.length; i += 4) {`),l.push(`${y} ${n} += ${r}[i] + ' ' + ${r}[i + 1] + ' ' + ${r}[i + 2] + ' ';`),l.push(`${y}}`),l.push(`${y}if (typeof require !== "undefined") {`),l.push(`${y} require('fs').writeFileSync('./${u}.ppm', ${n});`),l.push(`${y}}`),x++}function D(e){l.push(`${y}// ${e}`)}function $(){l.push(`${y}(() => {\n${y}const error = ${s}.getError();\n${y}if (error !== ${s}.NONE) {\n${y} const names = Object.getOwnPropertyNames(gl);\n${y} for (let i = 0; i < names.length; i++) {\n${y} const name = names[i];\n${y} if (${s}[name] === error) {\n${y} throw new Error('${s} threw ' + name);\n${y} }\n${y} }\n${y}}\n${y}})();`)}function w(e,t){return`${s}.${e}(${n(t,{contextName:s,contextVariables:m,getEntity:E,addVariable:_,variables:h,onUnrecognizedArgumentLookup:p})})`}function R(e){if(h)for(const t in h)if(h[t]===e)return t;return null}function I(e){const t=m.indexOf(e);return-1!==t?`${s}Variable${t}`:null}}function r(e,t){const r=new Proxy(e,{get:function(t,r){if("function"==typeof t[r])return function(){switch(r){case"drawBuffersWEBGL":return h.push(`${p}${a}.drawBuffersWEBGL([${n(arguments[0],{contextName:a,contextVariables:o,getEntity:m,addVariable:f,variables:c,onUnrecognizedArgumentLookup:d})}]);`),e.drawBuffersWEBGL(arguments[0])}let t=e[r].apply(e,arguments);switch(typeof t){case"undefined":return void h.push(`${p}${g(r,arguments)};`);case"number":case"boolean":l&&-1===o.indexOf(i(t))?(h.push(`${p}const ${a}Variable${o.length} = ${g(r,arguments)};`),o.push(t=i(t))):(h.push(`${p}const ${a}Variable${o.length} = ${g(r,arguments)};`),o.push(t));break;default:null===t?h.push(`${g(r,arguments)};`):h.push(`${p}const ${a}Variable${o.length} = ${g(r,arguments)};`),o.push(t)}return t};return s[e[r]]=r,e[r]}}),s={},{contextName:a,contextVariables:o,getEntity:u,useTrackablePrimitives:l,recording:h,variables:c,indent:p,onUnrecognizedArgumentLookup:d}=t;return r;function m(e){return s.hasOwnProperty(e)?`${a}.${s[e]}`:u(e)}function g(e,t){return`${a}.${e}(${n(t,{contextName:a,contextVariables:o,getEntity:m,addVariable:f,variables:c,onUnrecognizedArgumentLookup:d})})`}function f(e,t){const r=`${a}Variable${o.length}`;return o.push(e),h.push(`${p}const ${r} = ${t};`),r}}function n(e,t){const{variables:r,onUnrecognizedArgumentLookup:n}=t;return Array.from(e).map(e=>{const i=function(e){if(r)for(const t in r)if(r.hasOwnProperty(t)&&r[t]===e)return t;if(n)return n(e);return null}(e);return i||function(e,t){const{contextName:r,contextVariables:n,getEntity:i,addVariable:s,onUnrecognizedArgumentLookup:a}=t;if(void 0===e)return"undefined";if(null===e)return"null";const o=n.indexOf(e);if(o>-1)return`${r}Variable${o}`;switch(e.constructor.name){case"String":const t=/\n/.test(e),r=/'/.test(e),n=/"/.test(e);return t?"`"+e+"`":r&&!n?'"'+e+'"':"'"+e+"'";case"Number":case"Boolean":return i(e);case"Array":return s(e,`new ${e.constructor.name}([${Array.from(e).join(",")}])`);case"Float32Array":case"Uint8Array":case"Uint16Array":case"Int32Array":return s(e,`new ${e.constructor.name}(${JSON.stringify(Array.from(e))})`);default:if(a){const t=a(e);if(t)return t}throw new Error(`unrecognized argument type ${e.constructor.name}`)}}(e,t)}).join(", ")}function i(e){return new e.constructor(e)}e.exports={glWiretap:t,glExtensionWiretap:r},"undefined"!=typeof window&&(t.glExtensionWiretap=r,window.glWiretap=t)})),de=pe.glWiretap;pe.glExtensionWiretap;function me(e){return e.toString().replace("=>","").replace(/^function /,"").replace(/utils[.]/g,"/*utils.*/")}function ge(e,t,r,n,i){t=t?Array.from(t).map(e=>{switch(typeof e){case"boolean":return new Boolean(e);case"number":return new Number(e);default:return e}}):null;const s=[],a=de(r.context,{useTrackablePrimitives:!0,onReadPixels:e=>{if($.subKernels){if(o){const t=$.subKernels[u++].property;s.push(` result${isNaN(t)?"."+t:`[${t}]`} = ${fe(e,$)};`)}else s.push(` const result = { result: ${fe(e,$)} };`),o=!0;u===$.subKernels.length&&s.push(" return result;")}else e?s.push(` return ${fe(e,$)};`):s.push(" return null;")},onUnrecognizedArgumentLookup:e=>{const t=ye(e,$.kernelArguments,[],a);if(t)return t;const r=ye(e,$.kernelConstants,g?Object.keys(g).map(e=>g[e]):[],a);return r||null}});let o=!1,u=0;const{source:l,canvas:h,output:c,pipeline:p,graphical:d,loopMaxIterations:m,constants:g,optimizeFloatMemory:f,precision:x,fixIntegerDivisionAccuracy:y,functions:T,nativeFunctions:b,subKernels:A,immutable:E,argumentTypes:S,constantTypes:_,kernelArguments:v,kernelConstants:D}=r,$=new e(l,{canvas:h,context:a,checkContext:!1,output:c,pipeline:p,graphical:d,loopMaxIterations:m,constants:g,optimizeFloatMemory:f,precision:x,fixIntegerDivisionAccuracy:y,functions:T,nativeFunctions:b,subKernels:A,immutable:E,argumentTypes:S,constantTypes:_});let w=[];if(a.setIndent(2),$.build.apply($,t),w.push(a.toString()),a.reset(),$.kernelArguments.forEach((e,r)=>{switch(e.type){case"Integer":case"Boolean":case"Number":case"Float":case"Array":case"Array(2)":case"Array(3)":case"Array(4)":case"HTMLImage":case"HTMLVideo":a.insertVariable(`uploadValue_${e.name}`,e.uploadValue);break;case"HTMLImageArray":for(let n=0;ne.varName).join(", ")}) {`),a.setIndent(4),$.run.apply($,t),$.renderKernels?$.renderKernels():$.renderOutput&&$.renderOutput(),w.push(" /** start setup uploads for kernel values **/"),$.kernelArguments.forEach(e=>{w.push(" "+e.getStringValueHandler().split("\n").join("\n "))}),w.push(" /** end setup uploads for kernel values **/"),w.push(a.toString()),$.renderOutput===$.renderTexture){a.reset();const e=$.renderKernels(),t=a.getContextVariableName($.outputTexture);w.push(` return {\n result: {\n texture: ${t},\n type: '${e.result.type}',\n toArray: ${xe(e.result,t)}\n },`);const{subKernels:r,subKernelOutputTextures:n}=$;for(let t=0;t"utils"===e?`const ${t} = ${R[t].toString()};`:null,thisLookup:t=>{if("context"===t)return null;if(e.hasOwnProperty(t))return JSON.stringify(e[t]);throw new Error(`unhandled thisLookup ${t}`)}})}($)),w.push(" innerKernel.getPixels = getPixels;")),w.push(" return innerKernel;");let I=[];return D.forEach(e=>{I.push(`${e.getStringValueHandler()}`)}),`function kernel(settings) {\n const { context, constants } = settings;\n ${I.join("")}\n ${n||""}\n${w.join("\n")}\n}`}function fe(e,t){const r="single"===t.precision?e:`new Float32Array(${e}.buffer)`;return t.output[2]?`renderOutput(${r}, ${t.output[0]}, ${t.output[1]}, ${t.output[2]})`:t.output[1]?`renderOutput(${r}, ${t.output[0]}, ${t.output[1]})`:`renderOutput(${r}, ${t.output[0]})`}function xe(e,t){const r=e.toArray.toString(),n=!/^function/.test(r);return`() => {\n ${R.flattenFunctionToString(`${n?"function ":""}${r}`,{findDependency:(t,r)=>{if("utils"===t)return`const ${r} = ${R[r].toString()};`;if("this"===t)return`${n?"function ":""}${e[r].toString()}`;throw new Error("unhandled fromObject")},thisLookup:r=>{if("texture"===r)return t;if(e.hasOwnProperty(r))return JSON.stringify(e[r]);throw new Error(`unhandled thisLookup ${r}`)}})}\n return toArray();\n }`}function ye(e,t,r,n,i){if(null===e)return null;switch(typeof e){case"boolean":case"number":return null}if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement){for(let i=0;ir||t>r)throw e>t?new Error(`Argument width of ${e} larger than maximum size of ${r} for your GPU`):new Error(`Argument height of ${t} larger than maximum size of ${r} for your GPU`)}requestTexture(){this.texture=this.onRequestTexture(),this.setupTexture()}setupTexture(){this.contextHandle=this.onRequestContextHandle(),this.index=this.onRequestIndex(),this.dimensionsId=this.id+"Dim",this.sizeId=this.id+"Size"}getTransferArrayType(e){if(Array.isArray(e[0]))return this.getTransferArrayType(e[0]);switch(e.constructor){case Array:case Int32Array:case Int16Array:case Int8Array:return Float32Array;case Uint8ClampedArray:case Uint8Array:case Uint16Array:case Uint32Array:case Float32Array:case Float64Array:return e.constructor}return console.warn("Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros"),e.constructor}formatArrayTransfer(e,t,r){if(R.isArray(e[0])||this.optimizeFloatMemory){const r=new Float32Array(t);return R.flattenTo(e,r),r}switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:case Uint16Array:case Int16Array:case Float32Array:case Int32Array:{const n=new(r||e.constructor)(t);return R.flattenTo(e,n),n}default:{const r=new Float32Array(t);return R.flattenTo(e,r),r}}}getBitRatio(e){if(Array.isArray(e[0]))return this.getBitRatio(e[0]);if(e.constructor===_)return this.getBitRatio(e.value);switch(e.constructor){case Uint8ClampedArray:case Uint8Array:case Int8Array:return 1;case Uint16Array:case Int16Array:return 2;case Float32Array:case Int32Array:default:return 4}}getStringValueHandler(){throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`)}getVariablePrecisionString(){switch(this.tactic){case"speed":return"lowp";case"performance":return"highp";case"balanced":default:return"mediump"}}}class Ae extends be{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const bool ${this.id} = ${e};\n`:`uniform bool ${this.id};\n`}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}class Ee extends be{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?Number.isInteger(e)?`const float ${this.id} = ${e}.0;\n`:`const float ${this.id} = ${e};\n`:`uniform float ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1f(this.id,this.uploadValue=e)}}class Se extends be{constructor(e,t){super(e,t),this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(e){return"constants"===this.origin?`const int ${this.id} = ${parseInt(e)};\n`:`uniform int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}class _e extends be{constructor(e,t){super(e,t);const{width:r,height:n}=e;this.checkSize(r,n),this.dimensions=[r,n,1],this.requestTexture(),this.textureSize=[r,n],this.uploadValue=e}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue=e),this.kernel.setUniform1i(this.id,this.index)}}class ve extends _e{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){const{width:t,height:r}=e;this.checkSize(t,r),this.dimensions=[t,r,1],this.textureSize=[t,r],this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class De extends _e{}class $e extends ve{}class we extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4;let[r,n,i]=e.size;this.dimensions=new Int32Array([r||1,n||1,i||1]),this.textureSize=R.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}.value, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flattenTo(e.value,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Re extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=this.getBitRatio(e);const[r,n,i]=e.size;this.dimensions=new Int32Array([r||1,n||1,i||1]),this.textureSize=R.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio)),this.TranserArrayType=this.getTransferArrayType(e.value),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return R.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}.value, preUploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flattenTo(e.value,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Ie extends Re{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,r,n]=e.size;this.dimensions=new Int32Array([t||1,r||1,n||1]),this.textureSize=R.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio));const i=this.getTransferArrayType(e.value);this.preUploadValue=new i(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Fe extends be{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n),this.setupTexture(),this.dimensions=e.dimensions,this.textureSize=e.size,this.uploadValue=e.texture,this.forceUploadEachRun=!0}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.uploadValue=e.texture),this.kernel.setUniform1i(this.id,this.index)}}class ze extends Fe{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.checkSize(e.size[0],e.size[1]),this.dimensions=e.dimensions,this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Oe extends be{constructor(e,t){super(e,t);const[r,n]=e.size;this.checkSize(r,n),this.setupTexture();const{size:i,dimensions:s}=e;this.bitRatio=this.getBitRatio(e),this.dimensions=s,this.textureSize=i,this.uploadValue=e.texture,this.forceUploadEachRun=!0}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName}.texture;\n`}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();if(this.checkContext&&e.context!==this.context)throw new Error(`Value ${this.name} (${this.type}) must be from same context`);const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.uploadValue=e.texture),this.kernel.setUniform1i(this.id,this.index)}}class Ce extends Oe{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=e.dimensions,this.checkSize(e.size[0],e.size[1]),this.textureSize=e.size,this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Ne extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.dimensions=R.getDimensions(e,!0),this.textureSize=R.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flattenTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class ke extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=R.getDimensions(e,!0);this.textureSize=R.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],1,1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flatten2dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Me extends ke{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Ue extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=R.getDimensions(e,!0);this.textureSize=R.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],1]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flatten3dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Pe extends Ue{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Le extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=4,this.setShape(e)}setShape(e){const t=R.getDimensions(e,!0);this.textureSize=R.getMemoryOptimizedFloatTextureSize(t,this.bitRatio),this.dimensions=new Int32Array([t[1],t[2],t[3]]),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength)}getStringValueHandler(){return R.linesToString([`const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,`flattenTo(${this.varName}, uploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flatten4dArrayTo(e,this.uploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.FLOAT,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class Ve extends Le{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.setShape(e),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}class Ke extends be{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec2 ${this.id} = vec2(${e[0]},${e[1]});\n`:`uniform vec2 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform2fv(this.id,this.uploadValue=e)}}class Ge extends be{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec3 ${this.id} = vec3(${e[0]},${e[1]},${e[2]});\n`:`uniform vec3 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform3fv(this.id,this.uploadValue=e)}}class Be extends be{constructor(e,t){super(e,t),this.uploadValue=e}getSource(e){return"constants"===this.origin?`const vec4 ${this.id} = vec4(${e[0]},${e[1]},${e[2]},${e[3]});\n`:`uniform vec4 ${this.id};\n`}getStringValueHandler(){return"constants"===this.origin?"":`const uploadValue_${this.name} = ${this.varName};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform4fv(this.id,this.uploadValue=e)}}class Xe extends be{constructor(e,t){super(e,t),this.requestTexture(),this.bitRatio=this.getBitRatio(e),this.dimensions=R.getDimensions(e,!0),this.textureSize=R.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio)),this.TranserArrayType=this.getTransferArrayType(e),this.preUploadValue=new this.TranserArrayType(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer)}getStringValueHandler(){return R.linesToString([`const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,`const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,`flattenTo(${this.varName}, preUploadValue_${this.name})`])}getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){if(e.constructor!==this.initialValueConstructor)return void this.onUpdateValueMismatch();const{context:t}=this;R.flattenTo(e,this.preUploadValue),t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,this.textureSize[0],this.textureSize[1],0,t.RGBA,t.UNSIGNED_BYTE,this.uploadValue),this.kernel.setUniform1i(this.id,this.index)}}class je extends Xe{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=R.getDimensions(e,!0),this.textureSize=R.getMemoryOptimizedPackedTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*(4/this.bitRatio),this.checkSize(this.textureSize[0]*(4/this.bitRatio),this.textureSize[1]*(4/this.bitRatio));const t=this.getTransferArrayType(e);this.preUploadValue=new t(this.uploadArrayLength),this.uploadValue=new Uint8Array(this.preUploadValue.buffer),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}}const He={unsigned:{dynamic:{Boolean:Ae,Integer:Se,Float:Ee,Array:je,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:Ie,NumberTexture:Ce,"ArrayTexture(1)":Ce,"ArrayTexture(2)":Ce,"ArrayTexture(3)":Ce,"ArrayTexture(4)":Ce,MemoryOptimizedNumberTexture:Fe,HTMLImage:ve,HTMLImageArray:!1,HTMLVideo:$e},static:{Boolean:Ae,Float:Ee,Integer:Se,Array:Xe,"Array(2)":!1,"Array(3)":!1,"Array(4)":!1,"Array1D(2)":!1,"Array1D(3)":!1,"Array1D(4)":!1,"Array2D(2)":!1,"Array2D(3)":!1,"Array2D(4)":!1,"Array3D(2)":!1,"Array3D(3)":!1,"Array3D(4)":!1,Input:Re,NumberTexture:Oe,"ArrayTexture(1)":Oe,"ArrayTexture(2)":Oe,"ArrayTexture(3)":Oe,"ArrayTexture(4)":Oe,MemoryOptimizedNumberTexture:ze,HTMLImage:_e,HTMLImageArray:!1,HTMLVideo:De}},single:{dynamic:{Boolean:Ae,Integer:Se,Float:Ee,Array:class extends Ne{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){this.dimensions=R.getDimensions(e,!0),this.textureSize=R.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}},"Array(2)":Ke,"Array(3)":Ge,"Array(4)":Be,"Array1D(2)":Me,"Array1D(3)":Me,"Array1D(4)":Me,"Array2D(2)":Pe,"Array2D(3)":Pe,"Array2D(4)":Pe,"Array3D(2)":Ve,"Array3D(3)":Ve,"Array3D(4)":Ve,Input:class extends we{getSource(){return R.linesToString([`uniform sampler2D ${this.id}`,`uniform ivec2 ${this.sizeId}`,`uniform ivec3 ${this.dimensionsId}`])}updateValue(e){let[t,r,n]=e.size;this.dimensions=new Int32Array([t||1,r||1,n||1]),this.textureSize=R.getMemoryOptimizedFloatTextureSize(this.dimensions,this.bitRatio),this.uploadArrayLength=this.textureSize[0]*this.textureSize[1]*this.bitRatio,this.checkSize(this.textureSize[0]*this.bitRatio,this.textureSize[1]*this.bitRatio),this.uploadValue=new Float32Array(this.uploadArrayLength),this.kernel.setUniform3iv(this.dimensionsId,this.dimensions),this.kernel.setUniform2iv(this.sizeId,this.textureSize),super.updateValue(e)}},NumberTexture:Ce,"ArrayTexture(1)":Ce,"ArrayTexture(2)":Ce,"ArrayTexture(3)":Ce,"ArrayTexture(4)":Ce,MemoryOptimizedNumberTexture:ze,HTMLImage:ve,HTMLImageArray:!1,HTMLVideo:$e},static:{Boolean:Ae,Float:Ee,Integer:Se,Array:Ne,"Array(2)":Ke,"Array(3)":Ge,"Array(4)":Be,"Array1D(2)":ke,"Array1D(3)":ke,"Array1D(4)":ke,"Array2D(2)":Ue,"Array2D(3)":Ue,"Array2D(4)":Ue,"Array3D(2)":Le,"Array3D(3)":Le,"Array3D(4)":Le,Input:we,NumberTexture:Oe,"ArrayTexture(1)":Oe,"ArrayTexture(2)":Oe,"ArrayTexture(3)":Oe,"ArrayTexture(4)":Oe,MemoryOptimizedNumberTexture:Fe,HTMLImage:_e,HTMLImageArray:!1,HTMLVideo:De}}};let We=null,qe=null,Ye=null,Je=null,Ze=null;const Qe=[le],et=[],tt={};class rt extends ne{static get isSupported(){return null!==We?We:(this.setupFeatureChecks(),We=this.isContextMatch(Ye))}static setupFeatureChecks(){"undefined"!=typeof document?qe=document.createElement("canvas"):"undefined"!=typeof OffscreenCanvas&&(qe=new OffscreenCanvas(0,0)),qe&&(Ye=qe.getContext("webgl")||qe.getContext("experimental-webgl"))&&Ye.getExtension&&(Je={OES_texture_float:Ye.getExtension("OES_texture_float"),OES_texture_float_linear:Ye.getExtension("OES_texture_float_linear"),OES_element_index_uint:Ye.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:Ye.getExtension("WEBGL_draw_buffers")},Ze=this.getFeatures())}static isContextMatch(e){return"undefined"!=typeof WebGLRenderingContext&&e instanceof WebGLRenderingContext}static getFeatures(){const e=this.getIsDrawBuffers();return Object.freeze({isFloatRead:this.getIsFloatRead(),isIntegerDivisionAccurate:this.getIsIntegerDivisionAccurate(),isTextureFloat:this.getIsTextureFloat(),isDrawBuffers:e,kernelMap:e,channelCount:this.getChannelCount()})}static getIsTextureFloat(){return Boolean(Je.OES_texture_float)}static getIsDrawBuffers(){return Boolean(Je.WEBGL_draw_buffers)}static getChannelCount(){return Je.WEBGL_draw_buffers?Ye.getParameter(Je.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL):1}static lookupKernelValueType(e,t,r,n){return function(e,t,r,n){if(!e)throw new Error("type missing");if(!t)throw new Error("dynamic missing");if(!r)throw new Error("precision missing");n.type&&(e=n.type);const i=He[r][t];if(!1===i[e])return null;if(void 0===i[e])throw new Error(`Could not find a KernelValue for ${e}`);return i[e]}(e,t,r,n)}static get testCanvas(){return qe}static get testContext(){return Ye}static get features(){return Ze}static get fragmentShader(){return he}static get vertexShader(){return ce}constructor(e,t){super(e,t),this.program=null,this.pipeline=t.pipeline,this.endianness=R.systemEndianness(),this.extensions={},this.subKernelOutputTextures=null,this.kernelArguments=null,this.argumentTextureCount=0,this.constantTextureCount=0,this.compiledFragmentShader=null,this.compiledVertexShader=null,this.fragShader=null,this.vertShader=null,this.drawBuffersMap=null,this.outputTexture=null,this.maxTexSize=null,this.switchingKernels=!1,this.onRequestSwitchKernel=null,this.mergeSettings(e.settings||t),this.threadDim=null,this.framebuffer=null,this.buffer=null,this.textureCache={},this.programUniformLocationCache={},this.uniform1fCache={},this.uniform1iCache={},this.uniform2fCache={},this.uniform2fvCache={},this.uniform2ivCache={},this.uniform3fvCache={},this.uniform3ivCache={},this.uniform4fvCache={},this.uniform4ivCache={}}initCanvas(){if("undefined"!=typeof document){const e=document.createElement("canvas");return e.width=2,e.height=2,e}if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(0,0)}initContext(){const e={alpha:!1,depth:!1,antialias:!1};return this.canvas.getContext("webgl",e)||this.canvas.getContext("experimental-webgl",e)}initPlugins(e){const t=[],{source:r}=this;if("string"==typeof r)for(let e=0;ee===n.name)&&t.push(n)}return t}initExtensions(){this.extensions={OES_texture_float:this.context.getExtension("OES_texture_float"),OES_texture_float_linear:this.context.getExtension("OES_texture_float_linear"),OES_element_index_uint:this.context.getExtension("OES_element_index_uint"),WEBGL_draw_buffers:this.context.getExtension("WEBGL_draw_buffers"),WEBGL_color_buffer_float:this.context.getExtension("WEBGL_color_buffer_float")}}validateSettings(e){if(!this.validate)return void(this.texSize=R.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output));const{features:t}=this.constructor;if(!0===this.optimizeFloatMemory&&!t.isTextureFloat)throw new Error("Float textures are not supported");if("single"===this.precision&&!t.isFloatRead)throw new Error("Single precision not supported");if(!this.graphical&&null===this.precision&&t.isTextureFloat&&(this.precision=t.isFloatRead?"single":"unsigned"),this.subKernels&&this.subKernels.length>0&&!this.extensions.WEBGL_draw_buffers)throw new Error("could not instantiate draw buffers extension");if(null===this.fixIntegerDivisionAccuracy?this.fixIntegerDivisionAccuracy=!t.isIntegerDivisionAccurate:this.fixIntegerDivisionAccuracy&&t.isIntegerDivisionAccurate&&(this.fixIntegerDivisionAccuracy=!1),this.checkOutput(),!this.output||0===this.output.length){if(1!==e.length)throw new Error("Auto output only supported for kernels with only one input");const t=R.getVariableType(e[0],this.strictIntegers);if("Array"===t)this.output=R.getDimensions(t);else{if("NumberTexture"!==t&&"ArrayTexture(4)"!==t)throw new Error("Auto output not supported for input type: "+t);this.output=e[0].output}}if(this.graphical){if(2!==this.output.length)throw new Error("Output must have 2 dimensions on graphical mode");return"precision"===this.precision&&(this.precision="unsigned",console.warn("Cannot use graphical mode and single precision at the same time")),void(this.texSize=R.clone(this.output))}null===this.precision&&t.isTextureFloat&&(this.precision="single"),this.texSize=R.getKernelTextureSize({optimizeFloatMemory:this.optimizeFloatMemory,precision:this.precision},this.output),this.checkTextureSize()}updateMaxTexSize(){const{texSize:e,canvas:t}=this;if(null===this.maxTexSize){let r=et.indexOf(t);-1===r&&(r=et.length,et.push(t),tt[r]=[e[0],e[1]]),this.maxTexSize=tt[r]}this.maxTexSize[0]Ze.channelCount)throw new Error("Too many channels!");return this.translatedSource=t}setupArguments(e){this.kernelArguments=[],this.argumentTextureCount=0;const t=null===this.argumentTypes;if(t&&(this.argumentTypes=[]),this.argumentSizes=[],this.argumentBitRatios=[],e.lengththis.argumentNames.length)throw new Error("too many arguments for kernel");const{context:r}=this;let n=0;for(let i=0;ithis.context.createTexture(),onRequestIndex:()=>n++,onUpdateValueMismatch:()=>{this.switchingKernels=!0},onRequestContextHandle:()=>r.TEXTURE0+this.constantTextureCount+this.argumentTextureCount++});this.kernelArguments.push(l),this.argumentSizes.push(l.textureSize),this.argumentBitRatios[i]=l.bitRatio}}setupConstants(e){const{context:t}=this;this.kernelConstants=[],this.forceUploadKernelConstants=[];let r=null===this.constantTypes;r&&(this.constantTypes={}),this.constantBitRatios={};let n=0;for(const i in this.constants){const s=this.constants[i];let a;r?(a=R.getVariableType(s,this.strictIntegers),this.constantTypes[i]=a):a=this.constantTypes[i];const o=this.constructor.lookupKernelValueType(a,"static",this.precision,s);if(null===o)return this.requestFallback(e);const u=new o(s,{name:i,type:a,tactic:this.tactic,origin:"constants",context:this.context,checkContext:this.checkContext,kernel:this,strictIntegers:this.strictIntegers,onRequestTexture:()=>this.context.createTexture(),onRequestIndex:()=>n++,onRequestContextHandle:()=>t.TEXTURE0+this.constantTextureCount++});this.constantBitRatios[i]=u.bitRatio,this.kernelConstants.push(u),u.forceUploadEachRun&&this.forceUploadKernelConstants.push(u)}}build(){if(this.initExtensions(),this.validateSettings(arguments),this.setupConstants(arguments),this.fallbackRequested)return;if(this.setupArguments(arguments),this.fallbackRequested)return;this.updateMaxTexSize(),this.translateSource();const e=this.pickRenderStrategy(arguments);if(e)return e;const{texSize:t,context:r,canvas:n}=this;r.enable(r.SCISSOR_TEST),this.pipeline&&this.precision,r.viewport(0,0,this.maxTexSize[0],this.maxTexSize[1]),n.width=this.maxTexSize[0],n.height=this.maxTexSize[1];const i=this.threadDim=Array.from(this.output);for(;i.length<3;)i.push(1);const s=this.getVertexShader(arguments),a=r.createShader(r.VERTEX_SHADER);r.shaderSource(a,s),r.compileShader(a),this.vertShader=a;const o=this.getFragmentShader(arguments),u=r.createShader(r.FRAGMENT_SHADER);if(r.shaderSource(u,o),r.compileShader(u),this.fragShader=u,this.debug&&(console.log("GLSL Shader Output:"),console.log(o)),!r.getShaderParameter(a,r.COMPILE_STATUS))throw new Error("Error compiling vertex shader: "+r.getShaderInfoLog(a));if(!r.getShaderParameter(u,r.COMPILE_STATUS))throw new Error("Error compiling fragment shader: "+r.getShaderInfoLog(u));const l=this.program=r.createProgram();r.attachShader(l,a),r.attachShader(l,u),r.linkProgram(l),this.framebuffer=r.createFramebuffer(),this.framebuffer.width=t[0],this.framebuffer.height=t[1];const h=new Float32Array([-1,-1,1,-1,-1,1,1,1]),c=new Float32Array([0,0,1,0,0,1,1,1]),p=h.byteLength;let d=this.buffer;d?r.bindBuffer(r.ARRAY_BUFFER,d):(d=this.buffer=r.createBuffer(),r.bindBuffer(r.ARRAY_BUFFER,d),r.bufferData(r.ARRAY_BUFFER,h.byteLength+c.byteLength,r.STATIC_DRAW)),r.bufferSubData(r.ARRAY_BUFFER,0,h),r.bufferSubData(r.ARRAY_BUFFER,p,c);const m=r.getAttribLocation(this.program,"aPos");r.enableVertexAttribArray(m),r.vertexAttribPointer(m,2,r.FLOAT,!1,0,0);const g=r.getAttribLocation(this.program,"aTexCoord");r.enableVertexAttribArray(g),r.vertexAttribPointer(g,2,r.FLOAT,!1,0,p),r.bindFramebuffer(r.FRAMEBUFFER,this.framebuffer);let f=0;r.useProgram(this.program);for(let e in this.constants)this.kernelConstants[f++].updateValue(this.constants[e]);this.immutable||(this._setupOutputTexture(),null!==this.subKernels&&this.subKernels.length>0&&this._setupSubOutputTextures())}translateSource(){const e=F.fromKernel(this,ae,{fixIntegerDivisionAccuracy:this.fixIntegerDivisionAccuracy});if(this.translatedSource=e.getPrototypeString("kernel"),this.graphical||this.returnType||(this.returnType=e.getKernelResultType()),this.subKernels&&this.subKernels.length>0)for(let t=0;te.source&&this.source.match(e.functionMatch)?e.source:"").join("\n"):"\n"}_getConstantsString(){const e=[],{threadDim:t,texSize:r}=this;return this.dynamicOutput?e.push("uniform ivec3 uOutputDim","uniform ivec2 uTexSize"):e.push(`ivec3 uOutputDim = ivec3(${t[0]}, ${t[1]}, ${t[2]})`,`ivec2 uTexSize = ivec2(${r[0]}, ${r[1]})`),R.linesToString(e)}_getTextureCoordinate(){const e=this.subKernels;return null===e||e.length<1?"varying vec2 vTexCoord;\n":"out vec2 vTexCoord;\n"}_getDecode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getEncode32EndiannessString(){return"LE"===this.endianness?"":" texel.rgba = texel.abgr;\n"}_getDivideWithIntegerCheckString(){return this.fixIntegerDivisionAccuracy?"float div_with_int_check(float x, float y) {\n if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\n return float(int(x)/int(y));\n }\n return x / y;\n}":""}_getMainArgumentsString(e){const t=[],{argumentNames:r}=this;for(let n=0;n{if(t.hasOwnProperty(r))return t[r];throw`unhandled artifact ${r}`})}getFragmentShader(e){return null!==this.compiledFragmentShader?this.compiledFragmentShader:this.compiledFragmentShader=this.replaceArtifacts(this.constructor.fragmentShader,this._getFragShaderArtifactMap(e))}getVertexShader(e){return null!==this.compiledVertexShader?this.compiledVertexShader:this.compiledVertexShader=this.replaceArtifacts(this.constructor.vertexShader,this._getVertShaderArtifactMap(e))}toString(){const e=R.linesToString(["const gl = context"]);return ge(this.constructor,arguments,this,e)}destroy(e){this.outputTexture&&this.context.deleteTexture(this.outputTexture),this.buffer&&this.context.deleteBuffer(this.buffer),this.framebuffer&&this.context.deleteFramebuffer(this.framebuffer),this.vertShader&&this.context.deleteShader(this.vertShader),this.fragShader&&this.context.deleteShader(this.fragShader),this.program&&this.context.deleteProgram(this.program);const t=Object.keys(this.textureCache);for(let e=0;e=0&&(et[e]=null,tt[e]=null)}this.destroyExtensions(),delete this.context,delete this.canvas}destroyExtensions(){this.extensions.OES_texture_float=null,this.extensions.OES_texture_float_linear=null,this.extensions.OES_element_index_uint=null,this.extensions.WEBGL_draw_buffers=null}static destroyContext(e){const t=e.getExtension("WEBGL_lose_context");t&&t.loseContext()}toJSON(){const e=super.toJSON();return e.functionNodes=F.fromKernel(this,ae).toJSON(),e}}class nt extends ae{astIdentifierExpression(e,t){if("Identifier"!==e.type)throw this.astErrorOutput("IdentifierExpression - not an Identifier",e);const r=this.getType(e);return"Infinity"===e.name?t.push("intBitsToFloat(2139095039)"):"Boolean"===r&&this.argumentNames.indexOf(e.name)>-1?t.push(`bool(user_${e.name})`):t.push(`user_${e.name}`),t}}const it="#version 300 es\n__HEADER__;\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\n\nconst int LOOP_MAX = __LOOP_MAX__;\n\n__PLUGINS__;\n__CONSTANTS__;\n\nin vec2 vTexCoord;\n\nconst int BIT_COUNT = 32;\nint modi(int x, int y) {\n return x - y * (x / y);\n}\n\nint bitwiseOr(int a, int b) {\n int result = 0;\n int n = 1;\n\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseXOR(int a, int b) {\n int result = 0;\n int n = 1;\n\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 || b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseAnd(int a, int b) {\n int result = 0;\n int n = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\n result += n;\n }\n a = a / 2;\n b = b / 2;\n n = n * 2;\n if(!(a > 0 && b > 0)) {\n break;\n }\n }\n return result;\n}\nint bitwiseNot(int a) {\n int result = 0;\n int n = 1;\n\n for (int i = 0; i < BIT_COUNT; i++) {\n if (modi(a, 2) == 0) {\n result += n;\n }\n a = a / 2;\n n = n * 2;\n }\n return result;\n}\nint bitwiseZeroFillLeftShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n *= 2;\n }\n\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nint bitwiseSignedRightShift(int num, int shifts) {\n return int(floor(float(num) / pow(2.0, float(shifts))));\n}\n\nint bitwiseZeroFillRightShift(int n, int shift) {\n int maxBytes = BIT_COUNT;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (maxBytes >= n) {\n break;\n }\n maxBytes *= 2;\n }\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= shift) {\n break;\n }\n n /= 2;\n }\n int result = 0;\n int byteVal = 1;\n for (int i = 0; i < BIT_COUNT; i++) {\n if (i >= maxBytes) break;\n if (modi(n, 2) > 0) { result += byteVal; }\n n = int(n / 2);\n byteVal *= 2;\n }\n return result;\n}\n\nvec2 integerMod(vec2 x, float y) {\n vec2 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec3 integerMod(vec3 x, float y) {\n vec3 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nvec4 integerMod(vec4 x, vec4 y) {\n vec4 res = floor(mod(x, y));\n return res * step(1.0 - floor(y), -res);\n}\n\nfloat integerMod(float x, float y) {\n float res = floor(mod(x, y));\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\n}\n\nint integerMod(int x, int y) {\n return x - (y * int(x/y));\n}\n\n__DIVIDE_WITH_INTEGER_CHECK__;\n\n// Here be dragons!\n// DO NOT OPTIMIZE THIS CODE\n// YOU WILL BREAK SOMETHING ON SOMEBODY'S MACHINE\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\nfloat decode32(vec4 texel) {\n __DECODE32_ENDIANNESS__;\n texel *= 255.0;\n vec2 gte128;\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\n float res = exp2(round(exponent));\n texel.b = texel.b - 128.0 * gte128.x;\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\n res *= gte128.y * -2.0 + 1.0;\n return res;\n}\n\nfloat decode16(vec4 texel, int index) {\n int channel = integerMod(index, 2);\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\n}\n\nfloat decode8(vec4 texel, int index) {\n int channel = integerMod(index, 4);\n return texel[channel] * 255.0;\n}\n\nvec4 legacyEncode32(float f) {\n float F = abs(f);\n float sign = f < 0.0 ? 1.0 : 0.0;\n float exponent = floor(log2(F));\n float mantissa = (exp2(-exponent) * F);\n // exponent += floor(log2(mantissa));\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\n texel.rg = integerMod(texel.rg, 256.0);\n texel.b = integerMod(texel.b, 128.0);\n texel.a = exponent*0.5 + 63.5;\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\n texel = floor(texel);\n texel *= 0.003921569; // 1/255\n __ENCODE32_ENDIANNESS__;\n return texel;\n}\n\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\nvec4 encode32(float value) {\n if (value == 0.0) return vec4(0, 0, 0, 0);\n\n float exponent;\n float mantissa;\n vec4 result;\n float sgn;\n\n sgn = step(0.0, -value);\n value = abs(value);\n\n exponent = floor(log2(value));\n\n mantissa = value*pow(2.0, -exponent)-1.0;\n exponent = exponent+127.0;\n result = vec4(0,0,0,0);\n\n result.a = floor(exponent/2.0);\n exponent = exponent - result.a*2.0;\n result.a = result.a + 128.0*sgn;\n\n result.b = floor(mantissa * 128.0);\n mantissa = mantissa - result.b / 128.0;\n result.b = result.b + exponent*128.0;\n\n result.g = floor(mantissa*32768.0);\n mantissa = mantissa - result.g/32768.0;\n\n result.r = floor(mantissa*8388608.0);\n return result/255.0;\n}\n// Dragons end here\n\nint index;\nivec3 threadId;\n\nivec3 indexTo3D(int idx, ivec3 texDim) {\n int z = int(idx / (texDim.x * texDim.y));\n idx -= z * int(texDim.x * texDim.y);\n int y = int(idx / texDim.x);\n int x = int(integerMod(idx, texDim.x));\n return ivec3(x, y, z);\n}\n\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return decode32(texel);\n}\n\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 2;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\n return decode16(texel, index);\n}\n\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int w = texSize.x * 4;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\n return decode8(texel, index);\n}\n\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + (texDim.x * (y + (texDim.y * z)));\n int channel = integerMod(index, 4);\n index = index / 4;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n index = index / 4;\n vec4 texel = texture(tex, st / vec2(texSize));\n return texel[channel];\n}\n\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, st / vec2(texSize));\n}\n\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n return texture(tex, vec3(st / vec2(texSize), z));\n}\n\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return result[0];\n}\n\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec2(result[0], result[1]);\n}\n\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n index = index / 2;\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n if (channel == 0) return vec2(texel.r, texel.g);\n if (channel == 1) return vec2(texel.b, texel.a);\n return vec2(0.0, 0.0);\n}\n\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\n return vec3(result[0], result[1], result[2]);\n}\n\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\n int vectorIndex = fieldIndex / 4;\n int vectorOffset = fieldIndex - vectorIndex * 4;\n int readY = vectorIndex / texSize.x;\n int readX = vectorIndex - readY * texSize.x;\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\n\n if (vectorOffset == 0) {\n return tex1.xyz;\n } else if (vectorOffset == 1) {\n return tex1.yzw;\n } else {\n readX++;\n if (readX >= texSize.x) {\n readX = 0;\n readY++;\n }\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\n if (vectorOffset == 2) {\n return vec3(tex1.z, tex1.w, tex2.x);\n } else {\n return vec3(tex1.w, tex2.x, tex2.y);\n }\n }\n}\n\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n return getImage2D(tex, texSize, texDim, z, y, x);\n}\n\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\n int index = x + texDim.x * (y + texDim.y * z);\n int channel = integerMod(index, 2);\n int w = texSize.x;\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\n vec4 texel = texture(tex, st / vec2(texSize));\n return vec4(texel.r, texel.g, texel.b, texel.a);\n}\n\nvec4 actualColor;\nvoid color(float r, float g, float b, float a) {\n actualColor = vec4(r,g,b,a);\n}\n\nvoid color(float r, float g, float b) {\n color(r,g,b,1.0);\n}\n\n__INJECTED_NATIVE__;\n__MAIN_CONSTANTS__;\n__MAIN_ARGUMENTS__;\n__KERNEL__;\n\nvoid main(void) {\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\n __MAIN_RESULT__;\n}",st="#version 300 es\n__FLOAT_TACTIC_DECLARATION__;\n__INT_TACTIC_DECLARATION__;\n__SAMPLER_2D_TACTIC_DECLARATION__;\n\nin vec2 aPos;\nin vec2 aTexCoord;\n\nout vec2 vTexCoord;\nuniform vec2 ratio;\n\nvoid main(void) {\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\n vTexCoord = aTexCoord;\n}";class at extends Ae{}class ot extends Ee{}class ut extends Se{getSource(e){const t=this.getVariablePrecisionString();return"constants"===this.origin?`const ${t} int ${this.id} = ${parseInt(e)};\n`:`uniform ${t} int ${this.id};\n`}updateValue(e){"constants"!==this.origin&&this.kernel.setUniform1i(this.id,this.uploadValue=e)}}class lt extends _e{getSource(){const e=this.getVariablePrecisionString();return R.linesToString([`uniform ${e} sampler2D ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}}class ht extends ve{getSource(){const e=this.getVariablePrecisionString();return R.linesToString([`uniform ${e} sampler2D ${this.id}`,`uniform ${e} ivec2 ${this.sizeId}`,`uniform ${e} ivec3 ${this.dimensionsId}`])}}class ct extends be{constructor(e,t){super(e,t),this.checkSize(e[0].width,e[0].height),this.requestTexture(),this.dimensions=[e[0].width,e[0].height,e.length],this.textureSize=[e[0].width,e[0].height]}getStringValueHandler(){return`const uploadValue_${this.name} = ${this.varName};\n`}getSource(){const e=this.getVariablePrecisionString();return R.linesToString([`uniform ${e} sampler2DArray ${this.id}`,`${e} ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,`${e} ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`])}updateValue(e){const{context:t}=this;t.activeTexture(this.contextHandle),t.bindTexture(t.TEXTURE_2D_ARRAY,this.texture),t.texParameteri(t.TEXTURE_2D_ARRAY,t.TEXTURE_MAG_FILTER,t.NEAREST),t.texParameteri(t.TEXTURE_2D_ARRAY,t.TEXTURE_MIN_FILTER,t.NEAREST),t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,!0),t.texImage3D(t.TEXTURE_2D_ARRAY,0,t.RGBA,e[0].width,e[0].height,e.length,0,t.RGBA,t.UNSIGNED_BYTE,null);for(let r=0;r0)for(let t=0;te[i]),t.__defineSetter__(i,t=>{e[i]=t})))}}const Mt=[Nt,rt],Ut=["gpu","cpu"],Pt={webgl2:Nt,webgl:rt};let Lt=!0;function Vt(e){if(!e)return{};const t=Object.assign({},e);return e.hasOwnProperty("floatOutput")&&(f("setting","floatOutput","precision"),t.precision=e.floatOutput?"single":"unsigned"),e.hasOwnProperty("outputToTexture")&&(f("setting","outputToTexture","pipeline"),t.pipeline=Boolean(e.outputToTexture)),e.hasOwnProperty("outputImmutable")&&(f("setting","outputImmutable","immutable"),t.immutable=Boolean(e.outputImmutable)),e.hasOwnProperty("floatTextures")&&(f("setting","floatTextures","optimizeFloatMemory"),t.optimizeFloatMemory=Boolean(e.floatTextures)),t}const Kt=class{static disableValidation(){Lt=!1}static enableValidation(){Lt=!0}static get isGPUSupported(){return Mt.some(e=>e.isSupported)}static get isKernelMapSupported(){return Mt.some(e=>e.isSupported&&e.features.kernelMap)}static get isOffscreenCanvasSupported(){return"undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas||"undefined"!=typeof importScripts}static get isWebGLSupported(){return rt.isSupported}static get isWebGL2Supported(){return Nt.isSupported}static get isHeadlessGLSupported(){return!1}static get isCanvasSupported(){return"undefined"!=typeof HTMLCanvasElement}static get isGPUHTMLImageArraySupported(){return Nt.isSupported}static get isSinglePrecisionSupported(){return Mt.some(e=>e.isSupported&&e.features.isFloatRead&&e.features.isTextureFloat)}constructor(e){if(e=e||{},this.canvas=e.canvas||null,this.context=e.context||null,this.mode=e.mode,this.Kernel=null,this.kernels=[],this.functions=[],this.nativeFunctions=[],this.injectedNative=null,"dev"!==this.mode){if(this.chooseKernel(),e.functions)for(let t=0;tt.argumentTypes[e]));const s=Object.assign({context:this.context,canvas:this.canvas,functions:this.functions,nativeFunctions:this.nativeFunctions,injectedNative:this.injectedNative,gpu:this,validate:Lt,onRequestFallback:i,onRequestSwitchKernel:function t(n,s){const o=new Array(n.length);for(let e=0;e{try{e(t.apply(this,arguments))}catch(e){r(e)}})},r.replaceKernel=function(t){kt(e=t,r),r.kernel=e},kt(e,r),r.kernel=e,r}(new this.Kernel(e,s));return this.canvas||(this.canvas=a.canvas),this.context||(this.context=a.context),this.kernels.push(a),a}createKernelMap(){let e,t;if("function"==typeof arguments[arguments.length-2]?(e=arguments[arguments.length-2],t=arguments[arguments.length-1]):e=arguments[arguments.length-1],"dev"!==this.mode&&(!this.Kernel.isSupported||!this.Kernel.features.kernelMap)&&this.mode&&Ut.indexOf(this.mode)<0)throw new Error(`kernelMap not supported on ${this.Kernel.name}`);const r=Vt(t);if(t&&"object"==typeof t.argumentTypes&&(r.argumentTypes=Object.keys(t.argumentTypes).map(e=>t.argumentTypes[e])),Array.isArray(arguments[0])){r.subKernels=[];const e=arguments[0];for(let t=0;t0)throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.');r=r||{};const{argumentTypes:n,argumentNames:i}=this.Kernel.nativeFunctionArguments(t)||{};return this.nativeFunctions.push({name:e,source:t,settings:r,argumentTypes:n,argumentNames:i,returnType:r.returnType||this.Kernel.nativeFunctionReturnType(t)}),this}injectNative(e){return this.injectedNative=e,this}destroy(){this.kernels&&setTimeout(()=>{for(let e=0;e {\n kernel.output = setupOutput(output);\n if (kernel.graphical) {\n setupGraphical(kernel);\n }\n };\n kernel.toJSON = () => {\n throw new Error('Not usable with gpuMock');\n };\n kernel.setConstants = (flag) => {\n kernel.constants = flag;\n return kernel;\n };\n kernel.setGraphical = (flag) => {\n kernel.graphical = flag;\n return kernel;\n };\n kernel.setCanvas = (flag) => {\n kernel.canvas = flag;\n return kernel;\n };\n kernel.setContext = (flag) => {\n kernel.context = flag;\n return kernel;\n };\n kernel.exec = function() {\n return new Promise((resolve, reject) => {\n try {\n resolve(kernel.apply(kernel, arguments));\n } catch(e) {\n reject(e);\n }\n });\n };\n kernel.getPixels = (flip) => {\n const {x, y} = kernel.output;\n // cpu is not flipped by default\n return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0);\n };\n kernel.color = function(r, g, b, a) {\n if (typeof a === 'undefined') {\n a = 1;\n }\n\n r = Math.floor(r * 255);\n g = Math.floor(g * 255);\n b = Math.floor(b * 255);\n a = Math.floor(a * 255);\n\n const width = kernel.output.x;\n const height = kernel.output.y;\n\n const x = kernel.thread.x;\n const y = height - kernel.thread.y - 1;\n\n const index = x + y * width;\n\n kernel._colorData[index * 4 + 0] = r;\n kernel._colorData[index * 4 + 1] = g;\n kernel._colorData[index * 4 + 2] = b;\n kernel._colorData[index * 4 + 3] = a;\n };\n\n // these are added for api compatibility, but have no affect\n kernel.setWarnVarUsage = () => {\n return kernel;\n };\n kernel.setOptimizeFloatMemory = () => {\n return kernel;\n };\n kernel.setArgumentTypes = () => {\n return kernel;\n };\n kernel.setDebug = () => {\n return kernel;\n };\n kernel.setLoopMaxIterations = () => {\n return kernel;\n };\n kernel.setPipeline = () => {\n return kernel;\n };\n kernel.setPrecision = () => {\n return kernel;\n };\n kernel.setImmutable = () => {\n return kernel;\n };\n kernel.setFunctions = () => {\n return kernel;\n };\n kernel.addSubKernel = () => {\n return kernel;\n };\n kernel.destroy = () => {};\n kernel.validateSettings = () => {};\n if (kernel.graphical && kernel.output) {\n setupGraphical(kernel);\n }\n return kernel;\n}\n\nfunction setupGraphical(kernel) {\n const {x, y} = kernel.output;\n if (kernel.context && kernel.context.createImageData) {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = kernel.context.createImageData(x, y);\n kernel._colorData = data;\n } else {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = { data };\n kernel._colorData = data;\n }\n}\n\nfunction setupOutput(output) {\n let result = null;\n if (output.length) {\n if (output.length === 3) {\n const [x,y,z] = output;\n result = { x, y, z };\n } else if (output.length === 2) {\n const [x,y] = output;\n result = { x, y };\n } else {\n const [x] = output;\n result = { x };\n }\n } else {\n result = output;\n }\n return result;\n}\n\nfunction gpuMock(fn, settings = {}) {\n const output = settings.output ? setupOutput(settings.output) : null;\n function kernel() {\n if (kernel.output.z) {\n return mock3D.apply(kernel, arguments);\n } else if (kernel.output.y) {\n if (kernel.graphical) {\n return mock2DGraphical.apply(kernel, arguments);\n }\n return mock2D.apply(kernel, arguments);\n } else {\n return mock1D.apply(kernel, arguments);\n }\n }\n kernel._fn = fn;\n kernel.constants = settings.constants || null;\n kernel.context = settings.context || null;\n kernel.canvas = settings.canvas || null;\n kernel.graphical = settings.graphical || false;\n kernel._imageData = null;\n kernel._colorData = null;\n kernel.output = output;\n kernel.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n return apiDecorate(kernel);\n}\n\nfunction flipPixels(pixels, width, height) {\n // https://stackoverflow.com/a/41973289/1324039\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\n const bytesPerRow = width * 4;\n // make a temp buffer to hold one row\n const temp = new Uint8ClampedArray(width * 4);\n const result = pixels.slice(0);\n for (let y = 0; y < halfHeight; ++y) {\n const topOffset = y * bytesPerRow;\n const bottomOffset = (height - y - 1) * bytesPerRow;\n\n // make copy of a row on the top half\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\n\n // copy a row from the bottom half to the top\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\n\n // copy the copy of the top half row to the bottom half\n result.set(temp, bottomOffset);\n }\n return result;\n}\n\nmodule.exports = {\n gpuMock\n};\n","/**\r\n * @fileoverview Branch of utils to prevent circular dependencies.\r\n */\r\n\r\nconst ARGUMENT_NAMES = /([^\\s,]+)/g;\r\nconst FUNCTION_NAME = /function ([^(]*)/;\r\nconst STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\r\n\r\n/**\r\n * @descReturn TRUE, on a JS function\r\n * @param {Function} funcObj - Object to validate if its a function\r\n * @returns {Boolean} TRUE if the object is a JS function\r\n */\r\nexport function isFunction(funcObj) {\r\n return typeof(funcObj) === 'function';\r\n};\r\n\r\n/**\r\n * @desc Return the function name from a JS function string\r\n * @param {String} funcStr - String of JS function to validate\r\n * @returns {String} Function name string (if found)\r\n */\r\nexport function getFunctionNameFromString(funcStr) {\r\n return FUNCTION_NAME.exec(funcStr)[1].trim();\r\n};\r\n\r\n/**\r\n *\r\n * @param {String|Function} source\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {IFunction}\r\n */\r\nexport function functionToIFunction(source, settings) {\r\n settings = settings || {};\r\n if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');\r\n const sourceString = typeof source === 'string' ? source : source.toString();\r\n\r\n let argumentTypes = [];\r\n\r\n if (Array.isArray(settings.argumentTypes)) {\r\n argumentTypes = settings.argumentTypes;\r\n } else if (typeof settings.argumentTypes === 'object') {\r\n argumentTypes = getArgumentNamesFromString(sourceString)\r\n .map(name => settings.argumentTypes[name]) || [];\r\n } else {\r\n argumentTypes = settings.argumentTypes || [];\r\n }\r\n\r\n return {\r\n source: sourceString,\r\n argumentTypes,\r\n returnType: settings.returnType || null,\r\n };\r\n};\r\n\r\nexport function warnDeprecated(type, oldName, newName) {\r\n const msg = newName\r\n ? `It has been replaced with \"${ newName }\"`\r\n : 'It has been removed';\r\n console.warn(`You are using a deprecated ${ type } \"${ oldName }\". ${msg}. Fixing, but please upgrade as it will soon be removed.`)\r\n};\r\n\r\n/**\r\n * @desc Return TRUE, on a valid JS function string\r\n * Note: This does just a VERY simply sanity check. And may give false positives.\r\n *\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {Boolean} TRUE if the string passes basic validation\r\n */\r\nexport function isFunctionString(fn) {\r\n if (typeof fn === 'string') {\r\n return (fn\r\n .slice(0, 'function'.length)\r\n .toLowerCase() === 'function');\r\n }\r\n return false;\r\n};\r\n\r\n/**\r\n * @desc Return list of argument names extracted from a javascript function\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {String[]} Array representing all the parameter names\r\n */\r\nexport function getArgumentNamesFromString(fn) {\r\n const fnStr = fn.replace(STRIP_COMMENTS, '');\r\n let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);\r\n if (result === null) {\r\n result = [];\r\n }\r\n return result;\r\n};\r\n\r\n/**\r\n * @desc Checks if is an array or Array-like object\r\n * @param {Object} array - The argument object to check if is array\r\n * @returns {Boolean} true if is array or Array-like object\r\n */\r\nexport function isArray(array) {\r\n return !isNaN(array.length);\r\n};\r\n\r\nexport function erectMemoryOptimized2DFloat(array, width, height) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = y * width;\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n return yResults;\r\n};\r\n\r\nexport function erectMemoryOptimized3DFloat(array, width, height, depth) {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = (z * height * width) + (y * width);\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n};\r\n\r\nexport function getAstString(source, ast) {\r\n const lines = Array.isArray(source) ? source : source.split(/\\r?\\n/g);\r\n const start = ast.loc.start;\r\n const end = ast.loc.end;\r\n const result = [];\r\n if (start.line === end.line) {\r\n result.push(lines[start.line - 1].substring(start.column, end.column));\r\n } else {\r\n result.push(lines[start.line - 1].slice(start.column));\r\n for (let i = start.line; i < end.line; i++) {\r\n result.push(lines[i]);\r\n }\r\n result.push(lines[end.line - 1].slice(0, end.column));\r\n }\r\n return result.join('\\n');\r\n};\r\n","import { erectMemoryOptimized2DFloat, erectMemoryOptimized3DFloat } from './common';\r\n\r\nexport class Input {\r\n constructor(value, size) {\r\n this.value = value;\r\n if (Array.isArray(size)) {\r\n this.size = size;\r\n } else {\r\n this.size = new Int32Array(3);\r\n if (size.z) {\r\n this.size = new Int32Array([size.x, size.y, size.z]);\r\n } else if (size.y) {\r\n this.size = new Int32Array([size.x, size.y]);\r\n } else {\r\n this.size = new Int32Array([size.x]);\r\n }\r\n }\r\n\r\n const [w, h, d] = this.size;\r\n if (d) {\r\n if (this.value.length !== (w * h * d)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`);\r\n }\r\n } else if (h) {\r\n if (this.value.length !== (w * h)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`);\r\n }\r\n } else {\r\n if (this.value.length !== w) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w}`);\r\n }\r\n }\r\n\r\n }\r\n\r\n toArray() {\r\n const [ w, h, d ] = this.size;\r\n if (d) {\r\n return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d);\r\n } else if (h) {\r\n return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h);\r\n } else {\r\n return this.value;\r\n }\r\n }\r\n};\r\n\r\nexport function input(value, size) {\r\n return new Input(value, size);\r\n};\r\n","/**\r\n * @desc WebGl Texture implementation in JS\r\n * @param {ITextureSettings} settings\r\n */\r\nexport class Texture {\r\n constructor(settings) {\r\n const {\r\n texture,\r\n size,\r\n dimensions,\r\n output,\r\n context,\r\n type = 'NumberTexture',\r\n } = settings;\r\n if (!output) throw new Error('settings property \"output\" required.');\r\n if (!context) throw new Error('settings property \"context\" required.');\r\n this.texture = texture;\r\n this.size = size;\r\n this.dimensions = dimensions;\r\n this.output = output;\r\n this.context = context;\r\n this.kernel = null;\r\n this.type = type;\r\n }\r\n\r\n /**\r\n * @desc Converts the Texture into a JavaScript Array\r\n * @returns {Number[]|Number[][]|Number[][][]}\r\n */\r\n toArray() {\r\n throw new Error(`Not implemented on ${this.constructor.name}`);\r\n }\r\n\r\n /**\r\n * @desc Deletes the Texture\r\n */\r\n delete() {\r\n return this.context.deleteTexture(this.texture);\r\n }\r\n};\r\n","import { parse } from 'acorn';\r\nimport { Texture } from './texture';\r\nimport { Input } from './input';\r\nimport {\r\n getAstString,\r\n erectMemoryOptimized2DFloat,\r\n erectMemoryOptimized3DFloat,\r\n functionToIFunction,\r\n getArgumentNamesFromString,\r\n getFunctionNameFromString,\r\n isArray,\r\n isFunction,\r\n isFunctionString,\r\n warnDeprecated\r\n} from './common';\r\n\r\nexport function getSystemEndianness() {\r\n const b = new ArrayBuffer(4);\r\n const a = new Uint32Array(b);\r\n const c = new Uint8Array(b);\r\n a[0] = 0xdeadbeef;\r\n if (c[0] === 0xef) return 'LE';\r\n if (c[0] === 0xde) return 'BE';\r\n throw new Error('unknown endianness');\r\n};\r\n\r\nconst _systemEndianness = getSystemEndianness();\r\n\r\n/**\r\n *\r\n * @desc Gets the system endianness, and cache it\r\n * @returns {String} 'LE' or 'BE' depending on system architecture\r\n * Credit: https://gist.github.com/TooTallNate/4750953\r\n */\r\nexport function systemEndianness() {\r\n return _systemEndianness;\r\n};\r\n\r\n/**\r\n * @desc Evaluate the argument type, to apply respective logic for it\r\n * @param {Object} value - The argument object to evaluate type\r\n * @returns {String} Argument type Array/Number/Float/Texture/Unknown\r\n */\r\nexport function getVariableType(value, strictIntegers) {\r\n if (isArray(value)) {\r\n if (value[0].nodeName === 'IMG') {\r\n return 'HTMLImageArray';\r\n }\r\n return 'Array';\r\n }\r\n\r\n switch (value.constructor) {\r\n case Boolean:\r\n return 'Boolean';\r\n case Number:\r\n return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float';\r\n case Texture:\r\n return value.type;\r\n case Input:\r\n return 'Input';\r\n }\r\n\r\n switch (value.nodeName) {\r\n case 'IMG':\r\n return 'HTMLImage';\r\n case 'VIDEO':\r\n return 'HTMLVideo';\r\n }\r\n\r\n return value.hasOwnProperty('type') ? value.type : 'Unknown';\r\n};\r\n\r\n/**\r\n * @desc Various utility functions / snippets of code that GPU.JS uses internally.\r\n * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere)\r\n */\r\nconst utils = {\r\n systemEndianness,\r\n getSystemEndianness,\r\n isFunction,\r\n isFunctionString,\r\n getFunctionNameFromString,\r\n\r\n getFunctionBodyFromString(funcStr) {\r\n return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}'));\r\n },\r\n\r\n getArgumentNamesFromString,\r\n\r\n /**\r\n * @desc Returns a clone\r\n * @param {Object} obj - Object to clone\r\n * @returns {Object|Array} Cloned object\r\n */\r\n clone(obj) {\r\n if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj;\r\n\r\n const temp = obj.constructor(); // changed\r\n\r\n for (let key in obj) {\r\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\r\n obj.isActiveClone = null;\r\n temp[key] = utils.clone(obj[key]);\r\n delete obj.isActiveClone;\r\n }\r\n }\r\n\r\n return temp;\r\n },\r\n\r\n isArray,\r\n getVariableType,\r\n\r\n getKernelTextureSize(settings, dimensions) {\r\n let [w, h, d] = dimensions;\r\n let texelCount = (w || 1) * (h || 1) * (d || 1);\r\n\r\n if (settings.optimizeFloatMemory && settings.precision === 'single') {\r\n w = texelCount = Math.ceil(texelCount / 4);\r\n }\r\n // if given dimensions == a 2d image\r\n if (h > 1 && w * h === texelCount) {\r\n return new Int32Array([w, h]);\r\n }\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n /**\r\n *\r\n * @param {Number} length\r\n * @returns {TextureDimensions}\r\n */\r\n closestSquareDimensions(length) {\r\n const sqrt = Math.sqrt(length);\r\n let high = Math.ceil(sqrt);\r\n let low = Math.floor(sqrt);\r\n while (high * low < length) {\r\n high--;\r\n low = Math.ceil(length / high);\r\n }\r\n return new Int32Array([low, Math.ceil(length / low)]);\r\n },\r\n\r\n /**\r\n * A texture takes up four\r\n * @param {OutputDimensions} dimensions\r\n * @param {Number} bitRatio\r\n * @returns {TextureDimensions}\r\n */\r\n getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) {\r\n const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4);\r\n const texelCount = totalArea / bitRatio;\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n /**\r\n *\r\n * @param dimensions\r\n * @param bitRatio\r\n * @returns {*|TextureDimensions}\r\n */\r\n getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) {\r\n const [w, h, d] = dimensions;\r\n const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4);\r\n const texelCount = totalArea / (4 / bitRatio);\r\n return utils.closestSquareDimensions(texelCount);\r\n },\r\n\r\n roundTo(n, d) {\r\n return Math.floor((n + d - 1) / d) * d;\r\n },\r\n /**\r\n * @desc Return the dimension of an array.\r\n * @param {Array|String|Texture|Input} x - The array\r\n * @param {Boolean} [pad] - To include padding in the dimension calculation\r\n * @returns {OutputDimensions}\r\n */\r\n getDimensions(x, pad) {\r\n let ret;\r\n if (isArray(x)) {\r\n const dim = [];\r\n let temp = x;\r\n while (isArray(temp)) {\r\n dim.push(temp.length);\r\n temp = temp[0];\r\n }\r\n ret = dim.reverse();\r\n } else if (x instanceof Texture) {\r\n ret = x.output;\r\n } else if (x instanceof Input) {\r\n ret = x.size;\r\n } else {\r\n throw new Error(`Unknown dimensions of ${x}`);\r\n }\r\n\r\n if (pad) {\r\n ret = Array.from(ret);\r\n while (ret.length < 3) {\r\n ret.push(1);\r\n }\r\n }\r\n\r\n return new Int32Array(ret);\r\n },\r\n\r\n /**\r\n * Puts a nested 2d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten2dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let y = 0; y < array.length; y++) {\r\n target.set(array[y], offset);\r\n offset += array[y].length;\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 3d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten3dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let z = 0; z < array.length; z++) {\r\n for (let y = 0; y < array[z].length; y++) {\r\n target.set(array[z][y], offset);\r\n offset += array[z][y].length;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 4d array into a one-dimensional target array\r\n * @param {Array|*} array\r\n * @param {Float32Array|Float64Array} target\r\n */\r\n flatten4dArrayTo(array, target) {\r\n let offset = 0;\r\n for (let l = 0; l < array.length; l++) {\r\n for (let z = 0; z < array[l].length; z++) {\r\n for (let y = 0; y < array[l][z].length; y++) {\r\n target.set(array[l][z][y], offset);\r\n offset += array[l][z][y].length;\r\n }\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array\r\n * @param {Float32Array|Uint16Array|Uint8Array} array\r\n * @param {Float32Array} target\r\n */\r\n flattenTo(array, target) {\r\n if (isArray(array[0])) {\r\n if (isArray(array[0][0])) {\r\n if (isArray(array[0][0][0])) {\r\n utils.flatten4dArrayTo(array, target);\r\n } else {\r\n utils.flatten3dArrayTo(array, target);\r\n }\r\n } else {\r\n utils.flatten2dArrayTo(array, target);\r\n }\r\n } else {\r\n target.set(array);\r\n }\r\n },\r\n\r\n /**\r\n *\r\n * @desc Splits an array into smaller arrays.\r\n * Number of elements in one small chunk is given by `part`\r\n *\r\n * @param {Number[]} array - The array to split into chunks\r\n * @param {Number} part - elements in one chunk\r\n *\r\n * @returns {Number[]} An array of smaller chunks\r\n */\r\n splitArray(array, part) {\r\n const result = [];\r\n for (let i = 0; i < array.length; i += part) {\r\n result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part));\r\n }\r\n return result;\r\n },\r\n\r\n getAstString,\r\n\r\n allPropertiesOf(obj) {\r\n const props = [];\r\n\r\n do {\r\n props.push.apply(props, Object.getOwnPropertyNames(obj));\r\n } while (obj = Object.getPrototypeOf(obj));\r\n\r\n return props;\r\n },\r\n\r\n /**\r\n * @param {Array} lines - An Array of strings\r\n * @returns {String} Single combined String, separated by *\\n*\r\n */\r\n linesToString(lines) {\r\n if (lines.length > 0) {\r\n return lines.join(';\\n') + ';\\n';\r\n } else {\r\n return '\\n';\r\n }\r\n },\r\n\r\n warnDeprecated,\r\n functionToIFunction,\r\n\r\n flipPixels(pixels, width, height) {\r\n // https://stackoverflow.com/a/41973289/1324039\r\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\r\n const bytesPerRow = width * 4;\r\n // make a temp buffer to hold one row\r\n const temp = new Uint8ClampedArray(width * 4);\r\n const result = pixels.slice(0);\r\n for (let y = 0; y < halfHeight; ++y) {\r\n const topOffset = y * bytesPerRow;\r\n const bottomOffset = (height - y - 1) * bytesPerRow;\r\n\r\n // make copy of a row on the top half\r\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\r\n\r\n // copy a row from the bottom half to the top\r\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\r\n\r\n // copy the copy of the top half row to the bottom half\r\n result.set(temp, bottomOffset);\r\n }\r\n return result;\r\n },\r\n\r\n erectPackedFloat: (array, width) => {\r\n return array.subarray(0, width);\r\n },\r\n erect2DPackedFloat: (array, width, height) => {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xStart = y * width;\r\n const xEnd = xStart + width;\r\n yResults[y] = array.subarray(xStart, xEnd);\r\n }\r\n return yResults;\r\n },\r\n erect3DPackedFloat: (array, width, height, depth) => {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xStart = (z * height * width) + y * width;\r\n const xEnd = xStart + width;\r\n yResults[y] = array.subarray(xStart, xEnd);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectMemoryOptimizedFloat: (array, width) => {\r\n return array.subarray(0, width);\r\n },\r\n erectMemoryOptimized2DFloat,\r\n erectMemoryOptimized3DFloat,\r\n erectFloat: (array, width) => {\r\n const xResults = new Float32Array(width);\r\n let i = 0;\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n return xResults;\r\n },\r\n erect2DFloat: (array, width, height) => {\r\n const yResults = new Array(height);\r\n let i = 0;\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Float32Array(width);\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DFloat: (array, width, height, depth) => {\r\n const zResults = new Array(depth);\r\n let i = 0;\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Float32Array(width);\r\n for (let x = 0; x < width; x++) {\r\n xResults[x] = array[i];\r\n i += 4;\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray2: (array, width) => {\r\n const xResults = new Array(width);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 2);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray2: (array, width, height) => {\r\n const yResults = new Array(height);\r\n const XResultsMax = width * 4;\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * XResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < XResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 2);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray2: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 2);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray3: (array, width) => {\r\n const xResults = new Array(width);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 3);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray3: (array, width, height) => {\r\n const xResultsMax = width * 4;\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * xResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 3);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray3: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 3);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n erectArray4: (array, width) => {\r\n const xResults = new Array(array);\r\n const xResultsMax = width * 4;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x, x + 4);\r\n }\r\n return xResults;\r\n },\r\n erect2DArray4: (array, width, height) => {\r\n const xResultsMax = width * 4;\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = y * xResultsMax;\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 4);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n return yResults;\r\n },\r\n erect3DArray4: (array, width, height, depth) => {\r\n const xResultsMax = width * 4;\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const xResults = new Array(width);\r\n const offset = (z * xResultsMax * height) + (y * xResultsMax);\r\n let i = 0;\r\n for (let x = 0; x < xResultsMax; x += 4) {\r\n xResults[i++] = array.subarray(x + offset, x + offset + 4);\r\n }\r\n yResults[y] = xResults;\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n },\r\n\r\n /**\r\n * @param {String} source\r\n * @param {Object} settings\r\n * @return {String}\r\n */\r\n flattenFunctionToString: (source, settings) => {\r\n const { findDependency, thisLookup, doNotDefine } = settings;\r\n let flattened = settings.flattened;\r\n if (!flattened) {\r\n flattened = settings.flattened = {};\r\n }\r\n\r\n const ast = parse(source);\r\n const functionDependencies = [];\r\n\r\n function flatten(ast) {\r\n if (Array.isArray(ast)) {\r\n const results = [];\r\n for (let i = 0; i < ast.length; i++) {\r\n results.push(flatten(ast[i]));\r\n }\r\n return results.join('');\r\n }\r\n switch (ast.type) {\r\n case 'Program':\r\n return flatten(ast.body);\r\n case 'FunctionDeclaration':\r\n return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`;\r\n case 'BlockStatement': {\r\n const result = [];\r\n for (let i = 0; i < ast.body.length; i++) {\r\n result.push(flatten(ast.body[i]), ';\\n');\r\n }\r\n return `{\\n${result.join('')}}`;\r\n }\r\n case 'VariableDeclaration':\r\n switch (ast.declarations[0].id.type) {\r\n case 'ObjectPattern': {\r\n const source = flatten(ast.declarations[0].init);\r\n const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0];\r\n if (/this/.test(source)) {\r\n const result = [];\r\n const lookups = properties.map(thisLookup);\r\n for (let i = 0; i < lookups.length; i++) {\r\n const lookup = lookups[i];\r\n if (lookup === null) continue;\r\n const property = properties[i];\r\n result.push(`${ast.kind} ${ property } = ${ lookup };\\n`);\r\n }\r\n\r\n return result.join('');\r\n }\r\n return `${ast.kind} { ${properties} } = ${source}`;\r\n }\r\n case 'ArrayPattern':\r\n return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`;\r\n }\r\n if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) {\r\n return '';\r\n }\r\n return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`;\r\n case 'CallExpression': {\r\n if (ast.callee.property.name === 'subarray') {\r\n return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') {\r\n return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n if (ast.callee.object.type === 'ThisExpression') {\r\n functionDependencies.push(findDependency('this', ast.callee.property.name));\r\n return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else if (ast.callee.object.name) {\r\n const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name);\r\n if (foundSource === null) {\r\n // we're not flattening it\r\n return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else {\r\n functionDependencies.push(foundSource);\r\n // we're flattening it\r\n return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n }\r\n } else if (ast.callee.object.type === 'MemberExpression') {\r\n return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n } else {\r\n throw new Error('unknown ast.callee');\r\n }\r\n }\r\n case 'ReturnStatement':\r\n return `return ${flatten(ast.argument)}`;\r\n case 'BinaryExpression':\r\n return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`;\r\n case 'UnaryExpression':\r\n if (ast.prefix) {\r\n return `${ast.operator} ${flatten(ast.argument)}`;\r\n } else {\r\n return `${flatten(ast.argument)} ${ast.operator}`;\r\n }\r\n case 'ExpressionStatement':\r\n return `(${flatten(ast.expression)})`;\r\n case 'ArrowFunctionExpression':\r\n return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`;\r\n case 'Literal':\r\n return ast.raw;\r\n case 'Identifier':\r\n return ast.name;\r\n case 'MemberExpression':\r\n if (ast.object.type === 'ThisExpression') {\r\n return thisLookup(ast.property.name);\r\n }\r\n if (ast.computed) {\r\n return `${flatten(ast.object)}[${flatten(ast.property)}]`;\r\n }\r\n return flatten(ast.object) + '.' + flatten(ast.property);\r\n case 'ThisExpression':\r\n return 'this';\r\n case 'NewExpression':\r\n return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`;\r\n case 'ForStatement':\r\n return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`;\r\n case 'AssignmentExpression':\r\n return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`;\r\n case 'UpdateExpression':\r\n return `${flatten(ast.argument)}${ast.operator}`;\r\n case 'IfStatement':\r\n return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`;\r\n case 'ThrowStatement':\r\n return `throw ${flatten(ast.argument)}`;\r\n case 'ObjectPattern':\r\n return ast.properties.map(flatten).join(', ');\r\n case 'ArrayPattern':\r\n return ast.elements.map(flatten).join(', ');\r\n case 'DebuggerStatement':\r\n return 'debugger;';\r\n case 'ConditionalExpression':\r\n return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`;\r\n case 'Property':\r\n if (ast.kind === 'init') {\r\n return flatten(ast.key);\r\n }\r\n }\r\n throw new Error(`unhandled ast.type of ${ ast.type }`);\r\n }\r\n const result = flatten(ast);\r\n if (functionDependencies.length > 0) {\r\n const flattenedFunctionDependencies = [];\r\n for (let i = 0; i < functionDependencies.length; i++) {\r\n const functionDependency = functionDependencies[i];\r\n if (!flattened[functionDependency]) {\r\n flattened[functionDependency] = true;\r\n }\r\n flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\\n');\r\n }\r\n return flattenedFunctionDependencies.join('') + result;\r\n }\r\n return result;\r\n },\r\n};\r\n\r\nexport { utils };\r\n","import { Input } from '../input';\r\nimport {\r\n functionToIFunction,\r\n getArgumentNamesFromString,\r\n isArray,\r\n isFunctionString,\r\n warnDeprecated\r\n} from '../common';\r\nimport { getVariableType } from '../utils';\r\n\r\nexport class Kernel {\r\n /**\r\n * @type {Boolean}\r\n */\r\n static get isSupported() {\r\n throw new Error(`\"isSupported\" not implemented on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {Boolean}\r\n */\r\n static isContextMatch(context) {\r\n throw new Error(`\"isContextMatch\" not implemented on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {IKernelFeatures}\r\n * Used internally to populate the kernel.feature, which is a getter for the output of this value\r\n */\r\n static getFeatures() {\r\n throw new Error(`\"getFeatures\" not implemented on ${ this.name }`);\r\n }\r\n\r\n static destroyContext(context) {\r\n throw new Error(`\"destroyContext\" called on ${ this.name }`);\r\n }\r\n\r\n static nativeFunctionArguments() {\r\n throw new Error(`\"nativeFunctionArguments\" called on ${ this.name }`);\r\n }\r\n\r\n static nativeFunctionReturnType() {\r\n throw new Error(`\"nativeFunctionReturnType\" called on ${ this.name }`);\r\n }\r\n\r\n static combineKernels() {\r\n throw new Error(`\"combineKernels\" called on ${ this.name }`);\r\n }\r\n\r\n /**\r\n *\r\n * @param {string|object} source\r\n * @param [settings]\r\n */\r\n constructor(source, settings) {\r\n if (typeof source !== 'object') {\r\n if (typeof source !== 'string') {\r\n throw new Error('source not a string');\r\n }\r\n if (!isFunctionString(source)) {\r\n throw new Error('source not a function string');\r\n }\r\n }\r\n this.useLegacyEncoder = false;\r\n this.fallbackRequested = false;\r\n this.onRequestFallback = null;\r\n\r\n /**\r\n * Name of the arguments found from parsing source argument\r\n * @type {String[]}\r\n */\r\n this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null;\r\n this.argumentTypes = null;\r\n this.argumentSizes = null;\r\n this.argumentBitRatios = null;\r\n this.kernelArguments = null;\r\n this.kernelConstants = null;\r\n\r\n\r\n /**\r\n * The function source\r\n * @type {String}\r\n */\r\n this.source = source;\r\n\r\n /**\r\n * The size of the kernel's output\r\n * @type {Number[]}\r\n */\r\n this.output = null;\r\n\r\n /**\r\n * Debug mode\r\n * @type {Boolean}\r\n */\r\n this.debug = false;\r\n\r\n /**\r\n * Graphical mode\r\n * @type {Boolean}\r\n */\r\n this.graphical = false;\r\n\r\n /**\r\n * Maximum loops when using argument values to prevent infinity\r\n * @type {Number}\r\n */\r\n this.loopMaxIterations = 0;\r\n\r\n /**\r\n * Constants used in kernel via `this.constants`\r\n * @type {Object}\r\n */\r\n this.constants = null;\r\n this.constantTypes = null;\r\n this.constantBitRatios = null;\r\n this.dynamicArguments = false;\r\n this.dynamicOutput = false;\r\n\r\n /**\r\n *\r\n * @type {Object}\r\n */\r\n this.canvas = null;\r\n\r\n /**\r\n *\r\n * @type {WebGLRenderingContext}\r\n */\r\n this.context = null;\r\n\r\n /**\r\n *\r\n * @type {Boolean}\r\n */\r\n this.checkContext = null;\r\n\r\n /**\r\n *\r\n * @type {GPU}\r\n */\r\n this.gpu = null;\r\n\r\n /**\r\n *\r\n * @type {IGPUFunction[]}\r\n */\r\n this.functions = null;\r\n\r\n /**\r\n *\r\n * @type {IGPUNativeFunction[]}\r\n */\r\n this.nativeFunctions = null;\r\n\r\n /**\r\n *\r\n * @type {String}\r\n */\r\n this.injectedNative = null;\r\n\r\n /**\r\n *\r\n * @type {ISubKernel[]}\r\n */\r\n this.subKernels = null;\r\n\r\n /**\r\n *\r\n * @type {Boolean}\r\n */\r\n this.validate = true;\r\n\r\n /**\r\n * Enforces kernel to write to a new array or texture on run\r\n * @type {Boolean}\r\n */\r\n this.immutable = false;\r\n\r\n /**\r\n * Enforces kernel to write to a texture on run\r\n * @type {Boolean}\r\n */\r\n this.pipeline = false;\r\n\r\n /**\r\n * Make GPU use single precison or unsigned. Acceptable values: 'single' or 'unsigned'\r\n * @type {String|null}\r\n * @enum 'single' | 'unsigned'\r\n */\r\n this.precision = null;\r\n\r\n /**\r\n *\r\n * @type {String|null}\r\n * @enum 'speed' | 'balanced' | 'precision'\r\n */\r\n this.tactic = 'balanced';\r\n\r\n this.plugins = null;\r\n\r\n this.returnType = null;\r\n this.leadingReturnStatement = null;\r\n this.followingReturnStatement = null;\r\n this.optimizeFloatMemory = null;\r\n this.strictIntegers = false;\r\n this.fixIntegerDivisionAccuracy = null;\r\n this.warnVarUsage = true;\r\n }\r\n\r\n mergeSettings(settings) {\r\n for (let p in settings) {\r\n if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue;\r\n switch (p) {\r\n case 'output':\r\n if (!Array.isArray(settings.output)) {\r\n this.setOutput(settings.output); // Flatten output object\r\n continue;\r\n }\r\n break;\r\n case 'functions':\r\n if (typeof settings.functions[0] === 'function') {\r\n this.functions = settings.functions.map(source => functionToIFunction(source));\r\n continue;\r\n }\r\n break;\r\n case 'graphical':\r\n if (settings[p] && !settings.hasOwnProperty('precision')) {\r\n this.precision = 'unsigned';\r\n }\r\n this[p] = settings[p];\r\n continue;\r\n }\r\n this[p] = settings[p];\r\n }\r\n\r\n if (!this.canvas) this.canvas = this.initCanvas();\r\n if (!this.context) this.context = this.initContext();\r\n if (!this.plugins) this.plugins = this.initPlugins(settings);\r\n }\r\n /**\r\n * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders,\r\n * and instantiates the program.\r\n * @abstract\r\n */\r\n build() {\r\n throw new Error(`\"build\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Run the kernel program, and send the output to renderOutput\r\n *

This method calls a helper method *renderOutput* to return the result.

\r\n * @returns {Float32Array|Float32Array[]|Float32Array[][]|void} Result The final output of the program, as float, and as Textures for reuse.\r\n * @abstract\r\n */\r\n run() {\r\n throw new Error(`\"run\" not defined on ${ this.constructor.name }`)\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @return {Object}\r\n */\r\n initCanvas() {\r\n throw new Error(`\"initCanvas\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @return {Object}\r\n */\r\n initContext() {\r\n throw new Error(`\"initContext\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @param {IFunctionSettings} settings\r\n * @return {Object};\r\n * @abstract\r\n */\r\n initPlugins(settings) {\r\n throw new Error(`\"initPlugins\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Setup the parameter types for the parameters\r\n * supplied to the Kernel function\r\n *\r\n * @param {IArguments} args - The actual parameters sent to the Kernel\r\n */\r\n setupArguments(args) {\r\n this.kernelArguments = [];\r\n if (!this.argumentTypes) {\r\n if (!this.argumentTypes) {\r\n this.argumentTypes = [];\r\n for (let i = 0; i < args.length; i++) {\r\n const argType = getVariableType(args[i], this.strictIntegers);\r\n const type = argType === 'Integer' ? 'Number' : argType;\r\n this.argumentTypes.push(type);\r\n this.kernelArguments.push({\r\n type\r\n });\r\n }\r\n }\r\n } else {\r\n for (let i = 0; i < this.argumentTypes.length; i++) {\r\n this.kernelArguments.push({\r\n type: this.argumentTypes[i]\r\n });\r\n }\r\n }\r\n\r\n // setup sizes\r\n this.argumentSizes = new Array(args.length);\r\n this.argumentBitRatios = new Int32Array(args.length);\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n this.argumentSizes[i] = arg.constructor === Input ? arg.size : null;\r\n this.argumentBitRatios[i] = this.getBitRatio(arg);\r\n }\r\n\r\n if (this.argumentNames.length !== args.length) {\r\n throw new Error(`arguments are miss-aligned`);\r\n }\r\n }\r\n\r\n /**\r\n * Setup constants\r\n */\r\n setupConstants() {\r\n this.kernelConstants = [];\r\n let needsConstantTypes = this.constantTypes === null;\r\n if (needsConstantTypes) {\r\n this.constantTypes = {};\r\n }\r\n this.constantBitRatios = {};\r\n if (this.constants) {\r\n for (let name in this.constants) {\r\n if (needsConstantTypes) {\r\n const type = getVariableType(this.constants[name], this.strictIntegers);\r\n this.constantTypes[name] = type;\r\n this.kernelConstants.push({\r\n name,\r\n type\r\n });\r\n } else {\r\n this.kernelConstants.push({\r\n name,\r\n type: this.constantTypes[name]\r\n });\r\n }\r\n this.constantBitRatios[name] = this.getBitRatio(this.constants[name]);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setOptimizeFloatMemory(flag) {\r\n this.optimizeFloatMemory = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set output dimensions of the kernel function\r\n * @param {Array|Object} output - The output array to set the kernel output size to\r\n */\r\n setOutput(output) {\r\n if (output.hasOwnProperty('x')) {\r\n if (output.hasOwnProperty('y')) {\r\n if (output.hasOwnProperty('z')) {\r\n this.output = [output.x, output.y, output.z];\r\n } else {\r\n this.output = [output.x, output.y];\r\n }\r\n } else {\r\n this.output = [output.x];\r\n }\r\n } else {\r\n this.output = output;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle debug mode\r\n * @param {Boolean} flag - true to enable debug\r\n */\r\n setDebug(flag) {\r\n this.debug = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle graphical output mode\r\n * @param {Boolean} flag - true to enable graphical output\r\n */\r\n setGraphical(flag) {\r\n this.graphical = flag;\r\n this.precision = 'unsigned';\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set the maximum number of loop iterations\r\n * @param {number} max - iterations count\r\n *\r\n */\r\n setLoopMaxIterations(max) {\r\n this.loopMaxIterations = max;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Set Constants\r\n */\r\n setConstants(constants) {\r\n this.constants = constants;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [IKernelValueTypes] constantTypes\r\n * @return {Kernel}\r\n */\r\n setConstantTypes(constantTypes) {\r\n this.constantTypes = constantTypes;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IFunction[]|KernelFunction[]} functions\r\n * @return {Kernel}\r\n */\r\n setFunctions(functions) {\r\n if (typeof functions[0] === 'function') {\r\n this.functions = functions.map(source => functionToIFunction(source));\r\n } else {\r\n this.functions = functions;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IGPUNativeFunction} nativeFunctions\r\n * @return {Kernel}\r\n */\r\n setNativeFunctions(nativeFunctions) {\r\n this.nativeFunctions = nativeFunctions;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {String} injectedNative\r\n * @return {Kernel}\r\n */\r\n setInjectedNative(injectedNative) {\r\n this.injectedNative = injectedNative;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set writing to texture on/off\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setPipeline(flag) {\r\n this.pipeline = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set precision to 'unsigned' or 'single'\r\n * @param {String} flag 'unsigned' or 'single'\r\n * @return {Kernel}\r\n */\r\n setPrecision(flag) {\r\n this.precision = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param flag\r\n * @return {Kernel}\r\n * @deprecated\r\n */\r\n setOutputToTexture(flag) {\r\n warnDeprecated('method', 'setOutputToTexture', 'setPipeline');\r\n this.pipeline = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * Set to immutable\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setImmutable(flag) {\r\n this.immutable = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Bind the canvas to kernel\r\n * @param {Object} canvas\r\n */\r\n setCanvas(canvas) {\r\n this.canvas = canvas;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setStrictIntegers(flag) {\r\n this.strictIntegers = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setDynamicOutput(flag) {\r\n this.dynamicOutput = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setHardcodeConstants(flag) {\r\n warnDeprecated('method', 'setHardcodeConstants');\r\n this.setDynamicOutput(flag);\r\n this.setDynamicArguments(flag);\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param flag\r\n * @return {Kernel}\r\n */\r\n setDynamicArguments(flag) {\r\n this.dynamicArguments = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setUseLegacyEncoder(flag) {\r\n this.useLegacyEncoder = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Boolean} flag\r\n * @return {Kernel}\r\n */\r\n setWarnVarUsage(flag) {\r\n this.warnVarUsage = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @returns {Object}\r\n */\r\n getCanvas() {\r\n warnDeprecated('method', 'getCanvas');\r\n return this.canvas;\r\n }\r\n\r\n /**\r\n * @deprecated\r\n * @returns {Object}\r\n */\r\n getWebGl() {\r\n warnDeprecated('method', 'getWebGl');\r\n return this.context;\r\n }\r\n\r\n /**\r\n * @desc Bind the webGL instance to kernel\r\n * @param {WebGLRenderingContext} context - webGl instance to bind\r\n */\r\n setContext(context) {\r\n this.context = context;\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [IKernelValueTypes|GPUVariableType[]] argumentTypes\r\n * @return {Kernel}\r\n */\r\n setArgumentTypes(argumentTypes) {\r\n if (Array.isArray(argumentTypes)) {\r\n this.argumentTypes = argumentTypes;\r\n } else {\r\n this.argumentTypes = [];\r\n for (const p in argumentTypes) {\r\n const argumentIndex = this.argumentNames.indexOf(p);\r\n if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`);\r\n this.argumentTypes[argumentIndex] = argumentTypes[p];\r\n }\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n *\r\n * @param [Tactic] tactic\r\n * @return {Kernel}\r\n */\r\n setTactic(tactic) {\r\n this.tactic = tactic;\r\n return this;\r\n }\r\n\r\n requestFallback(args) {\r\n if (!this.onRequestFallback) {\r\n throw new Error(`\"onRequestFallback\" not defined on ${ this.constructor.name }`);\r\n }\r\n this.fallbackRequested = true;\r\n return this.onRequestFallback(args);\r\n }\r\n\r\n /**\r\n * @desc Validate settings\r\n * @abstract\r\n */\r\n validateSettings() {\r\n throw new Error(`\"validateSettings\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Add a sub kernel to the root kernel instance.\r\n * This is what `createKernelMap` uses.\r\n *\r\n * @param {ISubKernel} subKernel - function (as a String) of the subKernel to add\r\n */\r\n addSubKernel(subKernel) {\r\n if (this.subKernels === null) {\r\n this.subKernels = [];\r\n }\r\n if (!subKernel.source) throw new Error('subKernel missing \"source\" property');\r\n if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing \"property\" property');\r\n if (!subKernel.name) throw new Error('subKernel missing \"name\" property');\r\n this.subKernels.push(subKernel);\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Destroys all memory associated with this kernel\r\n * @param {Boolean} [removeCanvasReferences] remove any associated canvas references\r\n */\r\n destroy(removeCanvasReferences) {\r\n throw new Error(`\"destroy\" called on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4\r\n * @param value\r\n * @returns {number}\r\n */\r\n getBitRatio(value) {\r\n if (this.precision === 'single') {\r\n // 8 and 16 are upconverted to float32\r\n return 4;\r\n } else if (Array.isArray(value[0])) {\r\n return this.getBitRatio(value[0]);\r\n } else if (value.constructor === Input) {\r\n return this.getBitRatio(value.value);\r\n }\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n return 1;\r\n case Uint16Array:\r\n case Int16Array:\r\n return 2;\r\n case Float32Array:\r\n case Int32Array:\r\n default:\r\n return 4;\r\n }\r\n }\r\n\r\n /**\r\n * @returns {number[]}\r\n */\r\n getPixels() {\r\n throw new Error(`\"getPixels\" called on ${ this.constructor.name }`);\r\n }\r\n\r\n checkOutput() {\r\n if (!this.output || !isArray(this.output)) throw new Error('kernel.output not an array');\r\n if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value');\r\n for (let i = 0; i < this.output.length; i++) {\r\n if (isNaN(this.output[i]) || this.output[i] < 1) {\r\n throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \\`${ this.output[i] }\\`, needs to be numeric, and greater than 0`);\r\n }\r\n }\r\n }\r\n\r\n toJSON() {\r\n const settings = {\r\n output: this.output,\r\n threadDim: this.threadDim,\r\n pipeline: this.pipeline,\r\n argumentNames: this.argumentNames,\r\n argumentsTypes: this.argumentTypes,\r\n constants: this.constants,\r\n pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null,\r\n returnType: this.returnType,\r\n };\r\n return {\r\n settings\r\n };\r\n }\r\n}\r\n","/**\r\n * @desc This handles all the raw state, converted state, etc. of a single function.\r\n * [INTERNAL] A collection of functionNodes.\r\n * @class\r\n */\r\nexport class FunctionBuilder {\r\n /**\r\n *\r\n * @param {Kernel} kernel\r\n * @param {FunctionNode} FunctionNode\r\n * @param {object} [extraNodeOptions]\r\n * @returns {FunctionBuilder}\r\n * @static\r\n */\r\n static fromKernel(kernel, FunctionNode, extraNodeOptions) {\r\n const {\r\n kernelArguments,\r\n kernelConstants,\r\n argumentNames,\r\n argumentSizes,\r\n argumentBitRatios,\r\n constants,\r\n constantBitRatios,\r\n debug,\r\n loopMaxIterations,\r\n nativeFunctions,\r\n output,\r\n optimizeFloatMemory,\r\n precision,\r\n plugins,\r\n source,\r\n subKernels,\r\n functions,\r\n leadingReturnStatement,\r\n followingReturnStatement,\r\n dynamicArguments,\r\n dynamicOutput,\r\n warnVarUsage,\r\n } = kernel;\r\n\r\n const argumentTypes = new Array(kernelArguments.length);\r\n const constantTypes = {};\r\n\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n argumentTypes[i] = kernelArguments[i].type;\r\n }\r\n\r\n for (let i = 0; i < kernelConstants.length; i++) {\r\n const kernelConstant = kernelConstants[i]\r\n constantTypes[kernelConstant.name] = kernelConstant.type;\r\n }\r\n\r\n const needsArgumentType = (functionName, index) => {\r\n return functionBuilder.needsArgumentType(functionName, index);\r\n };\r\n\r\n const assignArgumentType = (functionName, index, type) => {\r\n functionBuilder.assignArgumentType(functionName, index, type);\r\n };\r\n\r\n const lookupReturnType = (functionName, ast, requestingNode) => {\r\n return functionBuilder.lookupReturnType(functionName, ast, requestingNode);\r\n };\r\n\r\n const lookupFunctionArgumentTypes = (functionName) => {\r\n return functionBuilder.lookupFunctionArgumentTypes(functionName);\r\n };\r\n\r\n const lookupFunctionArgumentName = (functionName, argumentIndex) => {\r\n return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex);\r\n };\r\n\r\n const lookupFunctionArgumentBitRatio = (functionName, argumentName) => {\r\n return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName);\r\n };\r\n\r\n const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => {\r\n functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode);\r\n };\r\n\r\n const triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => {\r\n functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex);\r\n };\r\n\r\n const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => {\r\n return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName);\r\n };\r\n\r\n const onFunctionCall = (functionName, calleeFunctionName, args) => {\r\n functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args);\r\n };\r\n\r\n const onNestedFunction = (ast, returnType) => {\r\n const argumentNames = [];\r\n for (let i = 0; i < ast.params.length; i++) {\r\n argumentNames.push(ast.params[i].name);\r\n }\r\n const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, {\r\n returnType: null,\r\n ast,\r\n name: ast.id.name,\r\n argumentNames,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n warnVarUsage,\r\n }));\r\n nestedFunction.traceFunctionAST(ast);\r\n functionBuilder.addFunctionNode(nestedFunction);\r\n };\r\n\r\n const nodeOptions = Object.assign({\r\n isRootKernel: false,\r\n onNestedFunction,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n optimizeFloatMemory,\r\n precision,\r\n constants,\r\n constantTypes,\r\n constantBitRatios,\r\n debug,\r\n loopMaxIterations,\r\n output,\r\n plugins,\r\n dynamicArguments,\r\n dynamicOutput,\r\n }, extraNodeOptions || {});\r\n\r\n const rootNodeOptions = Object.assign({}, nodeOptions, {\r\n isRootKernel: true,\r\n name: 'kernel',\r\n argumentNames,\r\n argumentTypes,\r\n argumentSizes,\r\n argumentBitRatios,\r\n leadingReturnStatement,\r\n followingReturnStatement,\r\n });\r\n\r\n if (typeof source === 'object' && source.functionNodes) {\r\n return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode);\r\n }\r\n\r\n const rootNode = new FunctionNode(source, rootNodeOptions);\r\n\r\n let functionNodes = null;\r\n if (functions) {\r\n functionNodes = functions.map((fn) => new FunctionNode(fn.source, {\r\n returnType: fn.returnType,\r\n argumentTypes: fn.argumentTypes,\r\n output,\r\n plugins,\r\n constants,\r\n constantTypes,\r\n constantBitRatios,\r\n optimizeFloatMemory,\r\n precision,\r\n lookupReturnType,\r\n lookupFunctionArgumentTypes,\r\n lookupFunctionArgumentName,\r\n lookupFunctionArgumentBitRatio,\r\n needsArgumentType,\r\n assignArgumentType,\r\n triggerImplyArgumentType,\r\n triggerTrackArgumentSynonym,\r\n lookupArgumentSynonym,\r\n onFunctionCall,\r\n }));\r\n }\r\n\r\n let subKernelNodes = null;\r\n if (subKernels) {\r\n subKernelNodes = subKernels.map((subKernel) => {\r\n const { name, source } = subKernel;\r\n return new FunctionNode(source, Object.assign({}, nodeOptions, {\r\n name,\r\n isSubKernel: true,\r\n isRootKernel: false,\r\n }));\r\n });\r\n }\r\n\r\n const functionBuilder = new FunctionBuilder({\r\n kernel,\r\n rootNode,\r\n functionNodes,\r\n nativeFunctions,\r\n subKernelNodes\r\n });\r\n\r\n return functionBuilder;\r\n }\r\n\r\n /**\r\n *\r\n * @param {IFunctionBuilderSettings} [settings]\r\n */\r\n constructor(settings) {\r\n settings = settings || {};\r\n this.kernel = settings.kernel;\r\n this.rootNode = settings.rootNode;\r\n this.functionNodes = settings.functionNodes || [];\r\n this.subKernelNodes = settings.subKernelNodes || [];\r\n this.nativeFunctions = settings.nativeFunctions || [];\r\n this.functionMap = {};\r\n this.nativeFunctionNames = [];\r\n this.lookupChain = [];\r\n this.argumentChain = [];\r\n this.functionNodeDependencies = {};\r\n this.functionCalls = {};\r\n\r\n if (this.rootNode) {\r\n this.functionMap['kernel'] = this.rootNode;\r\n }\r\n\r\n if (this.functionNodes) {\r\n for (let i = 0; i < this.functionNodes.length; i++) {\r\n this.functionMap[this.functionNodes[i].name] = this.functionNodes[i];\r\n }\r\n }\r\n\r\n if (this.subKernelNodes) {\r\n for (let i = 0; i < this.subKernelNodes.length; i++) {\r\n this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i];\r\n }\r\n }\r\n\r\n if (this.nativeFunctions) {\r\n for (let i = 0; i < this.nativeFunctions.length; i++) {\r\n const nativeFunction = this.nativeFunctions[i];\r\n this.nativeFunctionNames.push(nativeFunction.name);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @desc Add the function node directly\r\n *\r\n * @param {FunctionNode} functionNode - functionNode to add\r\n *\r\n */\r\n addFunctionNode(functionNode) {\r\n if (!functionNode.name) throw new Error('functionNode.name needs set');\r\n this.functionMap[functionNode.name] = functionNode;\r\n if (functionNode.isRootKernel) {\r\n this.rootNode = functionNode;\r\n }\r\n }\r\n\r\n /**\r\n * @desc Trace all the depending functions being called, from a single function\r\n *\r\n * This allow for 'unneeded' functions to be automatically optimized out.\r\n * Note that the 0-index, is the starting function trace.\r\n *\r\n * @param {String} functionName - Function name to trace from, default to 'kernel'\r\n * @param {String[]} [retList] - Returning list of function names that is traced. Including itself.\r\n *\r\n * @returns {String[]} Returning list of function names that is traced. Including itself.\r\n */\r\n traceFunctionCalls(functionName, retList) {\r\n functionName = functionName || 'kernel';\r\n retList = retList || [];\r\n\r\n if (this.nativeFunctionNames.indexOf(functionName) > -1) {\r\n if (retList.indexOf(functionName) === -1) {\r\n retList.push(functionName);\r\n }\r\n return retList;\r\n }\r\n\r\n const functionNode = this.functionMap[functionName];\r\n if (functionNode) {\r\n // Check if function already exists\r\n const functionIndex = retList.indexOf(functionName);\r\n if (functionIndex === -1) {\r\n retList.push(functionName);\r\n functionNode.toString(); //ensure JS trace is done\r\n for (let i = 0; i < functionNode.calledFunctions.length; ++i) {\r\n this.traceFunctionCalls(functionNode.calledFunctions[i], retList);\r\n }\r\n } else {\r\n /**\r\n * https://github.com/gpujs/gpu.js/issues/207\r\n * if dependent function is already in the list, because a function depends on it, and because it has\r\n * already been traced, we know that we must move the dependent function to the end of the the retList.\r\n * */\r\n const dependantFunctionName = retList.splice(functionIndex, 1)[0];\r\n retList.push(dependantFunctionName);\r\n }\r\n }\r\n\r\n return retList;\r\n }\r\n\r\n /**\r\n * @desc Return the string for a function\r\n * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {String} The full string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getPrototypeString(functionName) {\r\n return this.getPrototypes(functionName).join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Return the string for a function\r\n * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getPrototypes(functionName) {\r\n if (this.rootNode) {\r\n this.rootNode.toString();\r\n }\r\n if (functionName) {\r\n return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse());\r\n }\r\n return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap));\r\n }\r\n\r\n /**\r\n * @desc Get string from function names\r\n * @param {String[]} functionList - List of function to build string\r\n * @returns {String} The string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getStringFromFunctionNames(functionList) {\r\n const ret = [];\r\n for (let i = 0; i < functionList.length; ++i) {\r\n const node = this.functionMap[functionList[i]];\r\n if (node) {\r\n ret.push(this.functionMap[functionList[i]].toString());\r\n }\r\n }\r\n return ret.join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Return string of all functions converted\r\n * @param {String[]} functionList - List of function names to build the string.\r\n * @returns {Array} Prototypes of all functions converted\r\n */\r\n getPrototypesFromFunctionNames(functionList) {\r\n const ret = [];\r\n for (let i = 0; i < functionList.length; ++i) {\r\n const functionName = functionList[i];\r\n const functionIndex = this.nativeFunctionNames.indexOf(functionName);\r\n if (functionIndex > -1) {\r\n ret.push(this.nativeFunctions[functionIndex].source);\r\n continue;\r\n }\r\n const node = this.functionMap[functionName];\r\n if (node) {\r\n ret.push(node.toString());\r\n }\r\n }\r\n return ret;\r\n }\r\n\r\n toJSON() {\r\n return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => {\r\n const nativeIndex = this.nativeFunctions.indexOf(name);\r\n if (nativeIndex > -1) {\r\n return {\r\n name,\r\n source: this.nativeFunctions[nativeIndex].source\r\n };\r\n } else if (this.functionMap[name]) {\r\n return this.functionMap[name].toJSON();\r\n } else {\r\n throw new Error(`function ${ name } not found`);\r\n }\r\n });\r\n }\r\n\r\n fromJSON(jsonFunctionNodes, FunctionNode) {\r\n this.functionMap = {};\r\n for (let i = 0; i < jsonFunctionNodes.length; i++) {\r\n const jsonFunctionNode = jsonFunctionNodes[i];\r\n this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Get string for a particular function name\r\n * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack\r\n * @returns {String} settings - The string, of all the various functions. Trace optimized if functionName given\r\n */\r\n getString(functionName) {\r\n if (functionName) {\r\n return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse());\r\n }\r\n return this.getStringFromFunctionNames(Object.keys(this.functionMap));\r\n }\r\n\r\n lookupReturnType(functionName, ast, requestingNode) {\r\n if (ast.type !== 'CallExpression') {\r\n throw new Error(`expected ast type of \"CallExpression\", but is ${ ast.type }`);\r\n }\r\n if (this._isNativeFunction(functionName)) {\r\n return this._lookupNativeFunctionReturnType(functionName);\r\n } else if (this._isFunction(functionName)) {\r\n const node = this._getFunction(functionName);\r\n if (node.returnType) {\r\n return node.returnType;\r\n } else {\r\n for (let i = 0; i < this.lookupChain.length; i++) {\r\n // detect circlical logic\r\n if (this.lookupChain[i].ast === ast) {\r\n // detect if arguments have not resolved, preventing a return type\r\n // if so, go ahead and resolve them, so we can resolve the return type\r\n if (node.argumentTypes.length === 0 && ast.arguments.length > 0) {\r\n const args = ast.arguments;\r\n for (let j = 0; j < args.length; j++) {\r\n this.lookupChain.push({\r\n name: requestingNode.name,\r\n ast: args[i],\r\n requestingNode\r\n });\r\n node.argumentTypes[j] = requestingNode.getType(args[j]);\r\n this.lookupChain.pop();\r\n }\r\n return node.returnType = node.getType(node.getJsAST());\r\n }\r\n\r\n throw new Error('circlical logic detected!');\r\n }\r\n }\r\n // get ready for a ride!\r\n this.lookupChain.push({\r\n name: requestingNode.name,\r\n ast,\r\n requestingNode\r\n });\r\n const type = node.getType(node.getJsAST());\r\n this.lookupChain.pop();\r\n return node.returnType = type;\r\n }\r\n }\r\n\r\n // function not found, maybe native?\r\n return null;\r\n\r\n /**\r\n * first iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = null\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = null\r\n * calcErrorOutput.targets = null\r\n * calcErrorOutput.returns = null\r\n * calcDeltasSigmoid.error = null\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = null\r\n *\r\n * resolvable are:\r\n * calcErrorOutput.output\r\n * calcErrorOutput.targets\r\n * calcErrorOutput.returns\r\n *\r\n * second iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = null\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = Number\r\n * calcErrorOutput.targets = Array\r\n * calcErrorOutput.returns = Number\r\n * calcDeltasSigmoid.error = null\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = null\r\n *\r\n * resolvable are:\r\n * calcDeltasSigmoid.error\r\n * calcDeltasSigmoid.returns\r\n * kernel.returns\r\n *\r\n * third iteration\r\n * kernel.outputs = Array\r\n * kernel.targets = Array\r\n * kernel.returns = Number\r\n * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets]\r\n * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output]\r\n * calcErrorOutput.output = Number\r\n * calcErrorOutput.targets = Array\r\n * calcErrorOutput.returns = Number\r\n * calcDeltasSigmoid.error = Number\r\n * calcDeltasSigmoid.output = Number\r\n * calcDeltasSigmoid.returns = Number\r\n *\r\n *\r\n */\r\n }\r\n\r\n _getFunction(functionName) {\r\n if (!this._isFunction(functionName)) {\r\n new Error(`Function ${functionName} not found`);\r\n }\r\n return this.functionMap[functionName];\r\n }\r\n\r\n _isFunction(functionName) {\r\n return Boolean(this.functionMap[functionName]);\r\n }\r\n\r\n _getNativeFunction(functionName) {\r\n for (let i = 0; i < this.nativeFunctions.length; i++) {\r\n if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i];\r\n }\r\n return null;\r\n }\r\n\r\n _isNativeFunction(functionName) {\r\n return Boolean(this._getNativeFunction(functionName));\r\n }\r\n\r\n _lookupNativeFunctionReturnType(functionName) {\r\n let nativeFunction = this._getNativeFunction(functionName);\r\n if (nativeFunction) {\r\n return nativeFunction.returnType;\r\n }\r\n throw new Error(`Native function ${ functionName } not found`);\r\n }\r\n\r\n lookupFunctionArgumentTypes(functionName) {\r\n if (this._isNativeFunction(functionName)) {\r\n return this._getNativeFunction(functionName).argumentTypes;\r\n } else if (this._isFunction(functionName)) {\r\n return this._getFunction(functionName).argumentTypes;\r\n }\r\n return null;\r\n }\r\n\r\n lookupFunctionArgumentName(functionName, argumentIndex) {\r\n return this._getFunction(functionName).argumentNames[argumentIndex];\r\n }\r\n\r\n lookupFunctionArgumentBitRatio(functionName, argumentName) {\r\n if (!this._isFunction(functionName)) {\r\n throw new Error('function not found');\r\n }\r\n if (this.rootNode.name === functionName) {\r\n const i = this.rootNode.argumentNames.indexOf(argumentName);\r\n if (i !== -1) {\r\n return this.rootNode.argumentBitRatios[i];\r\n } else {\r\n throw new Error('argument bit ratio not found');\r\n }\r\n } else {\r\n const node = this._getFunction(functionName);\r\n const argumentSynonym = node.argumentSynonym[node.synonymIndex];\r\n if (!argumentSynonym) {\r\n throw new Error('argument synonym not found');\r\n }\r\n return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName);\r\n }\r\n }\r\n\r\n needsArgumentType(functionName, i) {\r\n if (!this._isFunction(functionName)) return false;\r\n const fnNode = this._getFunction(functionName);\r\n return !fnNode.argumentTypes[i];\r\n }\r\n\r\n assignArgumentType(functionName, i, argumentType, requestingNode) {\r\n if (!this._isFunction(functionName)) return;\r\n const fnNode = this._getFunction(functionName);\r\n if (!fnNode.argumentTypes[i]) {\r\n fnNode.argumentTypes[i] = argumentType;\r\n }\r\n }\r\n\r\n trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) {\r\n if (!this._isFunction(calleeFunctionName)) return;\r\n const node = this._getFunction(calleeFunctionName);\r\n if (!node.argumentSynonym) {\r\n node.argumentSynonym = {};\r\n }\r\n const calleeArgumentName = node.argumentNames[argumentIndex];\r\n if (!node.argumentSynonym[calleeArgumentName]) {\r\n node.argumentSynonym[calleeArgumentName] = {};\r\n }\r\n node.synonymIndex++;\r\n node.argumentSynonym[node.synonymIndex] = {\r\n functionName,\r\n argumentName,\r\n calleeArgumentName,\r\n calleeFunctionName,\r\n };\r\n }\r\n\r\n lookupArgumentSynonym(originFunctionName, functionName, argumentName) {\r\n if (originFunctionName === functionName) return argumentName;\r\n if (!this._isFunction(functionName)) return null;\r\n const node = this._getFunction(functionName);\r\n const argumentSynonym = node.argumentSynonym[node.synonymUseIndex];\r\n if (!argumentSynonym) return null;\r\n if (argumentSynonym.calleeArgumentName !== argumentName) return null;\r\n node.synonymUseIndex++;\r\n if (originFunctionName !== functionName) {\r\n return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName);\r\n }\r\n return argumentSynonym.argumentName;\r\n }\r\n\r\n trackFunctionCall(functionName, calleeFunctionName, args) {\r\n if (!this.functionNodeDependencies[functionName]) {\r\n this.functionNodeDependencies[functionName] = new Set();\r\n this.functionCalls[functionName] = [];\r\n }\r\n this.functionNodeDependencies[functionName].add(calleeFunctionName);\r\n this.functionCalls[functionName].push(args);\r\n }\r\n\r\n getKernelResultType() {\r\n return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast);\r\n }\r\n\r\n getSubKernelResultType(index) {\r\n const subKernelNode = this.subKernelNodes[index];\r\n let called = false;\r\n for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) {\r\n const functionCall = this.rootNode.functionCalls[functionCallIndex];\r\n if (functionCall.ast.callee.name === subKernelNode.name) {\r\n called = true;\r\n }\r\n }\r\n if (!called) {\r\n throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`);\r\n }\r\n return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST());\r\n }\r\n\r\n getReturnTypes() {\r\n const result = {\r\n [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast),\r\n };\r\n const list = this.traceFunctionCalls(this.rootNode.name);\r\n for (let i = 0; i < list.length; i++) {\r\n const functionName = list[i];\r\n const functionNode = this.functionMap[functionName];\r\n result[functionName] = functionNode.getType(functionNode.ast);\r\n }\r\n return result;\r\n }\r\n}\r\n","export class FunctionTracer {\r\n constructor(ast) {\r\n this.runningContexts = [];\r\n this.contexts = [];\r\n this.functionCalls = [];\r\n this.declarations = [];\r\n this.identifiers = [];\r\n this.functions = [];\r\n this.returnStatements = [];\r\n this.inLoopInit = false;\r\n this.scan(ast);\r\n }\r\n\r\n get currentContext() {\r\n return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null;\r\n }\r\n\r\n newContext(run) {\r\n const newContext = Object.assign({}, this.currentContext);\r\n this.contexts.push(newContext);\r\n this.runningContexts.push(newContext);\r\n run();\r\n this.runningContexts.pop();\r\n }\r\n\r\n /**\r\n * Recursively scans AST for declarations and functions, and add them to their respective context\r\n * @param ast\r\n */\r\n scan(ast) {\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.scan(ast[i]);\r\n }\r\n return;\r\n }\r\n switch (ast.type) {\r\n case 'Program':\r\n this.scan(ast.body);\r\n break;\r\n case 'BlockStatement':\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n });\r\n break;\r\n case 'AssignmentExpression':\r\n case 'LogicalExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'BinaryExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'UpdateExpression':\r\n case 'UnaryExpression':\r\n this.scan(ast.argument);\r\n break;\r\n case 'VariableDeclaration':\r\n this.scan(ast.declarations);\r\n break;\r\n case 'VariableDeclarator':\r\n const { currentContext } = this;\r\n const declaration = {\r\n ast: ast,\r\n context: currentContext,\r\n name: ast.id.name,\r\n origin: 'declaration',\r\n forceInteger: this.inLoopInit,\r\n assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name),\r\n };\r\n currentContext[ast.id.name] = declaration;\r\n this.declarations.push(declaration);\r\n this.scan(ast.id);\r\n this.scan(ast.init);\r\n break;\r\n case 'FunctionExpression':\r\n case 'FunctionDeclaration':\r\n if (this.runningContexts.length === 0) {\r\n this.scan(ast.body);\r\n } else {\r\n this.functions.push(ast);\r\n }\r\n break;\r\n case 'IfStatement':\r\n this.scan(ast.test);\r\n this.scan(ast.consequent);\r\n if (ast.alternate) this.scan(ast.alternate);\r\n break;\r\n case 'ForStatement':\r\n this.newContext(() => {\r\n this.inLoopInit = true;\r\n this.scan(ast.init);\r\n this.inLoopInit = false;\r\n this.scan(ast.test);\r\n this.scan(ast.update);\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n });\r\n });\r\n break;\r\n case 'DoWhileStatement':\r\n case 'WhileStatement':\r\n this.newContext(() => {\r\n this.scan(ast.body);\r\n this.scan(ast.test);\r\n });\r\n break;\r\n case 'Identifier':\r\n this.identifiers.push({\r\n context: this.currentContext,\r\n ast,\r\n });\r\n break;\r\n case 'ReturnStatement':\r\n this.returnStatements.push(ast);\r\n this.scan(ast.argument);\r\n break;\r\n case 'MemberExpression':\r\n this.scan(ast.object);\r\n this.scan(ast.property);\r\n break;\r\n case 'ExpressionStatement':\r\n this.scan(ast.expression);\r\n break;\r\n case 'CallExpression':\r\n this.functionCalls.push({\r\n context: this.currentContext,\r\n ast,\r\n });\r\n this.scan(ast.arguments);\r\n break;\r\n case 'ArrayExpression':\r\n this.scan(ast.elements);\r\n break;\r\n case 'ConditionalExpression':\r\n this.scan(ast.test);\r\n this.scan(ast.alternate);\r\n this.scan(ast.consequent);\r\n break;\r\n case 'SwitchStatement':\r\n this.scan(ast.discriminant);\r\n this.scan(ast.cases);\r\n break;\r\n case 'SwitchCase':\r\n this.scan(ast.test);\r\n this.scan(ast.consequent);\r\n break;\r\n case 'ThisExpression':\r\n this.scan(ast.left);\r\n this.scan(ast.right);\r\n break;\r\n case 'Literal':\r\n case 'DebuggerStatement':\r\n case 'EmptyStatement':\r\n case 'BreakStatement':\r\n case 'ContinueStatement':\r\n break;\r\n default:\r\n throw new Error(`unhandled type \"${ast.type}\"`);\r\n }\r\n }\r\n}\r\n","import { parse } from 'acorn';\r\nimport { FunctionTracer } from './function-tracer';\r\nimport {\r\n getArgumentNamesFromString,\r\n getAstString,\r\n getFunctionNameFromString,\r\n isFunctionString,\r\n} from '../common';\r\n\r\n/**\r\n *\r\n * @desc Represents a single function, inside JS, webGL, or openGL.\r\n *

This handles all the raw state, converted state, etc. Of a single function.

\r\n */\r\nexport class FunctionNode {\r\n /**\r\n *\r\n * @param {string|object} source\r\n * @param {IFunctionSettings} [settings]\r\n */\r\n constructor(source, settings) {\r\n if (!source && !settings.ast) {\r\n throw new Error('source parameter is missing');\r\n }\r\n settings = settings || {};\r\n this.source = source;\r\n this.ast = null;\r\n this.name = typeof source === 'string' ? settings.isRootKernel ?\r\n 'kernel' :\r\n (settings.name || getFunctionNameFromString(source)) : null;\r\n this.calledFunctions = [];\r\n this.constants = {};\r\n this.constantTypes = {};\r\n this.constantBitRatios = {};\r\n this.isRootKernel = false;\r\n this.isSubKernel = false;\r\n this.debug = null;\r\n this.declarations = null;\r\n this.functions = null;\r\n this.identifiers = null;\r\n this.contexts = null;\r\n this.functionCalls = null;\r\n this.states = [];\r\n this.needsArgumentType = null;\r\n this.assignArgumentType = null;\r\n this.lookupReturnType = null;\r\n this.lookupFunctionArgumentTypes = null;\r\n this.lookupFunctionArgumentBitRatio = null;\r\n this.triggerImplyArgumentType = null;\r\n this.triggerImplyArgumentBitRatio = null;\r\n this.onNestedFunction = null;\r\n this.onFunctionCall = null;\r\n this.optimizeFloatMemory = null;\r\n this.precision = null;\r\n this.loopMaxIterations = null;\r\n this.argumentNames = (typeof this.source === 'string' ? getArgumentNamesFromString(this.source) : null);\r\n this.argumentTypes = [];\r\n this.argumentSizes = [];\r\n this.argumentBitRatios = null;\r\n this.returnType = null;\r\n this.output = [];\r\n this.plugins = null;\r\n this.leadingReturnStatement = null;\r\n this.followingReturnStatement = null;\r\n this.dynamicOutput = null;\r\n this.dynamicArguments = null;\r\n this.strictTypingChecking = false;\r\n this.fixIntegerDivisionAccuracy = null;\r\n this.warnVarUsage = true;\r\n\r\n if (settings) {\r\n for (const p in settings) {\r\n if (!settings.hasOwnProperty(p)) continue;\r\n if (!this.hasOwnProperty(p)) continue;\r\n this[p] = settings[p];\r\n }\r\n }\r\n\r\n this.literalTypes = {};\r\n\r\n this.validate();\r\n this._string = null;\r\n this._internalVariableNames = {};\r\n }\r\n\r\n validate() {\r\n if (typeof this.source !== 'string' && !this.ast) {\r\n throw new Error('this.source not a string');\r\n }\r\n\r\n if (!this.ast && !isFunctionString(this.source)) {\r\n throw new Error('this.source not a function string');\r\n }\r\n\r\n if (!this.name) {\r\n throw new Error('this.name could not be set');\r\n }\r\n\r\n if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) {\r\n throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`);\r\n }\r\n\r\n if (this.output.length < 1) {\r\n throw new Error('this.output is not big enough');\r\n }\r\n }\r\n\r\n /**\r\n * @param {String} name\r\n * @returns {boolean}\r\n */\r\n isIdentifierConstant(name) {\r\n if (!this.constants) return false;\r\n return this.constants.hasOwnProperty(name);\r\n }\r\n\r\n isInput(argumentName) {\r\n return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input';\r\n }\r\n\r\n pushState(state) {\r\n this.states.push(state);\r\n }\r\n\r\n popState(state) {\r\n if (this.state !== state) {\r\n throw new Error(`Cannot popState ${ state } when in ${ this.state }`);\r\n }\r\n this.states.pop();\r\n }\r\n\r\n isState(state) {\r\n return this.state === state;\r\n }\r\n\r\n get state() {\r\n return this.states[this.states.length - 1];\r\n }\r\n\r\n /**\r\n * @function\r\n * @name astMemberExpressionUnroll\r\n * @desc Parses the abstract syntax tree for binary expression.\r\n *\r\n *

Utility function for astCallExpression.

\r\n *\r\n * @param {Object} ast - the AST object to parse\r\n *\r\n * @returns {String} the function namespace call, unrolled\r\n */\r\n astMemberExpressionUnroll(ast) {\r\n if (ast.type === 'Identifier') {\r\n return ast.name;\r\n } else if (ast.type === 'ThisExpression') {\r\n return 'this';\r\n }\r\n\r\n if (ast.type === 'MemberExpression') {\r\n if (ast.object && ast.property) {\r\n //babel sniffing\r\n if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') {\r\n return this.astMemberExpressionUnroll(ast.property);\r\n }\r\n\r\n return (\r\n this.astMemberExpressionUnroll(ast.object) +\r\n '.' +\r\n this.astMemberExpressionUnroll(ast.property)\r\n );\r\n }\r\n }\r\n\r\n //babel sniffing\r\n if (ast.hasOwnProperty('expressions')) {\r\n const firstExpression = ast.expressions[0];\r\n if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) {\r\n return this.astMemberExpressionUnroll(ast.expressions[1]);\r\n }\r\n }\r\n\r\n // Failure, unknown expression\r\n throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast);\r\n }\r\n\r\n /**\r\n * @desc Parses the class function JS, and returns its Abstract Syntax Tree object.\r\n * This is used internally to convert to shader code\r\n *\r\n * @param {Object} [inParser] - Parser to use, assumes in scope 'parser' if null or undefined\r\n *\r\n * @returns {Object} The function AST Object, note that result is cached under this.ast;\r\n */\r\n getJsAST(inParser) {\r\n if (this.ast) {\r\n return this.ast;\r\n }\r\n if (typeof this.source === 'object') {\r\n this.traceFunctionAST(this.source);\r\n return this.ast = this.source;\r\n }\r\n\r\n const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : parse\r\n if (inParser === null) {\r\n throw new Error('Missing JS to AST parser');\r\n }\r\n\r\n const ast = Object.freeze(parser(`const parser_${ this.name } = ${ this.source };`, {\r\n locations: true\r\n }));\r\n // take out the function object, outside the var declarations\r\n const functionAST = ast.body[0].declarations[0].init;\r\n this.traceFunctionAST(functionAST);\r\n\r\n if (!ast) {\r\n throw new Error('Failed to parse JS code');\r\n }\r\n\r\n return this.ast = functionAST;\r\n }\r\n\r\n traceFunctionAST(ast) {\r\n const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast);\r\n this.contexts = contexts;\r\n this.identifiers = identifiers;\r\n this.functionCalls = functionCalls;\r\n this.declarations = [];\r\n this.functions = functions;\r\n for (let i = 0; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n const { ast, context, name, origin, forceInteger, assignable } = declaration;\r\n const { init } = ast;\r\n const dependencies = this.getDependencies(init);\r\n let valueType = null;\r\n\r\n if (forceInteger) {\r\n valueType = 'Integer';\r\n } else {\r\n if (init) {\r\n const realType = this.getType(init);\r\n switch (realType) {\r\n case 'Integer':\r\n case 'Float':\r\n case 'Number':\r\n if (init.type === 'MemberExpression') {\r\n valueType = realType;\r\n } else {\r\n valueType = 'Number';\r\n }\r\n break;\r\n case 'LiteralInteger':\r\n valueType = 'Number';\r\n break;\r\n default:\r\n valueType = realType;\r\n }\r\n }\r\n }\r\n this.declarations.push({\r\n valueType,\r\n dependencies,\r\n isSafe: this.isSafeDependencies(dependencies),\r\n ast,\r\n name,\r\n context,\r\n origin,\r\n assignable,\r\n });\r\n }\r\n\r\n for (let i = 0; i < functions.length; i++) {\r\n this.onNestedFunction(functions[i]);\r\n }\r\n }\r\n\r\n getDeclaration(ast) {\r\n for (let i = 0; i < this.identifiers.length; i++) {\r\n const identifier = this.identifiers[i];\r\n if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) {\r\n for (let j = 0; j < this.declarations.length; j++) {\r\n const declaration = this.declarations[j];\r\n if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) {\r\n return declaration;\r\n }\r\n }\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * @desc Return the type of parameter sent to subKernel/Kernel.\r\n * @param {Object} ast - Identifier\r\n * @returns {String} Type of the parameter\r\n */\r\n getVariableType(ast) {\r\n if (ast.type !== 'Identifier') {\r\n throw new Error(`ast of ${ast.type} not \"Identifier\"`);\r\n }\r\n let type = null;\r\n const argumentIndex = this.argumentNames.indexOf(ast.name);\r\n if (argumentIndex === -1) {\r\n const declaration = this.getDeclaration(ast);\r\n if (declaration) {\r\n return declaration.valueType;\r\n }\r\n } else {\r\n const argumentType = this.argumentTypes[argumentIndex];\r\n if (argumentType) {\r\n type = argumentType;\r\n }\r\n }\r\n if (!type && this.strictTypingChecking) {\r\n throw new Error(`Declaration of ${name} not found`);\r\n }\r\n return type;\r\n }\r\n\r\n /**\r\n * Generally used to lookup the value type returned from a member expressions\r\n * @param {String} type\r\n * @return {String}\r\n */\r\n getLookupType(type) {\r\n if (!typeLookupMap.hasOwnProperty(type)) {\r\n throw new Error(`unknown typeLookupMap ${ type }`);\r\n }\r\n return typeLookupMap[type];\r\n }\r\n\r\n getConstantType(constantName) {\r\n if (this.constantTypes[constantName]) {\r\n const type = this.constantTypes[constantName];\r\n if (type === 'Float') {\r\n return 'Number';\r\n } else {\r\n return type;\r\n }\r\n }\r\n throw new Error(`Type for constant \"${ constantName }\" not declared`);\r\n }\r\n\r\n toString() {\r\n if (this._string) return this._string;\r\n return this._string = this.astGeneric(this.getJsAST(), []).join('').trim();\r\n }\r\n\r\n toJSON() {\r\n const settings = {\r\n source: this.source,\r\n name: this.name,\r\n constants: this.constants,\r\n constantTypes: this.constantTypes,\r\n isRootKernel: this.isRootKernel,\r\n isSubKernel: this.isSubKernel,\r\n debug: this.debug,\r\n output: this.output,\r\n loopMaxIterations: this.loopMaxIterations,\r\n argumentNames: this.argumentNames,\r\n argumentTypes: this.argumentTypes,\r\n argumentSizes: this.argumentSizes,\r\n returnType: this.returnType,\r\n leadingReturnStatement: this.leadingReturnStatement,\r\n followingReturnStatement: this.followingReturnStatement,\r\n };\r\n\r\n return {\r\n ast: this.ast,\r\n settings\r\n };\r\n }\r\n\r\n /**\r\n * Recursively looks up type for ast expression until it's found\r\n * @param ast\r\n * @returns {String|null}\r\n */\r\n getType(ast) {\r\n if (Array.isArray(ast)) {\r\n return this.getType(ast[ast.length - 1]);\r\n }\r\n switch (ast.type) {\r\n case 'BlockStatement':\r\n return this.getType(ast.body);\r\n case 'ArrayExpression':\r\n return `Array(${ ast.elements.length })`;\r\n case 'Literal':\r\n const literalKey = `${ast.start},${ast.end}`;\r\n if (this.literalTypes[literalKey]) {\r\n return this.literalTypes[literalKey];\r\n }\r\n if (Number.isInteger(ast.value)) {\r\n return 'LiteralInteger';\r\n } else if (ast.value === true || ast.value === false) {\r\n return 'Boolean';\r\n } else {\r\n return 'Number';\r\n }\r\n case 'AssignmentExpression':\r\n return this.getType(ast.left);\r\n case 'CallExpression':\r\n if (this.isAstMathFunction(ast)) {\r\n return 'Number';\r\n }\r\n if (!ast.callee || !ast.callee.name) {\r\n if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) {\r\n const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name;\r\n this.inferArgumentTypesIfNeeded(functionName, ast.arguments);\r\n return this.lookupReturnType(functionName, ast, this);\r\n }\r\n throw this.astErrorOutput('Unknown call expression', ast);\r\n }\r\n if (ast.callee && ast.callee.name) {\r\n const functionName = ast.callee.name;\r\n this.inferArgumentTypesIfNeeded(functionName, ast.arguments);\r\n return this.lookupReturnType(functionName, ast, this);\r\n }\r\n throw this.astErrorOutput(`Unhandled getType Type \"${ ast.type }\"`, ast);\r\n case 'BinaryExpression':\r\n // modulos is Number\r\n switch (ast.operator) {\r\n case '%':\r\n case '/':\r\n if (this.fixIntegerDivisionAccuracy) {\r\n return 'Number';\r\n } else {\r\n break;\r\n }\r\n case '>':\r\n case '<':\r\n return 'Boolean';\r\n case '&':\r\n case '|':\r\n case '^':\r\n case '<<':\r\n case '>>':\r\n case '>>>':\r\n return 'Integer';\r\n }\r\n const type = this.getType(ast.left);\r\n if (this.isState('skip-literal-correction')) return type;\r\n if (type === 'LiteralInteger') {\r\n const rightType = this.getType(ast.right);\r\n if (rightType === 'LiteralInteger') {\r\n if (ast.left.value % 1 === 0) {\r\n return 'Integer';\r\n } else {\r\n return 'Float';\r\n }\r\n }\r\n return rightType;\r\n }\r\n return typeLookupMap[type] || type;\r\n case 'UpdateExpression':\r\n return this.getType(ast.argument);\r\n case 'UnaryExpression':\r\n if (ast.operator === '~') {\r\n return 'Integer';\r\n }\r\n return this.getType(ast.argument);\r\n case 'VariableDeclaration': {\r\n const declarations = ast.declarations;\r\n let lastType;\r\n for (let i = 0; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n lastType = this.getType(declaration);\r\n }\r\n if (!lastType) {\r\n throw this.astErrorOutput(`Unable to find type for declaration`, ast);\r\n }\r\n return lastType;\r\n }\r\n case 'VariableDeclarator':\r\n const declaration = this.getDeclaration(ast.id);\r\n if (!declaration) {\r\n throw this.astErrorOutput(`Unable to find declarator`, ast);\r\n }\r\n\r\n if (!declaration.valueType) {\r\n throw this.astErrorOutput(`Unable to find declarator valueType`, ast);\r\n }\r\n\r\n return declaration.valueType;\r\n case 'Identifier':\r\n if (ast.name === 'Infinity') {\r\n return 'Number';\r\n }\r\n if (this.isAstVariable(ast)) {\r\n const signature = this.getVariableSignature(ast);\r\n if (signature === 'value') {\r\n const type = this.getVariableType(ast);\r\n if (!type) {\r\n throw this.astErrorOutput(`Unable to find identifier valueType`, ast);\r\n }\r\n return type;\r\n }\r\n }\r\n const origin = this.findIdentifierOrigin(ast);\r\n if (origin && origin.init) {\r\n return this.getType(origin.init);\r\n }\r\n return null;\r\n case 'ReturnStatement':\r\n return this.getType(ast.argument);\r\n case 'MemberExpression':\r\n if (this.isAstMathFunction(ast)) {\r\n switch (ast.property.name) {\r\n case 'ceil':\r\n return 'Integer';\r\n case 'floor':\r\n return 'Integer';\r\n case 'round':\r\n return 'Integer';\r\n }\r\n return 'Number';\r\n }\r\n if (this.isAstVariable(ast)) {\r\n const variableSignature = this.getVariableSignature(ast);\r\n switch (variableSignature) {\r\n case 'value[]':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'value[][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object));\r\n case 'value[][][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object.object));\r\n case 'value[][][][]':\r\n return this.getLookupType(this.getVariableType(ast.object.object.object.object));\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n return 'Integer';\r\n case 'this.output.value':\r\n return this.dynamicOutput ? 'Integer' : 'LiteralInteger';\r\n case 'this.constants.value':\r\n return this.getConstantType(ast.property.name);\r\n case 'this.constants.value[]':\r\n return this.getLookupType(this.getConstantType(ast.object.property.name));\r\n case 'this.constants.value[][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.property.name));\r\n case 'this.constants.value[][][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.object.property.name));\r\n case 'this.constants.value[][][][]':\r\n return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name));\r\n case 'fn()[]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'fn()[][]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'fn()[][][]':\r\n return this.getLookupType(this.getType(ast.object));\r\n case 'value.value':\r\n if (this.isAstMathVariable(ast)) {\r\n return 'Number';\r\n }\r\n switch (ast.property.name) {\r\n case 'r':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'g':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'b':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n case 'a':\r\n return this.getLookupType(this.getVariableType(ast.object));\r\n }\r\n case '[][]':\r\n return 'Number';\r\n }\r\n throw this.astErrorOutput('Unhandled getType MemberExpression', ast);\r\n }\r\n throw this.astErrorOutput('Unhandled getType MemberExpression', ast);\r\n case 'ConditionalExpression':\r\n return this.getType(ast.consequent);\r\n case 'FunctionDeclaration':\r\n case 'FunctionExpression':\r\n const lastReturn = this.findLastReturn(ast.body);\r\n if (lastReturn) {\r\n return this.getType(lastReturn);\r\n }\r\n return null;\r\n case 'IfStatement':\r\n return this.getType(ast.consequent);\r\n default:\r\n throw this.astErrorOutput(`Unhandled getType Type \"${ ast.type }\"`, ast);\r\n }\r\n }\r\n\r\n inferArgumentTypesIfNeeded(functionName, args) {\r\n // ensure arguments are filled in, so when we lookup return type, we already can infer it\r\n for (let i = 0; i < args.length; i++) {\r\n if (!this.needsArgumentType(functionName, i)) continue;\r\n const type = this.getType(args[i]);\r\n if (!type) {\r\n throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]);\r\n }\r\n this.assignArgumentType(functionName, i, type);\r\n }\r\n }\r\n\r\n isAstMathVariable(ast) {\r\n const mathProperties = [\r\n 'E',\r\n 'PI',\r\n 'SQRT2',\r\n 'SQRT1_2',\r\n 'LN2',\r\n 'LN10',\r\n 'LOG2E',\r\n 'LOG10E',\r\n ];\r\n return ast.type === 'MemberExpression' &&\r\n ast.object && ast.object.type === 'Identifier' &&\r\n ast.object.name === 'Math' &&\r\n ast.property &&\r\n ast.property.type === 'Identifier' &&\r\n mathProperties.indexOf(ast.property.name) > -1;\r\n }\r\n\r\n isAstMathFunction(ast) {\r\n const mathFunctions = [\r\n 'abs',\r\n 'acos',\r\n 'asin',\r\n 'atan',\r\n 'atan2',\r\n 'ceil',\r\n 'cos',\r\n 'exp',\r\n 'floor',\r\n 'log',\r\n 'log2',\r\n 'max',\r\n 'min',\r\n 'pow',\r\n 'random',\r\n 'round',\r\n 'sign',\r\n 'sin',\r\n 'sqrt',\r\n 'tan',\r\n ];\r\n return ast.type === 'CallExpression' &&\r\n ast.callee &&\r\n ast.callee.type === 'MemberExpression' &&\r\n ast.callee.object &&\r\n ast.callee.object.type === 'Identifier' &&\r\n ast.callee.object.name === 'Math' &&\r\n ast.callee.property &&\r\n ast.callee.property.type === 'Identifier' &&\r\n mathFunctions.indexOf(ast.callee.property.name) > -1;\r\n }\r\n\r\n isAstVariable(ast) {\r\n return ast.type === 'Identifier' || ast.type === 'MemberExpression';\r\n }\r\n\r\n isSafe(ast) {\r\n return this.isSafeDependencies(this.getDependencies(ast));\r\n }\r\n\r\n isSafeDependencies(dependencies) {\r\n return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true;\r\n }\r\n\r\n /**\r\n *\r\n * @param ast\r\n * @param dependencies\r\n * @param isNotSafe\r\n * @return {Array}\r\n */\r\n getDependencies(ast, dependencies, isNotSafe) {\r\n if (!dependencies) {\r\n dependencies = [];\r\n }\r\n if (!ast) return null;\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.getDependencies(ast[i], dependencies, isNotSafe);\r\n }\r\n return dependencies;\r\n }\r\n switch (ast.type) {\r\n case 'AssignmentExpression':\r\n this.getDependencies(ast.left, dependencies, isNotSafe);\r\n this.getDependencies(ast.right, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'ConditionalExpression':\r\n this.getDependencies(ast.test, dependencies, isNotSafe);\r\n this.getDependencies(ast.alternate, dependencies, isNotSafe);\r\n this.getDependencies(ast.consequent, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'Literal':\r\n dependencies.push({\r\n origin: 'literal',\r\n value: ast.value,\r\n isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value)\r\n });\r\n break;\r\n case 'VariableDeclarator':\r\n return this.getDependencies(ast.init, dependencies, isNotSafe);\r\n case 'Identifier':\r\n const declaration = this.getDeclaration(ast);\r\n if (declaration) {\r\n dependencies.push({\r\n name: ast.name,\r\n origin: 'declaration',\r\n isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies),\r\n });\r\n } else if (this.argumentNames.indexOf(ast.name) > -1) {\r\n dependencies.push({\r\n name: ast.name,\r\n origin: 'argument',\r\n isSafe: false,\r\n });\r\n } else if (this.strictTypingChecking) {\r\n throw new Error(`Cannot find identifier origin \"${ast.name}\"`);\r\n }\r\n break;\r\n case 'FunctionDeclaration':\r\n return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe);\r\n case 'ReturnStatement':\r\n return this.getDependencies(ast.argument, dependencies);\r\n case 'BinaryExpression':\r\n isNotSafe = (ast.operator === '/' || ast.operator === '*');\r\n this.getDependencies(ast.left, dependencies, isNotSafe);\r\n this.getDependencies(ast.right, dependencies, isNotSafe);\r\n return dependencies;\r\n case 'UnaryExpression':\r\n case 'UpdateExpression':\r\n return this.getDependencies(ast.argument, dependencies, isNotSafe);\r\n case 'VariableDeclaration':\r\n return this.getDependencies(ast.declarations, dependencies, isNotSafe);\r\n case 'ArrayExpression':\r\n dependencies.push({\r\n origin: 'declaration',\r\n isSafe: true,\r\n });\r\n return dependencies;\r\n case 'CallExpression':\r\n dependencies.push({\r\n origin: 'function',\r\n isSafe: true,\r\n });\r\n return dependencies;\r\n case 'MemberExpression':\r\n const details = this.getMemberExpressionDetails(ast);\r\n switch (details.signature) {\r\n case 'value[]':\r\n this.getDependencies(ast.object, dependencies, isNotSafe);\r\n break;\r\n case 'value[][]':\r\n this.getDependencies(ast.object.object, dependencies, isNotSafe);\r\n break;\r\n case 'value[][][]':\r\n this.getDependencies(ast.object.object.object, dependencies, isNotSafe);\r\n break;\r\n case 'this.output.value':\r\n if (this.dynamicOutput) {\r\n dependencies.push({\r\n name: details.name,\r\n origin: 'output',\r\n isSafe: false,\r\n });\r\n }\r\n break;\r\n }\r\n if (details) {\r\n if (details.property) {\r\n this.getDependencies(details.property, dependencies, isNotSafe);\r\n }\r\n if (details.xProperty) {\r\n this.getDependencies(details.xProperty, dependencies, isNotSafe);\r\n }\r\n if (details.yProperty) {\r\n this.getDependencies(details.yProperty, dependencies, isNotSafe);\r\n }\r\n if (details.zProperty) {\r\n this.getDependencies(details.zProperty, dependencies, isNotSafe);\r\n }\r\n return dependencies;\r\n }\r\n default:\r\n throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast);\r\n }\r\n return dependencies;\r\n }\r\n\r\n getVariableSignature(ast) {\r\n if (!this.isAstVariable(ast)) {\r\n throw new Error(`ast of type \"${ ast.type }\" is not a variable signature`);\r\n }\r\n if (ast.type === 'Identifier') {\r\n return 'value';\r\n }\r\n const signature = [];\r\n while (true) {\r\n if (!ast) break;\r\n if (ast.computed) {\r\n signature.push('[]');\r\n } else if (ast.type === 'ThisExpression') {\r\n signature.unshift('this');\r\n } else if (ast.property && ast.property.name) {\r\n if (\r\n ast.property.name === 'x' ||\r\n ast.property.name === 'y' ||\r\n ast.property.name === 'z'\r\n ) {\r\n signature.unshift('.value');\r\n } else if (\r\n ast.property.name === 'constants' ||\r\n ast.property.name === 'thread' ||\r\n ast.property.name === 'output'\r\n ) {\r\n signature.unshift('.' + ast.property.name);\r\n } else {\r\n signature.unshift('.value');\r\n }\r\n } else if (ast.name) {\r\n signature.unshift('value');\r\n } else if (ast.callee && ast.callee.name) {\r\n signature.unshift('fn()');\r\n } else if (ast.elements) {\r\n signature.unshift('[]');\r\n } else {\r\n signature.unshift('unknown');\r\n }\r\n ast = ast.object;\r\n }\r\n\r\n const signatureString = signature.join('');\r\n const allowedExpressions = [\r\n 'value',\r\n 'value[]',\r\n 'value[][]',\r\n 'value[][][]',\r\n 'value[][][][]',\r\n 'value.value',\r\n 'value.thread.value',\r\n 'this.thread.value',\r\n 'this.output.value',\r\n 'this.constants.value',\r\n 'this.constants.value[]',\r\n 'this.constants.value[][]',\r\n 'this.constants.value[][][]',\r\n 'this.constants.value[][][][]',\r\n 'fn()[]',\r\n 'fn()[][]',\r\n 'fn()[][][]',\r\n '[][]',\r\n ];\r\n if (allowedExpressions.indexOf(signatureString) > -1) {\r\n return signatureString;\r\n }\r\n return null;\r\n }\r\n\r\n build() {\r\n return this.toString().length > 0;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for generically to its respective function\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed string array\r\n */\r\n astGeneric(ast, retArr) {\r\n if (ast === null) {\r\n throw this.astErrorOutput('NULL ast', ast);\r\n } else {\r\n if (Array.isArray(ast)) {\r\n for (let i = 0; i < ast.length; i++) {\r\n this.astGeneric(ast[i], retArr);\r\n }\r\n return retArr;\r\n }\r\n\r\n switch (ast.type) {\r\n case 'FunctionDeclaration':\r\n return this.astFunctionDeclaration(ast, retArr);\r\n case 'FunctionExpression':\r\n return this.astFunctionExpression(ast, retArr);\r\n case 'ReturnStatement':\r\n return this.astReturnStatement(ast, retArr);\r\n case 'Literal':\r\n return this.astLiteral(ast, retArr);\r\n case 'BinaryExpression':\r\n return this.astBinaryExpression(ast, retArr);\r\n case 'Identifier':\r\n return this.astIdentifierExpression(ast, retArr);\r\n case 'AssignmentExpression':\r\n return this.astAssignmentExpression(ast, retArr);\r\n case 'ExpressionStatement':\r\n return this.astExpressionStatement(ast, retArr);\r\n case 'EmptyStatement':\r\n return this.astEmptyStatement(ast, retArr);\r\n case 'BlockStatement':\r\n return this.astBlockStatement(ast, retArr);\r\n case 'IfStatement':\r\n return this.astIfStatement(ast, retArr);\r\n case 'SwitchStatement':\r\n return this.astSwitchStatement(ast, retArr);\r\n case 'BreakStatement':\r\n return this.astBreakStatement(ast, retArr);\r\n case 'ContinueStatement':\r\n return this.astContinueStatement(ast, retArr);\r\n case 'ForStatement':\r\n return this.astForStatement(ast, retArr);\r\n case 'WhileStatement':\r\n return this.astWhileStatement(ast, retArr);\r\n case 'DoWhileStatement':\r\n return this.astDoWhileStatement(ast, retArr);\r\n case 'VariableDeclaration':\r\n return this.astVariableDeclaration(ast, retArr);\r\n case 'VariableDeclarator':\r\n return this.astVariableDeclarator(ast, retArr);\r\n case 'ThisExpression':\r\n return this.astThisExpression(ast, retArr);\r\n case 'SequenceExpression':\r\n return this.astSequenceExpression(ast, retArr);\r\n case 'UnaryExpression':\r\n return this.astUnaryExpression(ast, retArr);\r\n case 'UpdateExpression':\r\n return this.astUpdateExpression(ast, retArr);\r\n case 'LogicalExpression':\r\n return this.astLogicalExpression(ast, retArr);\r\n case 'MemberExpression':\r\n return this.astMemberExpression(ast, retArr);\r\n case 'CallExpression':\r\n return this.astCallExpression(ast, retArr);\r\n case 'ArrayExpression':\r\n return this.astArrayExpression(ast, retArr);\r\n case 'DebuggerStatement':\r\n return this.astDebuggerStatement(ast, retArr);\r\n case 'ConditionalExpression':\r\n return this.astConditionalExpression(ast, retArr);\r\n }\r\n\r\n throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast);\r\n }\r\n }\r\n /**\r\n * @desc To throw the AST error, with its location.\r\n * @param {string} error - the error message output\r\n * @param {Object} ast - the AST object where the error is\r\n */\r\n astErrorOutput(error, ast) {\r\n if (typeof this.source !== 'string') {\r\n return new Error(error);\r\n }\r\n\r\n const debugString = getAstString(this.source, ast);\r\n const leadingSource = this.source.substr(ast.start);\r\n const splitLines = leadingSource.split(/\\n/);\r\n const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0;\r\n return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\\n ${ debugString }`);\r\n }\r\n\r\n astDebuggerStatement(arrNode, retArr) {\r\n return retArr;\r\n }\r\n\r\n astConditionalExpression(ast, retArr) {\r\n if (ast.type !== 'ConditionalExpression') {\r\n throw this.astErrorOutput('Not a conditional expression', ast);\r\n }\r\n retArr.push('(');\r\n this.astGeneric(ast.test, retArr);\r\n retArr.push('?');\r\n this.astGeneric(ast.consequent, retArr);\r\n retArr.push(':');\r\n this.astGeneric(ast.alternate, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @param {Object} ast\r\n * @param {String[]} retArr\r\n * @returns {String[]}\r\n */\r\n astFunction(ast, retArr) {\r\n throw new Error(`\"astFunction\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function declaration*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunctionDeclaration(ast, retArr) {\r\n if (this.isChildFunction(ast)) {\r\n return retArr;\r\n }\r\n return this.astFunction(ast, retArr);\r\n }\r\n astFunctionExpression(ast, retArr) {\r\n if (this.isChildFunction(ast)) {\r\n return retArr;\r\n }\r\n return this.astFunction(ast, retArr);\r\n }\r\n isChildFunction(ast) {\r\n for (let i = 0; i < this.functions.length; i++) {\r\n if (this.functions[i] === ast) {\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n astReturnStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astLiteral(ast, retArr) {\r\n this.literalTypes[`${ast.start},${ast.end}`] = 'Number';\r\n return retArr;\r\n }\r\n astBinaryExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astIdentifierExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astAssignmentExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *generic expression* statement\r\n * @param {Object} esNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astExpressionStatement(esNode, retArr) {\r\n this.astGeneric(esNode.expression, retArr);\r\n retArr.push(';');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for an *Empty* Statement\r\n * @param {Object} eNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astEmptyStatement(eNode, retArr) {\r\n return retArr;\r\n }\r\n astBlockStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astIfStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astSwitchStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Break* Statement\r\n * @param {Object} brNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBreakStatement(brNode, retArr) {\r\n retArr.push('break;');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Continue* Statement\r\n * @param {Object} crNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astContinueStatement(crNode, retArr) {\r\n retArr.push('continue;\\n');\r\n return retArr;\r\n }\r\n astForStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astWhileStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n astDoWhileStatement(ast, retArr) {\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declaration*\r\n * @param {Object} varDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclaration(varDecNode, retArr) {\r\n const declarations = varDecNode.declarations;\r\n if (!declarations || !declarations[0] || !declarations[0].init) {\r\n throw this.astErrorOutput('Unexpected expression', varDecNode);\r\n }\r\n const result = [];\r\n const firstDeclaration = declarations[0];\r\n const init = firstDeclaration.init;\r\n let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init);\r\n if (type === 'LiteralInteger') {\r\n // We had the choice to go either float or int, choosing float\r\n type = 'Number';\r\n }\r\n const markupType = typeMap[type];\r\n if (!markupType) {\r\n throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode);\r\n }\r\n let dependencies = this.getDependencies(firstDeclaration.init);\r\n throw new Error('remove me');\r\n this.declarations[firstDeclaration.id.name] = Object.freeze({\r\n type,\r\n dependencies,\r\n isSafe: dependencies.every(dependency => dependency.isSafe)\r\n });\r\n const initResult = [`${type} user_${firstDeclaration.id.name}=`];\r\n this.astGeneric(init, initResult);\r\n result.push(initResult.join(''));\r\n\r\n // first declaration is done, now any added ones setup\r\n for (let i = 1; i < declarations.length; i++) {\r\n const declaration = declarations[i];\r\n dependencies = this.getDependencies(declaration);\r\n throw new Error('Remove me');\r\n this.declarations[declaration.id.name] = Object.freeze({\r\n type,\r\n dependencies,\r\n isSafe: false\r\n });\r\n this.astGeneric(declaration, result);\r\n }\r\n\r\n retArr.push(retArr, result.join(','));\r\n retArr.push(';');\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declarator*\r\n * @param {Object} iVarDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclarator(iVarDecNode, retArr) {\r\n this.astGeneric(iVarDecNode.id, retArr);\r\n if (iVarDecNode.init !== null) {\r\n retArr.push('=');\r\n this.astGeneric(iVarDecNode.init, retArr);\r\n }\r\n return retArr;\r\n }\r\n astThisExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astSequenceExpression(sNode, retArr) {\r\n for (let i = 0; i < sNode.expressions.length; i++) {\r\n if (i > 0) {\r\n retArr.push(',');\r\n }\r\n this.astGeneric(sNode.expressions, retArr);\r\n }\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Unary* Expression\r\n * @param {Object} uNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astUnaryExpression(uNode, retArr) {\r\n const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr);\r\n if (unaryResult) {\r\n return retArr;\r\n }\r\n\r\n if (uNode.prefix) {\r\n retArr.push(uNode.operator);\r\n this.astGeneric(uNode.argument, retArr);\r\n } else {\r\n this.astGeneric(uNode.argument, retArr);\r\n retArr.push(uNode.operator);\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseUnary(uNode, retArr) {}\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Update* Expression\r\n * @param {Object} uNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astUpdateExpression(uNode, retArr) {\r\n if (uNode.prefix) {\r\n retArr.push(uNode.operator);\r\n this.astGeneric(uNode.argument, retArr);\r\n } else {\r\n this.astGeneric(uNode.argument, retArr);\r\n retArr.push(uNode.operator);\r\n }\r\n\r\n return retArr;\r\n }\r\n /**\r\n * @desc Parses the abstract syntax tree for *Logical* Expression\r\n * @param {Object} logNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astLogicalExpression(logNode, retArr) {\r\n retArr.push('(');\r\n this.astGeneric(logNode.left, retArr);\r\n retArr.push(logNode.operator);\r\n this.astGeneric(logNode.right, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n astMemberExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astCallExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n astArrayExpression(ast, retArr) {\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param ast\r\n * @return {IFunctionNodeMemberExpressionDetails}\r\n */\r\n getMemberExpressionDetails(ast) {\r\n if (ast.type !== 'MemberExpression') {\r\n throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast);\r\n }\r\n let name = null;\r\n let type = null;\r\n const variableSignature = this.getVariableSignature(ast);\r\n switch (variableSignature) {\r\n case 'value':\r\n return null;\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n case 'this.output.value':\r\n return {\r\n signature: variableSignature,\r\n type: 'Integer',\r\n name: ast.property.name\r\n };\r\n case 'value[]':\r\n if (typeof ast.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object),\r\n xProperty: ast.property\r\n };\r\n case 'value[][]':\r\n if (typeof ast.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object),\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value[][][]':\r\n if (typeof ast.object.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object.object),\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value[][][][]':\r\n if (typeof ast.object.object.object.object.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.object.name;\r\n return {\r\n name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: this.getVariableType(ast.object.object.object.object),\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n case 'value.value':\r\n if (typeof ast.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n if (this.isAstMathVariable(ast)) {\r\n name = ast.property.name;\r\n return {\r\n name,\r\n origin: 'Math',\r\n type: 'Number',\r\n signature: variableSignature,\r\n };\r\n }\r\n switch (ast.property.name) {\r\n case 'r':\r\n case 'g':\r\n case 'b':\r\n case 'a':\r\n name = ast.object.name;\r\n return {\r\n name,\r\n property: ast.property.name,\r\n origin: 'user',\r\n signature: variableSignature,\r\n type: 'Number'\r\n };\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n case 'this.constants.value':\r\n if (typeof ast.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n };\r\n case 'this.constants.value[]':\r\n if (typeof ast.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n xProperty: ast.property,\r\n };\r\n case 'this.constants.value[][]': {\r\n if (typeof ast.object.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n }\r\n case 'this.constants.value[][][]': {\r\n if (typeof ast.object.object.object.property.name !== 'string') {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n name = ast.object.object.object.property.name;\r\n type = this.getConstantType(name);\r\n if (!type) {\r\n throw this.astErrorOutput('Constant has no type', ast);\r\n }\r\n return {\r\n name,\r\n type,\r\n origin: 'constants',\r\n signature: variableSignature,\r\n zProperty: ast.object.object.property,\r\n yProperty: ast.object.property,\r\n xProperty: ast.property,\r\n };\r\n }\r\n case 'fn()[]':\r\n case '[][]':\r\n return {\r\n signature: variableSignature,\r\n property: ast.property,\r\n };\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n }\r\n\r\n findIdentifierOrigin(astToFind) {\r\n const stack = [this.ast];\r\n\r\n while (stack.length > 0) {\r\n const atNode = stack[0];\r\n if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) {\r\n return atNode;\r\n }\r\n stack.shift();\r\n if (atNode.argument) {\r\n stack.push(atNode.argument);\r\n } else if (atNode.body) {\r\n stack.push(atNode.body);\r\n } else if (atNode.declarations) {\r\n stack.push(atNode.declarations);\r\n } else if (Array.isArray(atNode)) {\r\n for (let i = 0; i < atNode.length; i++) {\r\n stack.push(atNode[i]);\r\n }\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n findLastReturn(ast) {\r\n const stack = [ast || this.ast];\r\n\r\n while (stack.length > 0) {\r\n const atNode = stack.pop();\r\n if (atNode.type === 'ReturnStatement') {\r\n return atNode;\r\n }\r\n if (atNode.type === 'FunctionDeclaration') {\r\n continue;\r\n }\r\n if (atNode.argument) {\r\n stack.push(atNode.argument);\r\n } else if (atNode.body) {\r\n stack.push(atNode.body);\r\n } else if (atNode.declarations) {\r\n stack.push(atNode.declarations);\r\n } else if (Array.isArray(atNode)) {\r\n for (let i = 0; i < atNode.length; i++) {\r\n stack.push(atNode[i]);\r\n }\r\n } else if (atNode.consequent) {\r\n stack.push(atNode.consequent);\r\n } else if (atNode.cases) {\r\n stack.push(atNode.cases);\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n getInternalVariableName(name) {\r\n if (!this._internalVariableNames.hasOwnProperty(name)) {\r\n this._internalVariableNames[name] = 0;\r\n }\r\n this._internalVariableNames[name]++;\r\n if (this._internalVariableNames[name] === 1) {\r\n return name;\r\n }\r\n return name + this._internalVariableNames[name];\r\n }\r\n\r\n varWarn() {\r\n console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let');\r\n }\r\n}\r\n\r\nconst typeLookupMap = {\r\n 'Number': 'Number',\r\n 'Float': 'Float',\r\n 'Integer': 'Integer',\r\n 'Array': 'Number',\r\n 'Array(2)': 'Number',\r\n 'Array(3)': 'Number',\r\n 'Array(4)': 'Number',\r\n 'Array2D': 'Number',\r\n 'Array3D': 'Number',\r\n 'Input': 'Number',\r\n 'HTMLImage': 'Array(4)',\r\n 'HTMLVideo': 'Array(4)',\r\n 'HTMLImageArray': 'Array(4)',\r\n 'NumberTexture': 'Number',\r\n 'MemoryOptimizedNumberTexture': 'Number',\r\n 'Array1D(2)': 'Array(2)',\r\n 'Array1D(3)': 'Array(3)',\r\n 'Array1D(4)': 'Array(4)',\r\n 'Array2D(2)': 'Array(2)',\r\n 'Array2D(3)': 'Array(3)',\r\n 'Array2D(4)': 'Array(4)',\r\n 'Array3D(2)': 'Array(2)',\r\n 'Array3D(3)': 'Array(3)',\r\n 'Array3D(4)': 'Array(4)',\r\n 'ArrayTexture(1)': 'Number',\r\n 'ArrayTexture(2)': 'Array(2)',\r\n 'ArrayTexture(3)': 'Array(3)',\r\n 'ArrayTexture(4)': 'Array(4)',\r\n};\r\n","import { FunctionNode } from '../function-node';\r\n\r\n/**\r\n * @desc [INTERNAL] Represents a single function, inside JS\r\n *\r\n *

This handles all the raw state, converted state, etc. Of a single function.

\r\n */\r\nexport class CPUFunctionNode extends FunctionNode {\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunction(ast, retArr) {\r\n\r\n // Setup function return type and name\r\n if (!this.isRootKernel) {\r\n retArr.push('function');\r\n retArr.push(' ');\r\n retArr.push(this.name);\r\n retArr.push('(');\r\n\r\n // Arguments handling\r\n for (let i = 0; i < this.argumentNames.length; ++i) {\r\n const argumentName = this.argumentNames[i];\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n retArr.push('user_');\r\n retArr.push(argumentName);\r\n }\r\n\r\n // Function opening\r\n retArr.push(') {\\n');\r\n }\r\n\r\n // Body statement iteration\r\n for (let i = 0; i < ast.body.body.length; ++i) {\r\n this.astGeneric(ast.body.body[i], retArr);\r\n retArr.push('\\n');\r\n }\r\n\r\n if (!this.isRootKernel) {\r\n // Function closing\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to *return* statement\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astReturnStatement(ast, retArr) {\r\n const type = this.returnType || this.getType(ast.argument);\r\n\r\n if (!this.returnType) {\r\n this.returnType = type;\r\n }\r\n\r\n if (this.isRootKernel) {\r\n retArr.push(this.leadingReturnStatement);\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';\\n');\r\n retArr.push(this.followingReturnStatement);\r\n retArr.push('continue;\\n');\r\n } else if (this.isSubKernel) {\r\n retArr.push(`subKernelResult_${ this.name } = `);\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';');\r\n retArr.push(`return subKernelResult_${ this.name };`);\r\n } else {\r\n retArr.push('return ');\r\n this.astGeneric(ast.argument, retArr);\r\n retArr.push(';');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *literal value*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astLiteral(ast, retArr) {\r\n\r\n // Reject non numeric literals\r\n if (isNaN(ast.value)) {\r\n throw this.astErrorOutput(\r\n 'Non-numeric literal not supported : ' + ast.value,\r\n ast\r\n );\r\n }\r\n\r\n retArr.push(ast.value);\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *binary* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBinaryExpression(ast, retArr) {\r\n retArr.push('(');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput(\r\n 'IdentifierExpression - not an Identifier',\r\n idtNode\r\n );\r\n }\r\n\r\n switch (idtNode.name) {\r\n case 'Infinity':\r\n retArr.push('Infinity');\r\n break;\r\n default:\r\n if (this.constants && this.constants.hasOwnProperty(idtNode.name)) {\r\n retArr.push('constants_' + idtNode.name);\r\n } else {\r\n retArr.push('user_' + idtNode.name);\r\n }\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *for-loop* expression\r\n * @param {Object} forNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astForStatement(forNode, retArr) {\r\n if (forNode.type !== 'ForStatement') {\r\n throw this.astErrorOutput('Invalid for statement', forNode);\r\n }\r\n\r\n const initArr = [];\r\n const testArr = [];\r\n const updateArr = [];\r\n const bodyArr = [];\r\n let isSafe = null;\r\n\r\n if (forNode.init) {\r\n this.pushState('in-for-loop-init');\r\n this.astGeneric(forNode.init, initArr);\r\n for (let i = 0; i < initArr.length; i++) {\r\n if (initArr[i].includes && initArr[i].includes(',')) {\r\n isSafe = false;\r\n }\r\n }\r\n this.popState('in-for-loop-init');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.test) {\r\n this.astGeneric(forNode.test, testArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.update) {\r\n this.astGeneric(forNode.update, updateArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.body) {\r\n this.pushState('loop-body');\r\n this.astGeneric(forNode.body, bodyArr);\r\n this.popState('loop-body');\r\n }\r\n\r\n // have all parts, now make them safe\r\n if (isSafe === null) {\r\n isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);\r\n }\r\n\r\n if (isSafe) {\r\n retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\\n`);\r\n retArr.push(bodyArr.join(''));\r\n retArr.push('}\\n');\r\n } else {\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n if (initArr.length > 0) {\r\n retArr.push(initArr.join(''), ';\\n');\r\n }\r\n retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) {\r\n retArr.push(`if (!${testArr.join('')}) break;\\n`);\r\n }\r\n retArr.push(bodyArr.join(''));\r\n retArr.push(`\\n${updateArr.join('')};`);\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *while* loop\r\n * @param {Object} whileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed javascript string\r\n */\r\n astWhileStatement(whileNode, retArr) {\r\n if (whileNode.type !== 'WhileStatement') {\r\n throw this.astErrorOutput(\r\n 'Invalid while statement',\r\n whileNode\r\n );\r\n }\r\n\r\n retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');\r\n retArr.push('if (');\r\n this.astGeneric(whileNode.test, retArr);\r\n retArr.push(') {\\n');\r\n this.astGeneric(whileNode.body, retArr);\r\n retArr.push('} else {\\n');\r\n retArr.push('break;\\n');\r\n retArr.push('}\\n');\r\n retArr.push('}\\n');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *do while* loop\r\n * @param {Object} doWhileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astDoWhileStatement(doWhileNode, retArr) {\r\n if (doWhileNode.type !== 'DoWhileStatement') {\r\n throw this.astErrorOutput(\r\n 'Invalid while statement',\r\n doWhileNode\r\n );\r\n }\r\n\r\n retArr.push('for (let i = 0; i < LOOP_MAX; i++) {');\r\n this.astGeneric(doWhileNode.body, retArr);\r\n retArr.push('if (!');\r\n this.astGeneric(doWhileNode.test, retArr);\r\n retArr.push(') {\\n');\r\n retArr.push('break;\\n');\r\n retArr.push('}\\n');\r\n retArr.push('}\\n');\r\n\r\n return retArr;\r\n\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Assignment* Expression\r\n * @param {Object} assNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astAssignmentExpression(assNode, retArr) {\r\n const declaration = this.getDeclaration(assNode.left);\r\n if (declaration && !declaration.assignable) {\r\n throw new this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode);\r\n }\r\n this.astGeneric(assNode.left, retArr);\r\n retArr.push(assNode.operator);\r\n this.astGeneric(assNode.right, retArr);\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Block* statement\r\n * @param {Object} bNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBlockStatement(bNode, retArr) {\r\n if (this.isState('loop-body')) {\r\n this.pushState('block-body'); // this prevents recursive removal of braces\r\n for (let i = 0; i < bNode.body.length; i++) {\r\n this.astGeneric(bNode.body[i], retArr);\r\n }\r\n this.popState('block-body');\r\n } else {\r\n retArr.push('{\\n');\r\n for (let i = 0; i < bNode.body.length; i++) {\r\n this.astGeneric(bNode.body[i], retArr);\r\n }\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Variable Declaration*\r\n * @param {Object} varDecNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astVariableDeclaration(varDecNode, retArr) {\r\n if (varDecNode.kind === 'var' && this.warnVarUsage) {\r\n this.varWarn();\r\n }\r\n retArr.push(`${varDecNode.kind} `);\r\n const { declarations } = varDecNode;\r\n for (let i = 0; i < declarations.length; i++) {\r\n if (i > 0) {\r\n retArr.push(',');\r\n }\r\n this.astGeneric(declarations[i], retArr);\r\n }\r\n if (!this.isState('in-for-loop-init')) {\r\n retArr.push(';');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *If* Statement\r\n * @param {Object} ifNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIfStatement(ifNode, retArr) {\r\n retArr.push('if (');\r\n this.astGeneric(ifNode.test, retArr);\r\n retArr.push(')');\r\n if (ifNode.consequent.type === 'BlockStatement') {\r\n this.astGeneric(ifNode.consequent, retArr);\r\n } else {\r\n retArr.push(' {\\n');\r\n this.astGeneric(ifNode.consequent, retArr);\r\n retArr.push('\\n}\\n');\r\n }\r\n\r\n if (ifNode.alternate) {\r\n retArr.push('else ');\r\n if (ifNode.alternate.type === 'BlockStatement') {\r\n this.astGeneric(ifNode.alternate, retArr);\r\n } else {\r\n retArr.push(' {\\n');\r\n this.astGeneric(ifNode.alternate, retArr);\r\n retArr.push('\\n}\\n');\r\n }\r\n }\r\n return retArr;\r\n\r\n }\r\n\r\n astSwitchStatement(ast, retArr) {\r\n const { discriminant, cases } = ast;\r\n retArr.push('switch (');\r\n this.astGeneric(discriminant, retArr);\r\n retArr.push(') {\\n');\r\n for (let i = 0; i < cases.length; i++) {\r\n if (cases[i].test === null) {\r\n retArr.push('default:\\n');\r\n this.astGeneric(cases[i].consequent, retArr);\r\n if (cases[i].consequent && cases[i].consequent.length > 0) {\r\n retArr.push('break;\\n');\r\n }\r\n continue;\r\n }\r\n retArr.push('case ');\r\n this.astGeneric(cases[i].test, retArr);\r\n retArr.push(':\\n');\r\n if (cases[i].consequent && cases[i].consequent.length > 0) {\r\n this.astGeneric(cases[i].consequent, retArr);\r\n retArr.push('break;\\n');\r\n }\r\n }\r\n retArr.push('\\n}');\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *This* expression\r\n * @param {Object} tNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astThisExpression(tNode, retArr) {\r\n retArr.push('_this');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Member* Expression\r\n * @param {Object} mNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astMemberExpression(mNode, retArr) {\r\n const {\r\n signature,\r\n type,\r\n property,\r\n xProperty,\r\n yProperty,\r\n zProperty,\r\n name,\r\n origin\r\n } = this.getMemberExpressionDetails(mNode);\r\n switch (signature) {\r\n case 'this.thread.value':\r\n retArr.push(`_this.thread.${ name }`);\r\n return retArr;\r\n case 'this.output.value':\r\n switch (name) {\r\n case 'x':\r\n retArr.push('outputX');\r\n break;\r\n case 'y':\r\n retArr.push('outputY');\r\n break;\r\n case 'z':\r\n retArr.push('outputZ');\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n return retArr;\r\n case 'value':\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n case 'value[]':\r\n case 'value[][]':\r\n case 'value[][][]':\r\n case 'value.value':\r\n if (origin === 'Math') {\r\n retArr.push(Math[name]);\r\n return retArr;\r\n }\r\n switch (property) {\r\n case 'r':\r\n retArr.push(`user_${ name }[0]`);\r\n return retArr;\r\n case 'g':\r\n retArr.push(`user_${ name }[1]`);\r\n return retArr;\r\n case 'b':\r\n retArr.push(`user_${ name }[2]`);\r\n return retArr;\r\n case 'a':\r\n retArr.push(`user_${ name }[3]`);\r\n return retArr;\r\n }\r\n break;\r\n case 'this.constants.value':\r\n case 'this.constants.value[]':\r\n case 'this.constants.value[][]':\r\n case 'this.constants.value[][][]':\r\n break;\r\n case 'fn()[]':\r\n this.astGeneric(mNode.object, retArr);\r\n retArr.push('[');\r\n this.astGeneric(mNode.property, retArr);\r\n retArr.push(']');\r\n return retArr;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n\r\n if (!mNode.computed) {\r\n // handle simple types\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n retArr.push(`${origin}_${name}`);\r\n return retArr;\r\n }\r\n }\r\n\r\n // handle more complex types\r\n // argument may have come from a parent\r\n const markupName = `${origin}_${name}`;\r\n\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n case 'HTMLImageArray':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'HTMLImage':\r\n default:\r\n let size;\r\n let isInput;\r\n if (origin === 'constants') {\r\n const constant = this.constants[name];\r\n isInput = this.constantTypes[name] === 'Input';\r\n size = isInput ? constant.size : null;\r\n } else {\r\n isInput = this.isInput(name);\r\n size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null;\r\n }\r\n retArr.push(`${ markupName }`);\r\n if (zProperty && yProperty) {\r\n if (isInput) {\r\n retArr.push('[(');\r\n this.astGeneric(zProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`);\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n } else {\r\n retArr.push('[');\r\n this.astGeneric(zProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n } else if (yProperty) {\r\n if (isInput) {\r\n retArr.push('[(');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`);\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n } else {\r\n retArr.push('[');\r\n this.astGeneric(yProperty, retArr);\r\n retArr.push(']');\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n } else if (typeof xProperty !== 'undefined') {\r\n retArr.push('[');\r\n this.astGeneric(xProperty, retArr);\r\n retArr.push(']');\r\n }\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *call* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astCallExpression(ast, retArr) {\r\n if (ast.type !== 'CallExpression') {\r\n // Failure, unknown expression\r\n throw this.astErrorOutput('Unknown CallExpression', ast);\r\n }\r\n // Get the full function call, unrolled\r\n let functionName = this.astMemberExpressionUnroll(ast.callee);\r\n\r\n // Register the function into the called registry\r\n if (this.calledFunctions.indexOf(functionName) < 0) {\r\n this.calledFunctions.push(functionName);\r\n }\r\n\r\n const isMathFunction = this.isAstMathFunction(ast);\r\n\r\n // track the function was called\r\n if (this.onFunctionCall) {\r\n this.onFunctionCall(this.name, functionName, ast.arguments);\r\n }\r\n\r\n // Call the function\r\n retArr.push(functionName);\r\n\r\n // Open arguments space\r\n retArr.push('(');\r\n const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];\r\n // Add the arguments\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n\r\n // in order to track return type, even though this is CPU\r\n let argumentType = this.getType(argument);\r\n if (!targetTypes[i]) {\r\n this.triggerImplyArgumentType(functionName, i, argumentType, this);\r\n }\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n this.astGeneric(argument, retArr);\r\n }\r\n // Close arguments space\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Array* Expression\r\n * @param {Object} arrNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astArrayExpression(arrNode, retArr) {\r\n const arrLen = arrNode.elements.length;\r\n\r\n retArr.push('new Float32Array([');\r\n for (let i = 0; i < arrLen; ++i) {\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const subNode = arrNode.elements[i];\r\n this.astGeneric(subNode, retArr)\r\n }\r\n retArr.push('])');\r\n\r\n return retArr;\r\n }\r\n\r\n astDebuggerStatement(arrNode, retArr) {\r\n retArr.push('debugger;');\r\n return retArr;\r\n }\r\n}\r\n","import { utils } from '../../utils'\r\n\r\nfunction constantsToString(constants, types) {\r\n const results = [];\r\n for (const name in types) {\r\n if (!types.hasOwnProperty(name)) continue;\r\n const type = types[name];\r\n const constant = constants[name];\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n results.push(`${name}:${constant}`);\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`);\r\n break;\r\n }\r\n }\r\n return `{ ${ results.join() } }`;\r\n}\r\n\r\nexport function cpuKernelString(cpuKernel, name) {\r\n const header = [];\r\n const thisProperties = [];\r\n const beforeReturn = [];\r\n\r\n const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString());\r\n\r\n header.push(\r\n ' const { context, canvas, constants: incomingConstants } = settings;',\r\n ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`,\r\n ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`,\r\n ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`,\r\n );\r\n\r\n thisProperties.push(\r\n ' constants: _constants,',\r\n ' context,',\r\n ' output,',\r\n ' thread: {x: 0, y: 0, z: 0},',\r\n );\r\n\r\n if (cpuKernel.graphical) {\r\n header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`);\r\n header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`);\r\n\r\n const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), {\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case '_colorData':\r\n return '_colorData';\r\n case '_imageData':\r\n return '_imageData';\r\n case 'output':\r\n return 'output';\r\n case 'thread':\r\n return 'this.thread';\r\n }\r\n return JSON.stringify(cpuKernel[propertyName]);\r\n },\r\n findDependency: (object, name) => {\r\n return null;\r\n }\r\n });\r\n\r\n const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), {\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case '_colorData':\r\n return '_colorData';\r\n case '_imageData':\r\n return '_imageData';\r\n case 'output':\r\n return 'output';\r\n case 'thread':\r\n return 'this.thread';\r\n }\r\n return JSON.stringify(cpuKernel[propertyName]);\r\n },\r\n findDependency: () => {\r\n return null;\r\n }\r\n });\r\n\r\n thisProperties.push(\r\n ' _imageData,',\r\n ' _colorData,',\r\n ` color: ${colorFn},`,\r\n );\r\n\r\n beforeReturn.push(\r\n ` kernel.getPixels = ${getPixelsFn};`\r\n );\r\n }\r\n\r\n const constantTypes = [];\r\n const constantKeys = Object.keys(cpuKernel.constantTypes);\r\n for (let i = 0; i < constantKeys.length; i++) {\r\n constantTypes.push(cpuKernel.constantTypes[constantKeys]);\r\n }\r\n if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) {\r\n const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), {\r\n doNotDefine: ['canvas'],\r\n findDependency: (object, name) => {\r\n if (object === 'this') {\r\n return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString();\r\n }\r\n return null;\r\n },\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case 'canvas':\r\n return;\r\n case 'context':\r\n return 'context';\r\n }\r\n }\r\n });\r\n beforeReturn.push(flattenedImageTo3DArray);\r\n thisProperties.push(` _mediaTo2DArray,`);\r\n thisProperties.push(` _imageTo3DArray,`);\r\n } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) {\r\n const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), {\r\n findDependency: (object, name) => {\r\n return null;\r\n },\r\n thisLookup: (propertyName) => {\r\n switch (propertyName) {\r\n case 'canvas':\r\n return 'settings.canvas';\r\n case 'context':\r\n return 'settings.context';\r\n }\r\n throw new Error('unhandled thisLookup');\r\n }\r\n });\r\n beforeReturn.push(flattenedImageTo2DArray);\r\n thisProperties.push(` _mediaTo2DArray,`);\r\n }\r\n\r\n return `function(settings) {\r\n${ header.join('\\n') }\r\n for (const p in _constantTypes) {\r\n if (!_constantTypes.hasOwnProperty(p)) continue;\r\n const type = _constantTypes[p];\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n if (incomingConstants.hasOwnProperty(p)) {\r\n console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned');\r\n }\r\n continue;\r\n }\r\n if (!incomingConstants.hasOwnProperty(p)) {\r\n throw new Error('constant ' + p + ' not found');\r\n }\r\n _constants[p] = incomingConstants[p];\r\n }\r\n const kernel = (function() {\r\n${cpuKernel._kernelString}\r\n })\r\n .apply({ ${thisProperties.join('\\n')} });\r\n ${ beforeReturn.join('\\n') }\r\n return kernel;\r\n}`;\r\n}\r\n","import { Kernel } from '../kernel';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { CPUFunctionNode } from './function-node';\r\nimport { utils } from '../../utils';\r\nimport { cpuKernelString } from './kernel-string';\r\n\r\n/**\r\n * @desc Kernel Implementation for CPU.\r\n *

Instantiates properties to the CPU Kernel.

\r\n */\r\nexport class CPUKernel extends Kernel {\r\n static getFeatures() {\r\n return this.features;\r\n }\r\n static get features() {\r\n return Object.freeze({\r\n kernelMap: true,\r\n isIntegerDivisionAccurate: true\r\n });\r\n }\r\n static get isSupported() {\r\n return true;\r\n }\r\n static isContextMatch(context) {\r\n return false;\r\n }\r\n /**\r\n * @desc The current mode in which gpu.js is executing.\r\n */\r\n static get mode() {\r\n return 'cpu';\r\n }\r\n\r\n static nativeFunctionArguments() {\r\n return null;\r\n }\r\n\r\n static nativeFunctionReturnType() {\r\n return null;\r\n }\r\n\r\n static combineKernels(combinedKernel) {\r\n return combinedKernel;\r\n }\r\n\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.mergeSettings(source.settings || settings);\r\n\r\n this._imageData = null;\r\n this._colorData = null;\r\n this._kernelString = null;\r\n this.thread = {\r\n x: 0,\r\n y: 0,\r\n z: 0\r\n };\r\n this.translatedSources = null;\r\n }\r\n\r\n initCanvas() {\r\n if (typeof document !== 'undefined') {\r\n return document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n return new OffscreenCanvas(0, 0);\r\n }\r\n }\r\n\r\n initContext() {\r\n if (!this.canvas) return null;\r\n return this.canvas.getContext('2d');\r\n }\r\n\r\n initPlugins(settings) {\r\n return [];\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n if (argType === 'Array') {\r\n this.output = utils.getDimensions(argType);\r\n } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {\r\n this.output = args[0].output;\r\n } else {\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n }\r\n\r\n this.checkOutput();\r\n }\r\n\r\n translateSource() {\r\n this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = ';\r\n if (this.subKernels) {\r\n const followingReturnStatement = []\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const {\r\n name\r\n } = this.subKernels[i];\r\n followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\\n` : `result_${ name }[x] = subKernelResult_${ name };\\n`);\r\n }\r\n this.followingReturnStatement = followingReturnStatement.join('');\r\n }\r\n const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode);\r\n this.translatedSources = functionBuilder.getPrototypes('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n }\r\n\r\n /**\r\n * @desc Builds the Kernel, by generating the kernel\r\n * string using thread dimensions, and arguments\r\n * supplied to the kernel.\r\n *\r\n *

If the graphical flag is enabled, canvas is used.

\r\n */\r\n build() {\r\n this.setupConstants();\r\n this.setupArguments(arguments);\r\n this.validateSettings(arguments);\r\n this.translateSource();\r\n\r\n if (this.graphical) {\r\n const {\r\n canvas,\r\n output\r\n } = this;\r\n if (!canvas) {\r\n throw new Error('no canvas available for using graphical output');\r\n }\r\n const width = output[0];\r\n const height = output[1] || 1;\r\n canvas.width = width;\r\n canvas.height = height;\r\n this._imageData = this.context.createImageData(width, height);\r\n this._colorData = new Uint8ClampedArray(width * height * 4);\r\n }\r\n\r\n const kernelString = this.getKernelString();\r\n this.kernelString = kernelString;\r\n\r\n if (this.debug) {\r\n console.log('Function output:');\r\n console.log(kernelString);\r\n }\r\n\r\n try {\r\n this.run = new Function([], kernelString).bind(this)();\r\n } catch (e) {\r\n console.error('An error occurred compiling the javascript: ', e);\r\n }\r\n }\r\n\r\n color(r, g, b, a) {\r\n if (typeof a === 'undefined') {\r\n a = 1;\r\n }\r\n\r\n r = Math.floor(r * 255);\r\n g = Math.floor(g * 255);\r\n b = Math.floor(b * 255);\r\n a = Math.floor(a * 255);\r\n\r\n const width = this.output[0];\r\n const height = this.output[1];\r\n\r\n const x = this.thread.x;\r\n const y = height - this.thread.y - 1;\r\n\r\n const index = x + y * width;\r\n\r\n this._colorData[index * 4 + 0] = r;\r\n this._colorData[index * 4 + 1] = g;\r\n this._colorData[index * 4 + 2] = b;\r\n this._colorData[index * 4 + 3] = a;\r\n }\r\n\r\n /**\r\n * @desc Generates kernel string for this kernel program.\r\n *\r\n *

If sub-kernels are supplied, they are also factored in.\r\n * This string can be saved by calling the `toString` method\r\n * and then can be reused later.

\r\n *\r\n * @returns {String} result\r\n *\r\n */\r\n getKernelString() {\r\n if (this._kernelString !== null) return this._kernelString;\r\n\r\n let kernelThreadString = null;\r\n let {\r\n translatedSources\r\n } = this;\r\n if (translatedSources.length > 1) {\r\n translatedSources = translatedSources.filter(fn => {\r\n if (/^function/.test(fn)) return fn;\r\n kernelThreadString = fn;\r\n return false;\r\n })\r\n } else {\r\n kernelThreadString = translatedSources.shift();\r\n }\r\n return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() };\r\n ${ this.injectedNative || '' }\r\n const _this = this;\r\n ${ this._processConstants() }\r\n return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => {\r\n ${ this._processArguments() }\r\n ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) }\r\n ${ translatedSources.length > 0 ? translatedSources.join('\\n') : '' }\r\n };`;\r\n }\r\n\r\n /**\r\n * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.\r\n */\r\n toString() {\r\n return cpuKernelString(this);\r\n }\r\n\r\n /**\r\n * @desc Get the maximum loop size String.\r\n * @returns {String} result\r\n */\r\n _getLoopMaxString() {\r\n return (\r\n this.loopMaxIterations ?\r\n ` ${ parseInt(this.loopMaxIterations) };` :\r\n ' 1000;'\r\n );\r\n }\r\n\r\n _processConstants() {\r\n if (!this.constants) return '';\r\n\r\n const result = [];\r\n for (let p in this.constants) {\r\n const type = this.constantTypes[p];\r\n switch (type) {\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\\n`);\r\n break;\r\n case 'HTMLImageArray':\r\n result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\\n`);\r\n break;\r\n case 'Input':\r\n result.push(` const constants_${p} = this.constants.${p}.value;\\n`);\r\n break;\r\n default:\r\n result.push(` const constants_${p} = this.constants.${p};\\n`);\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n _processArguments() {\r\n const result = [];\r\n for (let i = 0; i < this.argumentTypes.length; i++) {\r\n const variableName = `user_${this.argumentNames[i]}`;\r\n switch (this.argumentTypes[i]) {\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\\n`);\r\n break;\r\n case 'HTMLImageArray':\r\n result.push(` ${variableName} = this._imageTo3DArray(${variableName});\\n`);\r\n break;\r\n case 'Input':\r\n result.push(` ${variableName} = ${variableName}.value;\\n`);\r\n break;\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'NumberTexture':\r\n case 'MemoryOptimizedNumberTexture':\r\n result.push(`\r\n if (${variableName}.toArray) {\r\n if (!_this.textureCache) {\r\n _this.textureCache = [];\r\n _this.arrayCache = [];\r\n }\r\n const textureIndex = _this.textureCache.indexOf(${variableName});\r\n if (textureIndex !== -1) {\r\n ${variableName} = _this.arrayCache[textureIndex];\r\n } else {\r\n _this.textureCache.push(${variableName});\r\n ${variableName} = ${variableName}.toArray();\r\n _this.arrayCache.push(${variableName});\r\n }\r\n }`);\r\n break;\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n _mediaTo2DArray(media) {\r\n const canvas = this.canvas;\r\n const width = media.width > 0 ? media.width : media.videoWidth;\r\n const height = media.height > 0 ? media.height : media.videoHeight;\r\n if (canvas.width < width) {\r\n canvas.width = width;\r\n }\r\n if (canvas.height < height) {\r\n canvas.height = height;\r\n }\r\n const ctx = this.context;\r\n ctx.drawImage(media, 0, 0, width, height);\r\n const pixelsData = ctx.getImageData(0, 0, width, height).data;\r\n const imageArray = new Array(height);\r\n let index = 0;\r\n for (let y = height - 1; y >= 0; y--) {\r\n const row = imageArray[y] = new Array(width);\r\n for (let x = 0; x < width; x++) {\r\n const pixel = new Float32Array(4);\r\n pixel[0] = pixelsData[index++] / 255; // r\r\n pixel[1] = pixelsData[index++] / 255; // g\r\n pixel[2] = pixelsData[index++] / 255; // b\r\n pixel[3] = pixelsData[index++] / 255; // a\r\n row[x] = pixel;\r\n }\r\n }\r\n return imageArray;\r\n }\r\n\r\n getPixels(flip) {\r\n const [width, height] = this.output;\r\n // cpu is not flipped by default\r\n return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0);\r\n }\r\n\r\n _imageTo3DArray(images) {\r\n const imagesArray = new Array(images.length);\r\n for (let i = 0; i < images.length; i++) {\r\n imagesArray[i] = this._mediaTo2DArray(images[i]);\r\n }\r\n return imagesArray;\r\n }\r\n\r\n _resultKernelBody(kernelString) {\r\n switch (this.output.length) {\r\n case 1:\r\n return this._resultKernel1DLoop(kernelString) + this._kernelOutput();\r\n case 2:\r\n return this._resultKernel2DLoop(kernelString) + this._kernelOutput();\r\n case 3:\r\n return this._resultKernel3DLoop(kernelString) + this._kernelOutput();\r\n default:\r\n throw new Error('unsupported size kernel');\r\n }\r\n }\r\n\r\n _graphicalKernelBody(kernelThreadString) {\r\n switch (this.output.length) {\r\n case 2:\r\n return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput();\r\n default:\r\n throw new Error('unsupported size kernel');\r\n }\r\n }\r\n\r\n _graphicalOutput() {\r\n return `\r\n this._imageData.data.set(this._colorData);\r\n this.context.putImageData(this._imageData, 0, 0);\r\n return;`\r\n }\r\n\r\n _getKernelResultTypeConstructorString() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return 'Float32Array';\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return 'Array';\r\n default:\r\n if (this.graphical) {\r\n return 'Float32Array';\r\n }\r\n throw new Error(`unhandled returnType ${ this.returnType }`);\r\n }\r\n }\r\n\r\n _resultKernel1DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const result = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n this.thread.y = 0;\r\n this.thread.z = 0;\r\n ${ kernelString }\r\n }`;\r\n }\r\n\r\n _resultKernel2DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n const result = new Array(outputY);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.z = 0;\r\n this.thread.y = y;\r\n const resultX = result[y] = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join('') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }`;\r\n }\r\n\r\n _graphicalKernel2DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.z = 0;\r\n this.thread.y = y;\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join('') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }`;\r\n }\r\n\r\n _resultKernel3DLoop(kernelString) {\r\n const {\r\n output\r\n } = this;\r\n const constructorString = this._getKernelResultTypeConstructorString();\r\n return ` const outputX = _this.output[0];\r\n const outputY = _this.output[1];\r\n const outputZ = _this.output[2];\r\n const result = new Array(outputZ);\r\n ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\\n`).join(' ') }\r\n ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\\n`).join(' ') }\r\n for (let z = 0; z < outputZ; z++) {\r\n this.thread.z = z;\r\n const resultY = result[z] = new Array(outputY);\r\n ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\\n`).join(' ') }\r\n for (let y = 0; y < outputY; y++) {\r\n this.thread.y = y;\r\n const resultX = resultY[y] = new ${constructorString}(outputX);\r\n ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\\n`).join(' ') }\r\n for (let x = 0; x < outputX; x++) {\r\n this.thread.x = x;\r\n ${ kernelString }\r\n }\r\n }\r\n }`;\r\n }\r\n\r\n _kernelOutput() {\r\n if (!this.subKernels) {\r\n return '\\n return result;';\r\n }\r\n return `\\n return {\r\n result: result,\r\n ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\\n ') }\r\n };`;\r\n }\r\n\r\n _mapSubKernels(fn) {\r\n return this.subKernels === null ? [''] :\r\n this.subKernels.map(fn);\r\n }\r\n\r\n\r\n\r\n destroy(removeCanvasReference) {\r\n if (removeCanvasReference) {\r\n delete this.canvas;\r\n }\r\n }\r\n\r\n static destroyContext(context) {}\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON();\r\n return json;\r\n }\r\n\r\n setOutput(output) {\r\n super.setOutput(output);\r\n const [width, height] = this.output;\r\n if (this.graphical) {\r\n this._imageData = this.context.createImageData(width, height);\r\n this._colorData = new Uint8ClampedArray(width * height * 4);\r\n }\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { Texture } from '../../../texture';\r\n\r\nexport class GLTextureFloat extends Texture {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n renderRawOutput() {\r\n const { context: gl } = this;\r\n const framebuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\r\n gl.framebufferTexture2D(\r\n gl.FRAMEBUFFER,\r\n gl.COLOR_ATTACHMENT0,\r\n gl.TEXTURE_2D,\r\n this.texture,\r\n 0\r\n );\r\n const result = new Float32Array(this.size[0] * this.size[1] * 4);\r\n gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n renderValues() {\r\n return this.renderRawOutput();\r\n }\r\n toArray() {\r\n return utils.erectFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray2Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(2)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erectArray3(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray3Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(3)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erectArray4(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureArray4Float3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureFloat2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n toArray() {\r\n return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureFloat3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(1)';\r\n }\r\n toArray() {\r\n return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized2D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureFloat } from './float';\r\n\r\nexport class GLTextureMemoryOptimized3D extends GLTextureFloat {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'MemoryOptimizedNumberTexture';\r\n }\r\n toArray() {\r\n return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { Texture } from '../../../texture';\r\n\r\nexport class GLTextureUnsigned extends Texture {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n renderRawOutput() {\r\n const { context: gl } = this;\r\n const framebuffer = gl.createFramebuffer();\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\r\n gl.framebufferTexture2D(\r\n gl.FRAMEBUFFER,\r\n gl.COLOR_ATTACHMENT0,\r\n gl.TEXTURE_2D,\r\n this.texture,\r\n 0\r\n );\r\n const result = new Uint8Array(this.size[0] * this.size[1] * 4);\r\n gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result);\r\n return result;\r\n }\r\n renderValues() {\r\n return new Float32Array(this.renderRawOutput().buffer);\r\n }\r\n toArray() {\r\n return utils.erectPackedFloat(this.renderValues(), this.output[0]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureUnsigned2D extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n toArray() {\r\n return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureUnsigned3D extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'NumberTexture';\r\n }\r\n toArray() {\r\n return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]);\r\n }\r\n}\r\n","import { GLTextureUnsigned } from './unsigned';\r\n\r\nexport class GLTextureGraphical extends GLTextureUnsigned {\r\n constructor(settings) {\r\n super(settings);\r\n this.type = 'ArrayTexture(4)';\r\n }\r\n toArray() {\r\n return this.renderValues();\r\n }\r\n}\r\n","import { Kernel } from '../kernel';\r\nimport { utils } from '../../utils';\r\nimport { GLTextureArray2Float } from './texture/array-2-float';\r\nimport { GLTextureArray2Float2D } from './texture/array-2-float-2d';\r\nimport { GLTextureArray2Float3D } from './texture/array-2-float-3d';\r\nimport { GLTextureArray3Float } from './texture/array-3-float';\r\nimport { GLTextureArray3Float2D } from './texture/array-3-float-2d';\r\nimport { GLTextureArray3Float3D } from './texture/array-3-float-3d';\r\nimport { GLTextureArray4Float } from './texture/array-4-float';\r\nimport { GLTextureArray4Float2D } from './texture/array-4-float-2d';\r\nimport { GLTextureArray4Float3D } from './texture/array-4-float-3d';\r\nimport { GLTextureFloat } from './texture/float';\r\nimport { GLTextureFloat2D } from './texture/float-2d';\r\nimport { GLTextureFloat3D } from './texture/float-3d';\r\nimport { GLTextureMemoryOptimized } from './texture/memory-optimized';\r\nimport { GLTextureMemoryOptimized2D } from './texture/memory-optimized-2d';\r\nimport { GLTextureMemoryOptimized3D } from './texture/memory-optimized-3d';\r\nimport { GLTextureUnsigned } from './texture/unsigned';\r\nimport { GLTextureUnsigned2D } from './texture/unsigned-2d';\r\nimport { GLTextureUnsigned3D } from './texture/unsigned-3d';\r\nimport { GLTextureGraphical } from './texture/graphical';\r\n\r\n/**\r\n * @abstract\r\n * @extends Kernel\r\n */\r\nexport class GLKernel extends Kernel {\r\n static get mode() {\r\n return 'gpu';\r\n }\r\n\r\n static getIsFloatRead() {\r\n const kernelString = `function kernelFunction() {\r\n return 1;\r\n }`;\r\n const kernel = new this(kernelString, {\r\n context: this.testContext,\r\n canvas: this.testCanvas,\r\n validate: false,\r\n output: [1],\r\n precision: 'single',\r\n returnType: 'Number',\r\n tactic: 'speed',\r\n });\r\n kernel.build();\r\n kernel.run();\r\n const result = kernel.renderOutput();\r\n kernel.destroy(true);\r\n return result[0] === 1;\r\n }\r\n\r\n static getIsIntegerDivisionAccurate() {\r\n function kernelFunction(v1, v2) {\r\n return v1[this.thread.x] / v2[this.thread.x];\r\n }\r\n const kernel = new this(kernelFunction.toString(), {\r\n context: this.testContext,\r\n canvas: this.testCanvas,\r\n validate: false,\r\n output: [2],\r\n returnType: 'Number',\r\n precision: 'unsigned',\r\n tactic: 'speed',\r\n });\r\n const args = [\r\n [6, 6030401],\r\n [3, 3991]\r\n ];\r\n kernel.build.apply(kernel, args);\r\n kernel.run.apply(kernel, args);\r\n const result = kernel.renderOutput();\r\n kernel.destroy(true);\r\n // have we not got whole numbers for 6/3 or 6030401/3991\r\n // add more here if others see this problem\r\n return result[0] === 2 && result[1] === 1511;\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static get testCanvas() {\r\n throw new Error(`\"testCanvas\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static get testContext() {\r\n throw new Error(`\"testContext\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @type {IKernelFeatures}\r\n */\r\n static get features() {\r\n throw new Error(`\"features\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n */\r\n static setupFeatureChecks() {\r\n throw new Error(`\"setupFeatureChecks\" not defined on ${ this.name }`);\r\n }\r\n\r\n /**\r\n * @desc Fix division by factor of 3 FP accuracy bug\r\n * @param {Boolean} fix - should fix\r\n */\r\n setFixIntegerDivisionAccuracy(fix) {\r\n this.fixIntegerDivisionAccuracy = fix;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle output mode\r\n * @param {String} flag - 'single' or 'unsigned'\r\n */\r\n setPrecision(flag) {\r\n this.precision = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Toggle texture output mode\r\n * @param {Boolean} flag - true to enable floatTextures\r\n * @deprecated\r\n */\r\n setFloatTextures(flag) {\r\n utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory');\r\n this.floatTextures = flag;\r\n return this;\r\n }\r\n\r\n /**\r\n * A highly readable very forgiving micro-parser for a glsl function that gets argument types\r\n * @param {String} source\r\n * @returns {{argumentTypes: String[], argumentNames: String[]}}\r\n */\r\n static nativeFunctionArguments(source) {\r\n const argumentTypes = [];\r\n const argumentNames = [];\r\n const states = [];\r\n const isStartingVariableName = /^[a-zA-Z_]/;\r\n const isVariableChar = /[a-zA-Z_0-9]/;\r\n let i = 0;\r\n let argumentName = null;\r\n let argumentType = null;\r\n while (i < source.length) {\r\n const char = source[i];\r\n const nextChar = source[i + 1];\r\n const state = states.length > 0 ? states[states.length - 1] : null;\r\n\r\n // begin MULTI_LINE_COMMENT handling\r\n if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') {\r\n states.push('MULTI_LINE_COMMENT');\r\n i += 2;\r\n continue;\r\n } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') {\r\n states.pop();\r\n i += 2;\r\n continue;\r\n }\r\n // end MULTI_LINE_COMMENT handling\r\n\r\n // begin COMMENT handling\r\n else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') {\r\n states.push('COMMENT');\r\n i += 2;\r\n continue;\r\n } else if (state === 'COMMENT' && char === '\\n') {\r\n states.pop();\r\n i++;\r\n continue;\r\n }\r\n // end COMMENT handling\r\n\r\n // being FUNCTION_ARGUMENTS handling\r\n else if (state === null && char === '(') {\r\n states.push('FUNCTION_ARGUMENTS');\r\n i++;\r\n continue;\r\n } else if (state === 'FUNCTION_ARGUMENTS') {\r\n if (char === ')') {\r\n states.pop();\r\n break;\r\n }\r\n if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'float';\r\n argumentName = '';\r\n i += 6;\r\n continue;\r\n } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'int';\r\n argumentName = '';\r\n i += 4;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec2';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec3';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') {\r\n states.push('DECLARE_VARIABLE');\r\n argumentType = 'vec4';\r\n argumentName = '';\r\n i += 5;\r\n continue;\r\n }\r\n }\r\n // end FUNCTION_ARGUMENTS handling\r\n\r\n // begin DECLARE_VARIABLE handling\r\n else if (state === 'DECLARE_VARIABLE') {\r\n if (argumentName === '') {\r\n if (char === ' ') {\r\n i++;\r\n continue;\r\n }\r\n if (!isStartingVariableName.test(char)) {\r\n throw new Error('variable name is not expected string');\r\n }\r\n }\r\n argumentName += char;\r\n if (!isVariableChar.test(nextChar)) {\r\n states.pop();\r\n argumentNames.push(argumentName);\r\n argumentTypes.push(typeMap[argumentType]);\r\n }\r\n }\r\n // end DECLARE_VARIABLE handling\r\n\r\n // Progress to next character\r\n i++;\r\n }\r\n if (states.length > 0) {\r\n throw new Error('GLSL function was not parsable');\r\n }\r\n return {\r\n argumentNames,\r\n argumentTypes,\r\n };\r\n }\r\n\r\n static nativeFunctionReturnType(source) {\r\n return typeMap[source.match(/int|float|vec[2-4]/)[0]];\r\n }\r\n\r\n static combineKernels(combinedKernel, lastKernel) {\r\n combinedKernel.apply(null, arguments);\r\n const {\r\n texSize,\r\n context,\r\n threadDim\r\n } = lastKernel.texSize;\r\n let result;\r\n if (lastKernel.precision === 'single') {\r\n const w = texSize[0];\r\n const h = Math.ceil(texSize[1] / 4);\r\n result = new Float32Array(w * h * 4 * 4);\r\n context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result);\r\n } else {\r\n const bytes = new Uint8Array(texSize[0] * texSize[1] * 4);\r\n context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes);\r\n result = new Float32Array(bytes.buffer);\r\n }\r\n\r\n result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]);\r\n\r\n if (lastKernel.output.length === 1) {\r\n return result;\r\n } else if (lastKernel.output.length === 2) {\r\n return utils.splitArray(result, lastKernel.output[0]);\r\n } else if (lastKernel.output.length === 3) {\r\n const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]);\r\n return cube.map(function(x) {\r\n return utils.splitArray(x, lastKernel.output[0]);\r\n });\r\n }\r\n }\r\n\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.transferValues = null;\r\n this.formatValues = null;\r\n this.TextureConstructor = null;\r\n this.renderOutput = null;\r\n this.renderRawOutput = null;\r\n this.texSize = null;\r\n this.translatedSource = null;\r\n this.renderStrategy = null;\r\n this.compiledFragmentShader = null;\r\n this.compiledVertexShader = null;\r\n }\r\n\r\n checkTextureSize() {\r\n const { features } = this.constructor;\r\n if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) {\r\n throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`);\r\n }\r\n }\r\n\r\n translateSource() {\r\n throw new Error(`\"translateSource\" not defined on ${this.constructor.name}`);\r\n }\r\n\r\n /**\r\n * Picks a render strategy for the now finally parsed kernel\r\n * @param args\r\n * @return {null|KernelOutput}\r\n */\r\n pickRenderStrategy(args) {\r\n if (this.graphical) {\r\n this.renderRawOutput = this.readPackedPixelsToUint8Array;\r\n this.transferValues = (pixels) => pixels;\r\n this.TextureConstructor = GLTextureGraphical;\r\n return null;\r\n }\r\n if (this.precision === 'unsigned') {\r\n this.renderRawOutput = this.readPackedPixelsToUint8Array;\r\n this.transferValues = this.readPackedPixelsToFloat32Array;\r\n if (this.pipeline) {\r\n this.renderOutput = this.renderTexture;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToTextures;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned3D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned2D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureUnsigned;\r\n this.renderStrategy = renderStrategy.PackedPixelToFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return this.requestFallback(args);\r\n }\r\n } else {\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToArrays;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n this.renderOutput = this.renderValues;\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned3D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo3DFloat;\r\n this.formatValues = utils.erect3DPackedFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureUnsigned2D;\r\n this.renderStrategy = renderStrategy.PackedPixelTo2DFloat;\r\n this.formatValues = utils.erect2DPackedFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureUnsigned;\r\n this.renderStrategy = renderStrategy.PackedPixelToFloat;\r\n this.formatValues = utils.erectPackedFloat;\r\n return null;\r\n }\r\n\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n return this.requestFallback(args);\r\n }\r\n }\r\n } else if (this.precision === 'single') {\r\n this.renderRawOutput = this.readFloatPixelsToFloat32Array;\r\n this.transferValues = this.readFloatPixelsToFloat32Array;\r\n if (this.pipeline) {\r\n this.renderStrategy = renderStrategy.FloatTexture;\r\n this.renderOutput = this.renderTexture;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToTextures;\r\n }\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureMemoryOptimized;\r\n return null;\r\n }\r\n } else {\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureFloat3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureFloat2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureFloat;\r\n return null;\r\n }\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n return null;\r\n }\r\n }\r\n }\r\n this.renderOutput = this.renderValues;\r\n if (this.subKernels !== null) {\r\n this.renderKernels = this.renderKernelsToArrays;\r\n }\r\n if (this.optimizeFloatMemory) {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized3D;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat;\r\n this.formatValues = utils.erectMemoryOptimized3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureMemoryOptimized2D;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat;\r\n this.formatValues = utils.erectMemoryOptimized2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureMemoryOptimized;\r\n this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat;\r\n this.formatValues = utils.erectMemoryOptimizedFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray2;\r\n this.formatValues = utils.erect3DArray2;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray2;\r\n this.formatValues = utils.erect2DArray2;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray2;\r\n this.formatValues = utils.erectArray2;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray3;\r\n this.formatValues = utils.erect3DArray3;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray3;\r\n this.formatValues = utils.erect2DArray3;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray3;\r\n this.formatValues = utils.erectArray3;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray4;\r\n this.formatValues = utils.erect3DArray4;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray4;\r\n this.formatValues = utils.erect2DArray4;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray4;\r\n this.formatValues = utils.erectArray4;\r\n return null;\r\n }\r\n }\r\n } else {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureFloat3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DFloat;\r\n this.formatValues = utils.erect3DFloat;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureFloat2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DFloat;\r\n this.formatValues = utils.erect2DFloat;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureFloat;\r\n this.renderStrategy = renderStrategy.FloatPixelToFloat;\r\n this.formatValues = utils.erectFloat;\r\n return null;\r\n }\r\n break;\r\n case 'Array(2)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray2;\r\n this.formatValues = utils.erect3DArray2;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray2Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray2;\r\n this.formatValues = utils.erect2DArray2;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray2Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray2;\r\n this.formatValues = utils.erectArray2;\r\n return null;\r\n }\r\n break;\r\n case 'Array(3)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray3;\r\n this.formatValues = utils.erect3DArray3;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray3Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray3;\r\n this.formatValues = utils.erect2DArray3;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray3Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray3;\r\n this.formatValues = utils.erectArray3;\r\n return null;\r\n }\r\n break;\r\n case 'Array(4)':\r\n if (this.output[2] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float3D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo3DArray4;\r\n this.formatValues = utils.erect3DArray4;\r\n return null;\r\n } else if (this.output[1] > 0) {\r\n this.TextureConstructor = GLTextureArray4Float2D;\r\n this.renderStrategy = renderStrategy.FloatPixelTo2DArray4;\r\n this.formatValues = utils.erect2DArray4;\r\n return null;\r\n } else {\r\n this.TextureConstructor = GLTextureArray4Float;\r\n this.renderStrategy = renderStrategy.FloatPixelToArray4;\r\n this.formatValues = utils.erectArray4;\r\n return null;\r\n }\r\n }\r\n }\r\n } else {\r\n throw new Error(`unhandled precision of \"${this.precision}\"`);\r\n }\r\n\r\n throw new Error(`unhandled return type \"${this.returnType}\"`);\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @returns String\r\n */\r\n getKernelString() {\r\n throw new Error(`abstract method call`);\r\n }\r\n\r\n getMainResultTexture() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Integer':\r\n case 'Number':\r\n return this.getMainResultNumberTexture();\r\n case 'Array(2)':\r\n return this.getMainResultArray2Texture();\r\n case 'Array(3)':\r\n return this.getMainResultArray3Texture();\r\n case 'Array(4)':\r\n return this.getMainResultArray4Texture();\r\n default:\r\n throw new Error(`unhandled returnType type ${ this.returnType }`);\r\n }\r\n }\r\n\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelNumberTexture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelNumberTexture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray2Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray2Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray3Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray3Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultKernelArray4Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultSubKernelArray4Texture() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultGraphical() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultMemoryOptimizedFloats() {\r\n throw new Error(`abstract method call`);\r\n }\r\n /**\r\n * @abstract\r\n * @returns String[]\r\n */\r\n getMainResultPackedPixels() {\r\n throw new Error(`abstract method call`);\r\n }\r\n\r\n getMainResultString() {\r\n if (this.graphical) {\r\n return this.getMainResultGraphical();\r\n } else if (this.precision === 'single') {\r\n if (this.optimizeFloatMemory) {\r\n return this.getMainResultMemoryOptimizedFloats();\r\n }\r\n return this.getMainResultTexture();\r\n } else {\r\n return this.getMainResultPackedPixels();\r\n }\r\n }\r\n\r\n getMainResultNumberTexture() {\r\n return utils.linesToString(this.getMainResultKernelNumberTexture()) +\r\n utils.linesToString(this.getMainResultSubKernelNumberTexture());\r\n }\r\n\r\n getMainResultArray2Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray2Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray2Texture());\r\n }\r\n\r\n getMainResultArray3Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray3Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray3Texture());\r\n }\r\n\r\n getMainResultArray4Texture() {\r\n return utils.linesToString(this.getMainResultKernelArray4Texture()) +\r\n utils.linesToString(this.getMainResultSubKernelArray4Texture());\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getFloatTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp float;\\n';\r\n case 'performance':\r\n return 'precision highp float;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump float;\\n';\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getIntTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp int;\\n';\r\n case 'performance':\r\n return 'precision highp int;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump int;\\n';\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @return {string}\r\n */\r\n getSampler2DTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp sampler2D;\\n';\r\n case 'performance':\r\n return 'precision highp sampler2D;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump sampler2D;\\n';\r\n }\r\n }\r\n\r\n getSampler2DArrayTacticDeclaration() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'precision lowp sampler2DArray;\\n';\r\n case 'performance':\r\n return 'precision highp sampler2DArray;\\n';\r\n case 'balanced':\r\n default:\r\n return 'precision mediump sampler2DArray;\\n';\r\n }\r\n }\r\n\r\n renderTexture() {\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n readPackedPixelsToUint8Array() {\r\n if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be \"unsigned\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const result = new Uint8Array(texSize[0] * texSize[1] * 4);\r\n gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result);\r\n return result;\r\n }\r\n\r\n readPackedPixelsToFloat32Array() {\r\n return new Float32Array(this.readPackedPixelsToUint8Array().buffer);\r\n }\r\n\r\n readFloatPixelsToFloat32Array() {\r\n if (this.precision !== 'single') throw new Error('Requires this.precision to be \"single\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const w = texSize[0];\r\n const h = texSize[1];\r\n const result = new Float32Array(w * h * 4);\r\n gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n\r\n readMemoryOptimizedFloatPixelsToFloat32Array() {\r\n if (this.precision !== 'single') throw new Error('Requires this.precision to be \"single\"');\r\n const {\r\n texSize,\r\n context: gl\r\n } = this;\r\n const w = texSize[0];\r\n const h = texSize[1];\r\n const result = new Float32Array(w * h * 4);\r\n gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result);\r\n return result;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Boolean} [flip]\r\n * @return {Uint8Array}\r\n */\r\n getPixels(flip) {\r\n const {\r\n context: gl,\r\n output\r\n } = this;\r\n const [width, height] = output;\r\n const pixels = new Uint8Array(width * height * 4);\r\n gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);\r\n // flipped by default, so invert\r\n return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer);\r\n }\r\n\r\n renderKernelsToArrays() {\r\n const result = {\r\n result: this.renderOutput(),\r\n };\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n result[this.subKernels[i].property] = new this.TextureConstructor({\r\n texture: this.subKernelOutputTextures[i],\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n }).toArray();\r\n }\r\n return result;\r\n }\r\n\r\n renderKernelsToTextures() {\r\n const result = {\r\n result: this.renderOutput(),\r\n };\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n result[this.subKernels[i].property] = new this.TextureConstructor({\r\n texture: this.subKernelOutputTextures[i],\r\n size: this.texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n return result;\r\n }\r\n\r\n setOutput(output) {\r\n super.setOutput(output);\r\n if (this.program) {\r\n this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1];\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n const { context: gl } = this;\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n this.updateMaxTexSize();\r\n this.framebuffer.width = this.texSize[0];\r\n this.framebuffer.height = this.texSize[1];\r\n this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n this.canvas.width = this.maxTexSize[0];\r\n this.canvas.height = this.maxTexSize[1];\r\n this._setupOutputTexture();\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n this._setupSubOutputTextures();\r\n }\r\n }\r\n return this;\r\n }\r\n renderValues() {\r\n return this.formatValues(\r\n this.transferValues(),\r\n this.output[0],\r\n this.output[1],\r\n this.output[2]\r\n );\r\n }\r\n}\r\n\r\nexport const renderStrategy = Object.freeze({\r\n PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'),\r\n PackedPixelToFloat: Symbol('PackedPixelToFloat'),\r\n PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'),\r\n PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'),\r\n PackedTexture: Symbol('PackedTexture'),\r\n FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'),\r\n FloatPixelToFloat: Symbol('FloatPixelToFloat'),\r\n FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'),\r\n FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'),\r\n FloatPixelToArray2: Symbol('FloatPixelToArray2'),\r\n FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'),\r\n FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'),\r\n FloatPixelToArray3: Symbol('FloatPixelToArray3'),\r\n FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'),\r\n FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'),\r\n FloatPixelToArray4: Symbol('FloatPixelToArray4'),\r\n FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'),\r\n FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'),\r\n FloatTexture: Symbol('FloatTexture'),\r\n MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'),\r\n MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'),\r\n MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'),\r\n});\r\n\r\nconst typeMap = {\r\n int: 'Integer',\r\n float: 'Number',\r\n vec2: 'Array(2)',\r\n vec3: 'Array(3)',\r\n vec4: 'Array(4)',\r\n};\r\n","import { utils } from '../../utils';\r\nimport { FunctionNode } from '../function-node';\r\n// Closure capture for the ast function, prevent collision with existing AST functions\r\n// The prefixes to use\r\nconst jsMathPrefix = 'Math.';\r\nconst localPrefix = 'this.';\r\n\r\n/**\r\n * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code\r\n * @extends FunctionNode\r\n * @returns the converted WebGL function string\r\n */\r\nexport class WebGLFunctionNode extends FunctionNode {\r\n constructor(source, settings) {\r\n super(source, settings);\r\n if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) {\r\n this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy;\r\n }\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to its *named function*\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astFunction(ast, retArr) {\r\n // Setup function return type and name\r\n if (this.isRootKernel) {\r\n retArr.push('void');\r\n } else {\r\n // looking up return type, this is a little expensive, and can be avoided if returnType is set\r\n let lastReturn = null;\r\n if (!this.returnType) {\r\n const lastReturn = this.findLastReturn();\r\n if (lastReturn) {\r\n this.returnType = this.getType(ast.body);\r\n if (this.returnType === 'LiteralInteger') {\r\n this.returnType = 'Number';\r\n }\r\n }\r\n }\r\n\r\n const { returnType } = this;\r\n if (!returnType) {\r\n retArr.push('void');\r\n } else {\r\n const type = typeMap[returnType];\r\n if (!type) {\r\n throw new Error(`unknown type ${returnType}`);\r\n }\r\n retArr.push(type);\r\n }\r\n }\r\n retArr.push(' ');\r\n retArr.push(this.name);\r\n retArr.push('(');\r\n\r\n if (!this.isRootKernel) {\r\n // Arguments handling\r\n for (let i = 0; i < this.argumentNames.length; ++i) {\r\n const argumentName = this.argumentNames[i];\r\n\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)];\r\n // The type is too loose ended, here we descide to solidify a type, lets go with float\r\n if (!argumentType) {\r\n throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast);\r\n }\r\n if (argumentType === 'LiteralInteger') {\r\n this.argumentTypes[i] = argumentType = 'Number';\r\n }\r\n const type = typeMap[argumentType];\r\n if (!type) {\r\n throw this.astErrorOutput('Unexpected expression', ast);\r\n }\r\n retArr.push(type);\r\n retArr.push(' ');\r\n retArr.push('user_');\r\n retArr.push(argumentName);\r\n }\r\n }\r\n\r\n // Function opening\r\n retArr.push(') {\\n');\r\n\r\n // Body statement iteration\r\n for (let i = 0; i < ast.body.body.length; ++i) {\r\n this.astGeneric(ast.body.body[i], retArr);\r\n retArr.push('\\n');\r\n }\r\n\r\n // Function closing\r\n retArr.push('}\\n');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for to *return* statement\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astReturnStatement(ast, retArr) {\r\n if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast);\r\n this.pushState('skip-literal-correction');\r\n const type = this.getType(ast.argument);\r\n this.popState('skip-literal-correction');\r\n\r\n const result = [];\r\n\r\n if (!this.returnType) {\r\n if (type === 'LiteralInteger' || type === 'Integer') {\r\n this.returnType = 'Number';\r\n } else {\r\n this.returnType = type;\r\n }\r\n }\r\n\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Float':\r\n switch (type) {\r\n case 'Integer':\r\n result.push('float(');\r\n this.astGeneric(ast.argument, result);\r\n result.push(')');\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.argument, result);\r\n\r\n // Running astGeneric forces the LiteralInteger to pick a type, and here, if we are returning a float, yet\r\n // the LiteralInteger has picked to be an integer because of constraints on it we cast it to float.\r\n if (this.getType(ast) === 'Integer') {\r\n result.unshift('float(');\r\n result.push(')');\r\n }\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, result);\r\n }\r\n break;\r\n case 'Integer':\r\n switch (type) {\r\n case 'Float':\r\n case 'Number':\r\n this.castValueToInteger(ast.argument, result);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.argument, result);\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, result);\r\n }\r\n break;\r\n case 'Array(4)':\r\n case 'Array(3)':\r\n case 'Array(2)':\r\n case 'Input':\r\n this.astGeneric(ast.argument, result);\r\n break;\r\n default:\r\n throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast);\r\n }\r\n\r\n if (this.isRootKernel) {\r\n retArr.push(`kernelResult = ${ result.join('') };`);\r\n retArr.push('return;');\r\n } else if (this.isSubKernel) {\r\n retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`);\r\n retArr.push(`return subKernelResult_${ this.name };`);\r\n } else {\r\n retArr.push(`return ${ result.join('') };`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *literal value*\r\n *\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n *\r\n * @returns {Array} the append retArr\r\n */\r\n astLiteral(ast, retArr) {\r\n // Reject non numeric literals\r\n if (isNaN(ast.value)) {\r\n throw this.astErrorOutput(\r\n 'Non-numeric literal not supported : ' + ast.value,\r\n ast\r\n );\r\n }\r\n\r\n const key = `${ast.start},${ast.end}`;\r\n if (Number.isInteger(ast.value)) {\r\n if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.literalTypes[key] = 'Integer';\r\n retArr.push(`${ast.value}`);\r\n } else if (this.isState('casting-to-float') || this.isState('building-float')) {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}.0`);\r\n } else {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}.0`);\r\n }\r\n } else if (this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.literalTypes[key] = 'Integer';\r\n retArr.push(Math.round(ast.value));\r\n } else {\r\n this.literalTypes[key] = 'Number';\r\n retArr.push(`${ast.value}`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *binary* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astBinaryExpression(ast, retArr) {\r\n if (this.checkAndUpconvertOperator(ast, retArr)) {\r\n return retArr;\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy && ast.operator === '/') {\r\n retArr.push('div_with_int_check(');\r\n this.pushState('building-float');\r\n switch (this.getType(ast.left)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(', ');\r\n switch (this.getType(ast.right)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n this.popState('building-float');\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n retArr.push('(');\r\n const leftType = this.getType(ast.left) || 'Number';\r\n const rightType = this.getType(ast.right) || 'Number';\r\n if (!leftType || !rightType) {\r\n throw this.astErrorOutput(`Unhandled binary expression`, ast);\r\n }\r\n const key = leftType + ' & ' + rightType;\r\n switch (key) {\r\n case 'Integer & Integer':\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n case 'Number & Float':\r\n case 'Float & Number':\r\n case 'Float & Float':\r\n case 'Number & Number':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n case 'LiteralInteger & LiteralInteger':\r\n if (this.isState('casting-to-integer') || this.isState('building-integer')) {\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.castLiteralToFloat(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n }\r\n break;\r\n\r\n case 'Integer & Float':\r\n case 'Integer & Number':\r\n if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') {\r\n // if right value is actually a float, don't loose that information, cast left to right rather than the usual right to left\r\n if (!Number.isInteger(ast.right.value)) {\r\n this.pushState('building-float');\r\n this.castValueToFloat(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n }\r\n }\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.pushState('casting-to-integer');\r\n if (ast.right.type === 'Literal') {\r\n const literalResult = [];\r\n this.astGeneric(ast.right, literalResult);\r\n const literalType = this.getType(ast.right);\r\n if (literalType === 'Integer') {\r\n retArr.push(literalResult.join(''));\r\n } else {\r\n throw this.astErrorOutput(`Unhandled binary expression with literal`, ast);\r\n }\r\n } else {\r\n retArr.push('int(');\r\n this.astGeneric(ast.right, retArr);\r\n retArr.push(')');\r\n }\r\n this.popState('casting-to-integer');\r\n this.popState('building-integer');\r\n break;\r\n case 'Integer & LiteralInteger':\r\n this.pushState('building-integer');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n\r\n case 'Number & Integer':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n case 'Float & LiteralInteger':\r\n case 'Number & LiteralInteger':\r\n if (this.isState('in-for-loop-test')) {\r\n this.pushState('building-integer');\r\n retArr.push('int(');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(')');\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castLiteralToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n }\r\n break;\r\n case 'LiteralInteger & Float':\r\n case 'LiteralInteger & Number':\r\n if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) {\r\n this.pushState('building-integer');\r\n this.castLiteralToInteger(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToInteger(ast.right, retArr);\r\n this.popState('building-integer');\r\n } else {\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.pushState('casting-to-float');\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('casting-to-float');\r\n this.popState('building-float');\r\n }\r\n break;\r\n case 'LiteralInteger & Integer':\r\n this.pushState('building-integer');\r\n this.castLiteralToInteger(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-integer');\r\n break;\r\n\r\n case 'Boolean & Boolean':\r\n this.pushState('building-boolean');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.astGeneric(ast.right, retArr);\r\n this.popState('building-boolean');\r\n break;\r\n\r\n case 'Float & Integer':\r\n this.pushState('building-float');\r\n this.astGeneric(ast.left, retArr);\r\n retArr.push(operatorMap[ast.operator] || ast.operator);\r\n this.castValueToFloat(ast.right, retArr);\r\n this.popState('building-float');\r\n break;\r\n\r\n default:\r\n throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast);\r\n }\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertOperator(ast, retArr) {\r\n const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr);\r\n if (bitwiseResult) {\r\n return bitwiseResult;\r\n }\r\n const upconvertableOperators = {\r\n '%': 'mod',\r\n '**': 'pow',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n switch (this.getType(ast.left)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(',');\r\n switch (this.getType(ast.right)) {\r\n case 'Integer':\r\n this.castValueToFloat(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseOperators(ast, retArr) {\r\n const upconvertableOperators = {\r\n '&': 'bitwiseAnd',\r\n '|': 'bitwiseOr',\r\n '^': 'bitwiseXOR',\r\n '<<': 'bitwiseZeroFillLeftShift',\r\n '>>': 'bitwiseSignedRightShift',\r\n '>>>': 'bitwiseZeroFillRightShift',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n const leftType = this.getType(ast.left);\r\n switch (leftType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.left, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.left, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.left, retArr);\r\n }\r\n retArr.push(',');\r\n const rightType = this.getType(ast.right);\r\n switch (rightType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.right, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.right, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.right, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n checkAndUpconvertBitwiseUnary(ast, retArr) {\r\n const upconvertableOperators = {\r\n '~': 'bitwiseNot',\r\n };\r\n const foundOperator = upconvertableOperators[ast.operator];\r\n if (!foundOperator) return null;\r\n retArr.push(foundOperator);\r\n retArr.push('(');\r\n switch (this.getType(ast.argument)) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(ast.argument, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(ast.argument, retArr);\r\n break;\r\n default:\r\n this.astGeneric(ast.argument, retArr);\r\n }\r\n retArr.push(')');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castLiteralToInteger(ast, retArr) {\r\n this.pushState('casting-to-integer');\r\n this.astGeneric(ast, retArr);\r\n this.popState('casting-to-integer');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castLiteralToFloat(ast, retArr) {\r\n this.pushState('casting-to-float');\r\n this.astGeneric(ast, retArr);\r\n this.popState('casting-to-float');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castValueToInteger(ast, retArr) {\r\n this.pushState('casting-to-integer');\r\n retArr.push('int(');\r\n this.astGeneric(ast, retArr);\r\n retArr.push(')');\r\n this.popState('casting-to-integer');\r\n return retArr;\r\n }\r\n\r\n /**\r\n *\r\n * @param {Object} ast\r\n * @param {Array} retArr\r\n * @return {String[]}\r\n */\r\n castValueToFloat(ast, retArr) {\r\n this.pushState('casting-to-float');\r\n retArr.push('float(');\r\n this.astGeneric(ast, retArr);\r\n retArr.push(')');\r\n this.popState('casting-to-float');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode);\r\n }\r\n\r\n const type = this.getType(idtNode);\r\n\r\n if (idtNode.name === 'Infinity') {\r\n // https://stackoverflow.com/a/47543127/1324039\r\n retArr.push('3.402823466e+38');\r\n } else if (type === 'Boolean') {\r\n if (this.argumentNames.indexOf(idtNode.name) > -1) {\r\n retArr.push(`bool(user_${idtNode.name})`);\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *for-loop* expression\r\n * @param {Object} forNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astForStatement(forNode, retArr) {\r\n if (forNode.type !== 'ForStatement') {\r\n throw this.astErrorOutput('Invalid for statement', forNode);\r\n }\r\n\r\n const initArr = [];\r\n const testArr = [];\r\n const updateArr = [];\r\n const bodyArr = [];\r\n let isSafe = null;\r\n\r\n if (forNode.init) {\r\n this.pushState('in-for-loop-init');\r\n this.astGeneric(forNode.init, initArr);\r\n const { declarations } = forNode.init;\r\n for (let i = 0; i < declarations.length; i++) {\r\n if (declarations[i].init && declarations[i].init.type !== 'Literal') {\r\n isSafe = false;\r\n }\r\n }\r\n if (isSafe) {\r\n for (let i = 0; i < initArr.length; i++) {\r\n if (initArr[i].includes && initArr[i].includes(',')) {\r\n isSafe = false;\r\n }\r\n }\r\n }\r\n this.popState('in-for-loop-init');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.test) {\r\n this.pushState('in-for-loop-test');\r\n this.astGeneric(forNode.test, testArr);\r\n this.popState('in-for-loop-test');\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.update) {\r\n this.astGeneric(forNode.update, updateArr);\r\n } else {\r\n isSafe = false;\r\n }\r\n\r\n if (forNode.body) {\r\n this.pushState('loop-body');\r\n this.astGeneric(forNode.body, bodyArr);\r\n this.popState('loop-body');\r\n }\r\n\r\n // have all parts, now make them safe\r\n if (isSafe === null) {\r\n isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test);\r\n }\r\n\r\n if (isSafe) {\r\n retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\\n`);\r\n retArr.push(bodyArr.join(''));\r\n retArr.push('}\\n');\r\n } else {\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n if (initArr.length > 0) {\r\n retArr.push(initArr.join(''), ';\\n');\r\n }\r\n retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) {\r\n retArr.push(`if (!${testArr.join('')}) break;\\n`);\r\n }\r\n retArr.push(bodyArr.join(''));\r\n retArr.push(`\\n${updateArr.join('')};`);\r\n retArr.push('}\\n');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *while* loop\r\n * @param {Object} whileNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the parsed webgl string\r\n */\r\n astWhileStatement(whileNode, retArr) {\r\n if (whileNode.type !== 'WhileStatement') {\r\n throw this.astErrorOutput('Invalid while statement', whileNode);\r\n }\r\n\r\n const iVariableName = this.getInternalVariableName('safeI');\r\n retArr.push(`for (int ${iVariableName}=0;${iVariableName} i + 1) {\r\n movingDefaultToEnd = true;\r\n this.astGeneric(cases[i].consequent, defaultResult);\r\n continue;\r\n } else {\r\n retArr.push(' else {\\n');\r\n }\r\n } else {\r\n // all others\r\n if (i === 0 || !pastFirstIf) {\r\n pastFirstIf = true;\r\n retArr.push(`if (${varName} == `);\r\n } else {\r\n if (fallingThrough) {\r\n retArr.push(`${varName} == `);\r\n fallingThrough = false;\r\n } else {\r\n retArr.push(` else if (${varName} == `);\r\n }\r\n }\r\n if (type === 'Integer') {\r\n const testType = this.getType(cases[i].test);\r\n switch (testType) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(cases[i].test, retArr);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(cases[i].test, retArr);\r\n break;\r\n }\r\n } else if (type === 'Float') {\r\n const testType = this.getType(cases[i].test);\r\n switch (testType) {\r\n case 'LiteralInteger':\r\n this.castLiteralToFloat(cases[i].test, retArr);\r\n break;\r\n case 'Integer':\r\n this.castValueToFloat(cases[i].test, retArr);\r\n break;\r\n }\r\n } else {\r\n throw new Error('unhanlded');\r\n }\r\n if (!cases[i].consequent || cases[i].consequent.length === 0) {\r\n fallingThrough = true;\r\n retArr.push(' || ');\r\n continue;\r\n }\r\n retArr.push(`) {\\n`);\r\n }\r\n this.astGeneric(cases[i].consequent, retArr);\r\n retArr.push('\\n}');\r\n }\r\n if (movingDefaultToEnd) {\r\n retArr.push(' else {');\r\n retArr.push(defaultResult.join(''));\r\n retArr.push('}');\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *This* expression\r\n * @param {Object} tNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astThisExpression(tNode, retArr) {\r\n retArr.push('this');\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Member* Expression\r\n * @param {Object} mNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astMemberExpression(mNode, retArr) {\r\n const {\r\n property,\r\n name,\r\n signature,\r\n origin,\r\n type,\r\n xProperty,\r\n yProperty,\r\n zProperty\r\n } = this.getMemberExpressionDetails(mNode);\r\n switch (signature) {\r\n case 'value.thread.value':\r\n case 'this.thread.value':\r\n if (name !== 'x' && name !== 'y' && name !== 'z') {\r\n throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode);\r\n }\r\n retArr.push(`threadId.${name}`);\r\n return retArr;\r\n case 'this.output.value':\r\n if (this.dynamicOutput) {\r\n switch (name) {\r\n case 'x':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.x)');\r\n } else {\r\n retArr.push('uOutputDim.x');\r\n }\r\n break;\r\n case 'y':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.y)');\r\n } else {\r\n retArr.push('uOutputDim.y');\r\n }\r\n break;\r\n case 'z':\r\n if (this.isState('casting-to-float')) {\r\n retArr.push('float(uOutputDim.z)');\r\n } else {\r\n retArr.push('uOutputDim.z');\r\n }\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n } else {\r\n switch (name) {\r\n case 'x':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[0]);\r\n } else {\r\n retArr.push(this.output[0], '.0');\r\n }\r\n break;\r\n case 'y':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[1]);\r\n } else {\r\n retArr.push(this.output[1], '.0');\r\n }\r\n break;\r\n case 'z':\r\n if (this.isState('casting-to-integer')) {\r\n retArr.push(this.output[2]);\r\n } else {\r\n retArr.push(this.output[2], '.0');\r\n }\r\n break;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n }\r\n return retArr;\r\n case 'value':\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n case 'value[]':\r\n case 'value[][]':\r\n case 'value[][][]':\r\n case 'value[][][][]':\r\n case 'value.value':\r\n if (origin === 'Math') {\r\n retArr.push(Math[name]);\r\n return retArr;\r\n }\r\n switch (property) {\r\n case 'r':\r\n retArr.push(`user_${ name }.r`);\r\n return retArr;\r\n case 'g':\r\n retArr.push(`user_${ name }.g`);\r\n return retArr;\r\n case 'b':\r\n retArr.push(`user_${ name }.b`);\r\n return retArr;\r\n case 'a':\r\n retArr.push(`user_${ name }.a`);\r\n return retArr;\r\n }\r\n break;\r\n case 'this.constants.value':\r\n if (typeof xProperty === 'undefined') {\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n retArr.push(`constants_${ name }`);\r\n return retArr;\r\n }\r\n }\r\n case 'this.constants.value[]':\r\n case 'this.constants.value[][]':\r\n case 'this.constants.value[][][]':\r\n case 'this.constants.value[][][][]':\r\n break;\r\n case 'fn()[]':\r\n this.astCallExpression(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(property));\r\n retArr.push(']');\r\n return retArr;\r\n case '[][]':\r\n this.astArrayExpression(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(property));\r\n retArr.push(']');\r\n return retArr;\r\n default:\r\n throw this.astErrorOutput('Unexpected expression', mNode);\r\n }\r\n\r\n if (mNode.computed === false) {\r\n // handle simple types\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'Boolean':\r\n retArr.push(`${origin}_${name}`);\r\n return retArr;\r\n }\r\n }\r\n\r\n // handle more complex types\r\n // argument may have come from a parent\r\n const markupName = `${origin}_${name}`;\r\n\r\n switch (type) {\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n // Get from local vec4\r\n this.astGeneric(mNode.object, retArr);\r\n retArr.push('[');\r\n retArr.push(this.memberExpressionPropertyMarkup(xProperty));\r\n retArr.push(']');\r\n break;\r\n case 'HTMLImageArray':\r\n retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(1)':\r\n retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(2)':\r\n case 'Array2D(2)':\r\n case 'Array3D(2)':\r\n retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(2)':\r\n retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(3)':\r\n case 'Array2D(3)':\r\n case 'Array3D(3)':\r\n retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(3)':\r\n retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'Array1D(4)':\r\n case 'Array2D(4)':\r\n case 'Array3D(4)':\r\n retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'ArrayTexture(4)':\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n case 'NumberTexture':\r\n case 'Array':\r\n case 'Array2D':\r\n case 'Array3D':\r\n case 'Array4D':\r\n case 'Input':\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.precision === 'single') {\r\n // bitRatio is always 4 here, javascript doesn't yet have 8 or 16 bit support\r\n // TODO: make 8 or 16 bit work anyway!\r\n retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n } else {\r\n const bitRatio = (origin === 'user' ?\r\n this.lookupFunctionArgumentBitRatio(this.name, name) :\r\n this.constantBitRatios[name]\r\n );\r\n switch (bitRatio) {\r\n case 1:\r\n retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n case 2:\r\n retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n case 4:\r\n case 0:\r\n retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `);\r\n break;\r\n default:\r\n throw new Error(`unhandled bit ratio of ${bitRatio}`);\r\n }\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n }\r\n break;\r\n case 'MemoryOptimizedNumberTexture':\r\n retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `);\r\n this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr);\r\n retArr.push(')');\r\n break;\r\n default:\r\n throw new Error(`unhandled member expression \"${ type }\"`);\r\n }\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *call* expression\r\n * @param {Object} ast - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astCallExpression(ast, retArr) {\r\n if (!ast.callee) {\r\n throw this.astErrorOutput('Unknown CallExpression', ast);\r\n }\r\n\r\n let functionName = null;\r\n const isMathFunction = this.isAstMathFunction(ast);\r\n\r\n // Its a math operator or this.something(), remove the prefix\r\n if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) {\r\n functionName = ast.callee.property.name;\r\n }\r\n // Issue #212, BABEL!\r\n else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) {\r\n functionName = ast.callee.expressions[1].property.name;\r\n } else {\r\n functionName = ast.callee.name;\r\n }\r\n\r\n if (!functionName) {\r\n throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast);\r\n }\r\n\r\n // if this if grows to more than one, lets use a switch\r\n if (functionName === 'atan2') {\r\n functionName = 'atan';\r\n }\r\n\r\n // Register the function into the called registry\r\n if (this.calledFunctions.indexOf(functionName) < 0) {\r\n this.calledFunctions.push(functionName);\r\n }\r\n\r\n if (functionName === 'random' && this.plugins && this.plugins.length > 0) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) {\r\n retArr.push(plugin.functionReplace);\r\n return retArr;\r\n }\r\n }\r\n }\r\n\r\n // track the function was called\r\n if (this.onFunctionCall) {\r\n this.onFunctionCall(this.name, functionName, ast.arguments);\r\n }\r\n\r\n // Call the function\r\n retArr.push(functionName);\r\n\r\n // Open arguments space\r\n retArr.push('(');\r\n\r\n // Add the arguments\r\n if (isMathFunction) {\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n const argumentType = this.getType(argument);\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n\r\n switch (argumentType) {\r\n case 'Integer':\r\n this.castValueToFloat(argument, retArr);\r\n break;\r\n default:\r\n this.astGeneric(argument, retArr);\r\n break;\r\n }\r\n }\r\n } else {\r\n const targetTypes = this.lookupFunctionArgumentTypes(functionName) || [];\r\n for (let i = 0; i < ast.arguments.length; ++i) {\r\n const argument = ast.arguments[i];\r\n let targetType = targetTypes[i];\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const argumentType = this.getType(argument);\r\n if (!targetType) {\r\n this.triggerImplyArgumentType(functionName, i, argumentType, this);\r\n targetType = argumentType;\r\n }\r\n switch (argumentType) {\r\n case 'Number':\r\n case 'Float':\r\n if (targetType === 'Integer') {\r\n retArr.push('int(');\r\n this.astGeneric(argument, retArr);\r\n retArr.push(')');\r\n continue;\r\n } else if (targetType === 'Number' || targetType === 'Float') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n } else if (targetType === 'LiteralInteger') {\r\n this.castLiteralToFloat(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'Integer':\r\n if (targetType === 'Number' || targetType === 'Float') {\r\n retArr.push('float(');\r\n this.astGeneric(argument, retArr);\r\n retArr.push(')');\r\n continue;\r\n } else if (targetType === 'Integer') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'LiteralInteger':\r\n if (targetType === 'Integer') {\r\n this.castLiteralToInteger(argument, retArr);\r\n continue;\r\n } else if (targetType === 'Number' || targetType === 'Float') {\r\n this.castLiteralToFloat(argument, retArr);\r\n continue;\r\n } else if (targetType === 'LiteralInteger') {\r\n this.astGeneric(argument, retArr);\r\n continue;\r\n }\r\n break;\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n if (targetType === argumentType) {\r\n if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);\r\n this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);\r\n retArr.push(`user_${argument.name}`);\r\n continue;\r\n }\r\n break;\r\n case 'HTMLImage':\r\n case 'HTMLImageArray':\r\n case 'HTMLVideo':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n case 'Array':\r\n case 'Input':\r\n if (targetType === argumentType) {\r\n if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast);\r\n this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i);\r\n retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`);\r\n continue;\r\n }\r\n break;\r\n }\r\n throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named \"${ argument.name }\"`, ast);\r\n }\r\n }\r\n // Close arguments space\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *Array* Expression\r\n * @param {Object} arrNode - the AST object to parse\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astArrayExpression(arrNode, retArr) {\r\n const arrLen = arrNode.elements.length;\r\n\r\n retArr.push('vec' + arrLen + '(');\r\n for (let i = 0; i < arrLen; ++i) {\r\n if (i > 0) {\r\n retArr.push(', ');\r\n }\r\n const subNode = arrNode.elements[i];\r\n this.astGeneric(subNode, retArr)\r\n }\r\n retArr.push(')');\r\n\r\n return retArr;\r\n }\r\n\r\n memberExpressionXYZ(x, y, z, retArr) {\r\n if (z) {\r\n retArr.push(this.memberExpressionPropertyMarkup(z), ', ');\r\n } else {\r\n retArr.push('0, ');\r\n }\r\n if (y) {\r\n retArr.push(this.memberExpressionPropertyMarkup(y), ', ');\r\n } else {\r\n retArr.push('0, ');\r\n }\r\n retArr.push(this.memberExpressionPropertyMarkup(x));\r\n return retArr;\r\n }\r\n\r\n memberExpressionPropertyMarkup(property) {\r\n if (!property) {\r\n throw new Error('Property not set');\r\n }\r\n const type = this.getType(property);\r\n const result = [];\r\n switch (type) {\r\n case 'Number':\r\n case 'Float':\r\n this.castValueToInteger(property, result);\r\n break;\r\n case 'LiteralInteger':\r\n this.castLiteralToInteger(property, result);\r\n break;\r\n default:\r\n this.astGeneric(property, result);\r\n }\r\n return result.join('');\r\n }\r\n}\r\n\r\nconst typeMap = {\r\n 'Array': 'sampler2D',\r\n 'Array(2)': 'vec2',\r\n 'Array(3)': 'vec3',\r\n 'Array(4)': 'vec4',\r\n 'Array2D': 'sampler2D',\r\n 'Array3D': 'sampler2D',\r\n 'Boolean': 'bool',\r\n 'Float': 'float',\r\n 'Input': 'sampler2D',\r\n 'Integer': 'int',\r\n 'Number': 'float',\r\n 'LiteralInteger': 'float',\r\n 'NumberTexture': 'sampler2D',\r\n 'MemoryOptimizedNumberTexture': 'sampler2D',\r\n 'ArrayTexture(1)': 'sampler2D',\r\n 'ArrayTexture(2)': 'sampler2D',\r\n 'ArrayTexture(3)': 'sampler2D',\r\n 'ArrayTexture(4)': 'sampler2D',\r\n 'HTMLVideo': 'sampler2D',\r\n 'HTMLImage': 'sampler2D',\r\n 'HTMLImageArray': 'sampler2DArray',\r\n};\r\n\r\nconst operatorMap = {\r\n '===': '==',\r\n '!==': '!='\r\n};\r\n","const source = `\r\n\r\nuniform highp float triangle_noise_seed;\r\nhighp float triangle_noise_shift = 0.000001;\r\n\r\n//https://www.shadertoy.com/view/4t2SDh\r\n//note: uniformly distributed, normalized rand, [0;1[\r\nfloat nrand( vec2 n )\r\n{\r\n return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);\r\n}\r\n//note: remaps v to [0;1] in interval [a;b]\r\nfloat remap( float a, float b, float v )\r\n{\r\n return clamp( (v-a) / (b-a), 0.0, 1.0 );\r\n}\r\n\r\nfloat n4rand( vec2 n )\r\n{\r\n float t = fract( triangle_noise_seed + triangle_noise_shift );\r\n float nrnd0 = nrand( n + 0.07*t );\r\n float nrnd1 = nrand( n + 0.11*t );\r\n float nrnd2 = nrand( n + 0.13*t );\r\n float nrnd3 = nrand( n + 0.17*t );\r\n float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0;\r\n triangle_noise_shift = result + 0.000001;\r\n return result;\r\n}`;\r\n\r\nconst name = 'triangle-noise-noise';\r\n\r\nconst functionMatch = 'Math.random()';\r\n\r\nconst functionReplace = 'n4rand(vTexCoord)';\r\n\r\nconst functionReturnType = 'Number';\r\n\r\nconst onBeforeRun = (kernel) => {\r\n kernel.setUniform1f('triangle_noise_seed', Math.random());\r\n};\r\n\r\n/**\r\n * @type IPlugin\r\n */\r\nexport default {\r\n name,\r\n onBeforeRun,\r\n functionMatch,\r\n functionReplace,\r\n functionReturnType,\r\n source\r\n};\r\n","// language=GLSL\r\nexport const fragmentShader = `__HEADER__;\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nconst int LOOP_MAX = __LOOP_MAX__;\r\n\r\n__PLUGINS__;\r\n__CONSTANTS__;\r\n\r\nvarying vec2 vTexCoord;\r\n\r\nvec4 round(vec4 x) {\r\n return floor(x + 0.5);\r\n}\r\n\r\nfloat round(float x) {\r\n return floor(x + 0.5);\r\n}\r\n\r\nconst int BIT_COUNT = 32;\r\nint modi(int x, int y) {\r\n return x - y * (x / y);\r\n}\r\n\r\nint bitwiseOr(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseXOR(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseAnd(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 && b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseNot(int a) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (modi(a, 2) == 0) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n n = n * 2;\r\n }\r\n return result;\r\n}\r\nint bitwiseZeroFillLeftShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n *= 2;\r\n }\r\n\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nint bitwiseSignedRightShift(int num, int shifts) {\r\n return int(floor(float(num) / pow(2.0, float(shifts))));\r\n}\r\n\r\nint bitwiseZeroFillRightShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n /= 2;\r\n }\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nvec2 integerMod(vec2 x, float y) {\r\n vec2 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec3 integerMod(vec3 x, float y) {\r\n vec3 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec4 integerMod(vec4 x, vec4 y) {\r\n vec4 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nfloat integerMod(float x, float y) {\r\n float res = floor(mod(x, y));\r\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\r\n}\r\n\r\nint integerMod(int x, int y) {\r\n return x - (y * int(x / y));\r\n}\r\n\r\n__DIVIDE_WITH_INTEGER_CHECK__;\r\n\r\n// Here be dragons!\r\n// DO NOT OPTIMIZE THIS CODE\r\n// YOU WILL BREAK SOMETHING ON SOMEBODY\\'S MACHINE\r\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\r\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\r\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\r\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\r\nfloat decode32(vec4 texel) {\r\n __DECODE32_ENDIANNESS__;\r\n texel *= 255.0;\r\n vec2 gte128;\r\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\r\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\r\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\r\n float res = exp2(round(exponent));\r\n texel.b = texel.b - 128.0 * gte128.x;\r\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\r\n res *= gte128.y * -2.0 + 1.0;\r\n return res;\r\n}\r\n\r\nfloat decode16(vec4 texel, int index) {\r\n int channel = integerMod(index, 2);\r\n if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0;\r\n if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0;\r\n return 0.0;\r\n}\r\n\r\nfloat decode8(vec4 texel, int index) {\r\n int channel = integerMod(index, 4);\r\n if (channel == 0) return texel.r * 255.0;\r\n if (channel == 1) return texel.g * 255.0;\r\n if (channel == 2) return texel.b * 255.0;\r\n if (channel == 3) return texel.a * 255.0;\r\n return 0.0;\r\n}\r\n\r\nvec4 legacyEncode32(float f) {\r\n float F = abs(f);\r\n float sign = f < 0.0 ? 1.0 : 0.0;\r\n float exponent = floor(log2(F));\r\n float mantissa = (exp2(-exponent) * F);\r\n // exponent += floor(log2(mantissa));\r\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\r\n texel.rg = integerMod(texel.rg, 256.0);\r\n texel.b = integerMod(texel.b, 128.0);\r\n texel.a = exponent*0.5 + 63.5;\r\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\r\n texel = floor(texel);\r\n texel *= 0.003921569; // 1/255\r\n __ENCODE32_ENDIANNESS__;\r\n return texel;\r\n}\r\n\r\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\r\nvec4 encode32(float value) {\r\n if (value == 0.0) return vec4(0, 0, 0, 0);\r\n\r\n float exponent;\r\n float mantissa;\r\n vec4 result;\r\n float sgn;\r\n\r\n sgn = step(0.0, -value);\r\n value = abs(value);\r\n\r\n exponent = floor(log2(value));\r\n\r\n mantissa = value*pow(2.0, -exponent)-1.0;\r\n exponent = exponent+127.0;\r\n result = vec4(0,0,0,0);\r\n\r\n result.a = floor(exponent/2.0);\r\n exponent = exponent - result.a*2.0;\r\n result.a = result.a + 128.0*sgn;\r\n\r\n result.b = floor(mantissa * 128.0);\r\n mantissa = mantissa - result.b / 128.0;\r\n result.b = result.b + exponent*128.0;\r\n\r\n result.g = floor(mantissa*32768.0);\r\n mantissa = mantissa - result.g/32768.0;\r\n\r\n result.r = floor(mantissa*8388608.0);\r\n return result/255.0;\r\n}\r\n// Dragons end here\r\n\r\nint index;\r\nivec3 threadId;\r\n\r\nivec3 indexTo3D(int idx, ivec3 texDim) {\r\n int z = int(idx / (texDim.x * texDim.y));\r\n idx -= z * int(texDim.x * texDim.y);\r\n int y = int(idx / texDim.x);\r\n int x = int(integerMod(idx, texDim.x));\r\n return ivec3(x, y, z);\r\n}\r\n\r\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n return decode32(texel);\r\n}\r\n\r\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x * 2;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y));\r\n return decode16(texel, index);\r\n}\r\n\r\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x * 4;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y));\r\n return decode8(texel, index);\r\n}\r\n\r\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 4);\r\n index = index / 4;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n if (channel == 0) return texel.r;\r\n if (channel == 1) return texel.g;\r\n if (channel == 2) return texel.b;\r\n if (channel == 3) return texel.a;\r\n return 0.0;\r\n}\r\n\r\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture2D(tex, st / vec2(texSize));\r\n}\r\n\r\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return result[0];\r\n}\r\n\r\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec2(result[0], result[1]);\r\n}\r\n\r\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int channel = integerMod(index, 2);\r\n index = index / 2;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n if (channel == 0) return vec2(texel.r, texel.g);\r\n if (channel == 1) return vec2(texel.b, texel.a);\r\n return vec2(0.0, 0.0);\r\n}\r\n\r\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec3(result[0], result[1], result[2]);\r\n}\r\n\r\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\r\n int vectorIndex = fieldIndex / 4;\r\n int vectorOffset = fieldIndex - vectorIndex * 4;\r\n int readY = vectorIndex / texSize.x;\r\n int readX = vectorIndex - readY * texSize.x;\r\n vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\r\n\r\n if (vectorOffset == 0) {\r\n return tex1.xyz;\r\n } else if (vectorOffset == 1) {\r\n return tex1.yzw;\r\n } else {\r\n readX++;\r\n if (readX >= texSize.x) {\r\n readX = 0;\r\n readY++;\r\n }\r\n vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize));\r\n if (vectorOffset == 2) {\r\n return vec3(tex1.z, tex1.w, tex2.x);\r\n } else {\r\n return vec3(tex1.w, tex2.x, tex2.y);\r\n }\r\n }\r\n}\r\n\r\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n return getImage2D(tex, texSize, texDim, z, y, x);\r\n}\r\n\r\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture2D(tex, st / vec2(texSize));\r\n return vec4(texel.r, texel.g, texel.b, texel.a);\r\n}\r\n\r\nvec4 actualColor;\r\nvoid color(float r, float g, float b, float a) {\r\n actualColor = vec4(r,g,b,a);\r\n}\r\n\r\nvoid color(float r, float g, float b) {\r\n color(r,g,b,1.0);\r\n}\r\n\r\nvoid color(sampler2D image) {\r\n actualColor = texture2D(image, vTexCoord);\r\n}\r\n\r\n__INJECTED_NATIVE__;\r\n__MAIN_CONSTANTS__;\r\n__MAIN_ARGUMENTS__;\r\n__KERNEL__;\r\n\r\nvoid main(void) {\r\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\r\n __MAIN_RESULT__;\r\n}`;\r\n","// language=GLSL\r\nexport const vertexShader = `__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nattribute vec2 aPos;\r\nattribute vec2 aTexCoord;\r\n\r\nvarying vec2 vTexCoord;\r\nuniform vec2 ratio;\r\n\r\nvoid main(void) {\r\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\r\n vTexCoord = aTexCoord;\r\n}`;\r\n","/**\n *\n * @param {WebGLRenderingContext} gl\n * @param {IGLWiretapOptions} [options]\n * @returns {GLWiretapProxy}\n */\nfunction glWiretap(gl, options = {}) {\n const {\n contextName = 'gl',\n throwGetError,\n useTrackablePrimitives,\n readPixelsFile,\n recording = [],\n variables = {},\n onReadPixels,\n onUnrecognizedArgumentLookup,\n } = options;\n const proxy = new Proxy(gl, { get: listen });\n const contextVariables = [];\n const entityNames = {};\n let imageCount = 0;\n let indent = '';\n let readPixelsVariableName;\n return proxy;\n function listen(obj, property) {\n switch (property) {\n case 'addComment': return addComment;\n case 'checkThrowError': return checkThrowError;\n case 'getReadPixelsVariableName': return readPixelsVariableName;\n case 'insertVariable': return insertVariable;\n case 'reset': return reset;\n case 'setIndent': return setIndent;\n case 'toString': return toString;\n case 'getContextVariableName': return getContextVariableName;\n }\n if (typeof gl[property] === 'function') {\n return function() { // need arguments from this, fyi\n switch (property) {\n case 'getError':\n if (throwGetError) {\n recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`);\n } else {\n recording.push(`${indent}${contextName}.getError();`); // flush out errors\n }\n return gl.getError();\n case 'getExtension': {\n const variableName = `${contextName}Variables${contextVariables.length}`;\n recording.push(`${indent}const ${variableName} = ${contextName}.getExtension('${arguments[0]}');`);\n const extension = gl.getExtension(arguments[0]);\n if (extension && typeof extension === 'object') {\n const tappedExtension = glExtensionWiretap(extension, {\n getEntity,\n useTrackablePrimitives,\n recording,\n contextName: variableName,\n contextVariables,\n variables,\n indent,\n onUnrecognizedArgumentLookup,\n });\n contextVariables.push(tappedExtension);\n return tappedExtension;\n } else {\n contextVariables.push(null);\n }\n return extension;\n }\n case 'readPixels':\n const i = contextVariables.indexOf(arguments[6]);\n let targetVariableName;\n if (i === -1) {\n const variableName = getVariableName(arguments[6]);\n if (variableName) {\n targetVariableName = variableName;\n recording.push(`${indent}${variableName}`);\n } else {\n targetVariableName = `${contextName}Variable${contextVariables.length}`;\n contextVariables.push(arguments[6]);\n recording.push(`${indent}const ${targetVariableName} = new ${arguments[6].constructor.name}(${arguments[6].length});`);\n }\n } else {\n targetVariableName = `${contextName}Variable${i}`;\n }\n readPixelsVariableName = targetVariableName;\n const argumentAsStrings = [\n arguments[0],\n arguments[1],\n arguments[2],\n arguments[3],\n getEntity(arguments[4]),\n getEntity(arguments[5]),\n targetVariableName\n ];\n recording.push(`${indent}${contextName}.readPixels(${argumentAsStrings.join(', ')});`);\n if (readPixelsFile) {\n writePPM(arguments[2], arguments[3]);\n }\n if (onReadPixels) {\n onReadPixels(targetVariableName, argumentAsStrings);\n }\n return gl.readPixels.apply(gl, arguments);\n case 'drawBuffers':\n recording.push(`${indent}${contextName}.drawBuffers([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup } )}]);`);\n return gl.drawBuffers(arguments[0]);\n }\n let result = gl[property].apply(gl, arguments);\n switch (typeof result) {\n case 'undefined':\n recording.push(`${indent}${methodCallToString(property, arguments)};`);\n return;\n case 'number':\n case 'boolean':\n if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result = trackablePrimitive(result));\n break;\n }\n default:\n if (result === null) {\n recording.push(`${methodCallToString(property, arguments)};`);\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n }\n\n contextVariables.push(result);\n }\n return result;\n }\n }\n entityNames[gl[property]] = property;\n return gl[property];\n }\n function toString() {\n return recording.join('\\n');\n }\n function reset() {\n while (recording.length > 0) {\n recording.pop();\n }\n }\n function insertVariable(name, value) {\n variables[name] = value;\n }\n function getEntity(value) {\n const name = entityNames[value];\n if (name) {\n return contextName + '.' + name;\n }\n return value;\n }\n function setIndent(spaces) {\n indent = ' '.repeat(spaces);\n }\n function addVariable(value, source) {\n const variableName = `${contextName}Variable${contextVariables.length}`;\n recording.push(`${indent}const ${variableName} = ${source};`);\n contextVariables.push(value);\n return variableName;\n }\n function writePPM(width, height) {\n const sourceVariable = `${contextName}Variable${contextVariables.length}`;\n const imageVariable = `imageDatum${imageCount}`;\n recording.push(`${indent}let ${imageVariable} = [\"P3\\\\n# ${readPixelsFile}.ppm\\\\n\", ${width}, ' ', ${height}, \"\\\\n255\\\\n\"].join(\"\");`);\n recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`);\n recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`);\n recording.push(`${indent}}`);\n recording.push(`${indent}if (typeof require !== \"undefined\") {`);\n recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`);\n recording.push(`${indent}}`);\n imageCount++;\n }\n function addComment(value) {\n recording.push(`${indent}// ${value}`);\n }\n function checkThrowError() {\n recording.push(`${indent}(() => {\n${indent}const error = ${contextName}.getError();\n${indent}if (error !== ${contextName}.NONE) {\n${indent} const names = Object.getOwnPropertyNames(gl);\n${indent} for (let i = 0; i < names.length; i++) {\n${indent} const name = names[i];\n${indent} if (${contextName}[name] === error) {\n${indent} throw new Error('${contextName} threw ' + name);\n${indent} }\n${indent} }\n${indent}}\n${indent}})();`);\n }\n function methodCallToString(method, args) {\n return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;\n }\n\n function getVariableName(value) {\n if (variables) {\n for (const name in variables) {\n if (variables[name] === value) {\n return name;\n }\n }\n }\n return null;\n }\n\n function getContextVariableName(value) {\n const i = contextVariables.indexOf(value);\n if (i !== -1) {\n return `${contextName}Variable${i}`;\n }\n return null;\n }\n}\n\n/**\n *\n * @param extension\n * @param {IGLExtensionWiretapOptions} options\n * @returns {*}\n */\nfunction glExtensionWiretap(extension, options) {\n const proxy = new Proxy(extension, { get: listen });\n const extensionEntityNames = {};\n const {\n contextName,\n contextVariables,\n getEntity,\n useTrackablePrimitives,\n recording,\n variables,\n indent,\n onUnrecognizedArgumentLookup,\n } = options;\n return proxy;\n function listen(obj, property) {\n if (typeof obj[property] === 'function') {\n return function() {\n switch (property) {\n case 'drawBuffersWEBGL':\n recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`);\n return extension.drawBuffersWEBGL(arguments[0]);\n }\n let result = extension[property].apply(extension, arguments);\n switch (typeof result) {\n case 'undefined':\n recording.push(`${indent}${methodCallToString(property, arguments)};`);\n return;\n case 'number':\n case 'boolean':\n if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result = trackablePrimitive(result));\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n contextVariables.push(result);\n }\n break;\n default:\n if (result === null) {\n recording.push(`${methodCallToString(property, arguments)};`);\n } else {\n recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`);\n }\n contextVariables.push(result);\n }\n return result;\n };\n }\n extensionEntityNames[extension[property]] = property;\n return extension[property];\n }\n\n function getExtensionEntity(value) {\n if (extensionEntityNames.hasOwnProperty(value)) {\n return `${contextName}.${extensionEntityNames[value]}`;\n }\n return getEntity(value);\n }\n\n function methodCallToString(method, args) {\n return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`;\n }\n\n function addVariable(value, source) {\n const variableName = `${contextName}Variable${contextVariables.length}`;\n contextVariables.push(value);\n recording.push(`${indent}const ${variableName} = ${source};`);\n return variableName;\n }\n}\n\nfunction argumentsToString(args, options) {\n const { variables, onUnrecognizedArgumentLookup } = options;\n return (Array.from(args).map((arg) => {\n const variableName = getVariableName(arg);\n if (variableName) {\n return variableName;\n }\n return argumentToString(arg, options);\n }).join(', '));\n\n function getVariableName(value) {\n if (variables) {\n for (const name in variables) {\n if (!variables.hasOwnProperty(name)) continue;\n if (variables[name] === value) {\n return name;\n }\n }\n }\n if (onUnrecognizedArgumentLookup) {\n return onUnrecognizedArgumentLookup(value);\n }\n return null;\n }\n}\n\nfunction argumentToString(arg, options) {\n const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options;\n if (typeof arg === 'undefined') {\n return 'undefined';\n }\n if (arg === null) {\n return 'null';\n }\n const i = contextVariables.indexOf(arg);\n if (i > -1) {\n return `${contextName}Variable${i}`;\n }\n switch (arg.constructor.name) {\n case 'String':\n const hasLines = /\\n/.test(arg);\n const hasSingleQuotes = /'/.test(arg);\n const hasDoubleQuotes = /\"/.test(arg);\n if (hasLines) {\n return '`' + arg + '`';\n } else if (hasSingleQuotes && !hasDoubleQuotes) {\n return '\"' + arg + '\"';\n } else if (!hasSingleQuotes && hasDoubleQuotes) {\n return \"'\" + arg + \"'\";\n } else {\n return '\\'' + arg + '\\'';\n }\n case 'Number': return getEntity(arg);\n case 'Boolean': return getEntity(arg);\n case 'Array':\n return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`);\n case 'Float32Array':\n case 'Uint8Array':\n case 'Uint16Array':\n case 'Int32Array':\n return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`);\n default:\n if (onUnrecognizedArgumentLookup) {\n const instantiationString = onUnrecognizedArgumentLookup(arg);\n if (instantiationString) {\n return instantiationString;\n }\n }\n throw new Error(`unrecognized argument type ${arg.constructor.name}`);\n }\n}\n\nfunction trackablePrimitive(value) {\n // wrapped in object, so track-able\n return new value.constructor(value);\n}\n\nif (typeof module !== 'undefined') {\n module.exports = { glWiretap, glExtensionWiretap };\n}\n\nif (typeof window !== 'undefined') {\n glWiretap.glExtensionWiretap = glExtensionWiretap;\n window.glWiretap = glWiretap;\n}\n","import { glWiretap } from 'gl-wiretap';\r\nimport { utils } from '../../utils';\r\n\r\nfunction toStringWithoutUtils(fn) {\r\n return fn.toString()\r\n .replace('=>', '')\r\n .replace(/^function /, '')\r\n .replace(/utils[.]/g, '/*utils.*/');\r\n}\r\n\r\n/**\r\n *\r\n * @param {Kernel} Kernel\r\n * @param {KernelVariable[]} args\r\n * @param {Kernel} originKernel\r\n * @param {string} [setupContextString]\r\n * @param {string} [destroyContextString]\r\n * @returns {string}\r\n */\r\nexport function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) {\r\n args = args ? Array.from(args).map(arg => {\r\n switch (typeof arg) {\r\n case 'boolean':\r\n return new Boolean(arg);\r\n case 'number':\r\n return new Number(arg);\r\n default:\r\n return arg;\r\n }\r\n }) : null;\r\n const uploadedValues = [];\r\n const postResult = [];\r\n const context = glWiretap(originKernel.context, {\r\n useTrackablePrimitives: true,\r\n onReadPixels: (targetName) => {\r\n if (kernel.subKernels) {\r\n if (!subKernelsResultVariableSetup) {\r\n postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`);\r\n subKernelsResultVariableSetup = true;\r\n } else {\r\n const property = kernel.subKernels[subKernelsResultIndex++].property;\r\n postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`);\r\n }\r\n if (subKernelsResultIndex === kernel.subKernels.length) {\r\n postResult.push(' return result;');\r\n }\r\n return;\r\n }\r\n if (targetName) {\r\n postResult.push(` return ${getRenderString(targetName, kernel)};`);\r\n } else {\r\n postResult.push(` return null;`);\r\n }\r\n },\r\n onUnrecognizedArgumentLookup: (argument) => {\r\n const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues);\r\n if (argumentName) {\r\n return argumentName;\r\n }\r\n const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues);\r\n if (constantName) {\r\n return constantName;\r\n }\r\n return null;\r\n }\r\n });\r\n let subKernelsResultVariableSetup = false;\r\n let subKernelsResultIndex = 0;\r\n const {\r\n source,\r\n canvas,\r\n output,\r\n pipeline,\r\n graphical,\r\n loopMaxIterations,\r\n constants,\r\n optimizeFloatMemory,\r\n precision,\r\n fixIntegerDivisionAccuracy,\r\n functions,\r\n nativeFunctions,\r\n subKernels,\r\n immutable,\r\n argumentTypes,\r\n constantTypes,\r\n kernelArguments,\r\n kernelConstants,\r\n } = originKernel;\r\n const kernel = new Kernel(source, {\r\n canvas,\r\n context,\r\n checkContext: false,\r\n output,\r\n pipeline,\r\n graphical,\r\n loopMaxIterations,\r\n constants,\r\n optimizeFloatMemory,\r\n precision,\r\n fixIntegerDivisionAccuracy,\r\n functions,\r\n nativeFunctions,\r\n subKernels,\r\n immutable,\r\n argumentTypes,\r\n constantTypes,\r\n });\r\n let result = [];\r\n context.setIndent(2);\r\n kernel.build.apply(kernel, args);\r\n result.push(context.toString());\r\n context.reset();\r\n\r\n kernel.kernelArguments.forEach((kernelArgument, i) => {\r\n switch (kernelArgument.type) {\r\n // primitives\r\n case 'Integer':\r\n case 'Boolean':\r\n case 'Number':\r\n case 'Float':\r\n // non-primitives\r\n case 'Array':\r\n case 'Array(2)':\r\n case 'Array(3)':\r\n case 'Array(4)':\r\n case 'HTMLImage':\r\n case 'HTMLVideo':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);\r\n break;\r\n case 'HTMLImageArray':\r\n for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) {\r\n const arg = args[i];\r\n context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]);\r\n }\r\n break;\r\n case 'Input':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue);\r\n break;\r\n case 'MemoryOptimizedNumberTexture':\r\n case 'NumberTexture':\r\n case 'Array1D(2)':\r\n case 'Array1D(3)':\r\n case 'Array1D(4)':\r\n case 'Array2D(2)':\r\n case 'Array2D(3)':\r\n case 'Array2D(4)':\r\n case 'Array3D(2)':\r\n case 'Array3D(3)':\r\n case 'Array3D(4)':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture);\r\n break;\r\n default:\r\n throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`);\r\n }\r\n });\r\n result.push('/** start of injected functions **/');\r\n result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`);\r\n result.push(`function ${toStringWithoutUtils(utils.isArray)}`);\r\n if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) {\r\n result.push(\r\n ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};`\r\n );\r\n }\r\n result.push('/** end of injected functions **/');\r\n result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`);\r\n context.setIndent(4);\r\n kernel.run.apply(kernel, args);\r\n if (kernel.renderKernels) {\r\n kernel.renderKernels();\r\n } else if (kernel.renderOutput) {\r\n kernel.renderOutput();\r\n }\r\n result.push(' /** start setup uploads for kernel values **/');\r\n kernel.kernelArguments.forEach(kernelArgument => {\r\n result.push(' ' + kernelArgument.getStringValueHandler().split('\\n').join('\\n '));\r\n });\r\n result.push(' /** end setup uploads for kernel values **/');\r\n result.push(context.toString());\r\n if (kernel.renderOutput === kernel.renderTexture) {\r\n context.reset();\r\n const results = kernel.renderKernels();\r\n const textureName = context.getContextVariableName(kernel.outputTexture);\r\n result.push(` return {\r\n result: {\r\n texture: ${ textureName },\r\n type: '${ results.result.type }',\r\n toArray: ${ getToArrayString(results.result, textureName) }\r\n },`);\r\n const { subKernels, subKernelOutputTextures } = kernel;\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const texture = subKernelOutputTextures[i];\r\n const subKernel = subKernels[i];\r\n const subKernelResult = results[subKernel.property];\r\n const subKernelTextureName = context.getContextVariableName(texture);\r\n result.push(`\r\n ${subKernel.property}: {\r\n texture: ${ subKernelTextureName },\r\n type: '${ subKernelResult.type }',\r\n toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) }\r\n },`);\r\n }\r\n result.push(` };`);\r\n }\r\n result.push(` ${destroyContextString ? '\\n' + destroyContextString + ' ': ''}`);\r\n result.push(postResult.join('\\n'));\r\n result.push(' };');\r\n if (kernel.graphical) {\r\n result.push(getGetPixelsString(kernel));\r\n result.push(` innerKernel.getPixels = getPixels;`);\r\n }\r\n result.push(' return innerKernel;');\r\n\r\n let constantsUpload = [];\r\n kernelConstants.forEach((kernelConstant) => {\r\n constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`);\r\n });\r\n return `function kernel(settings) {\r\n const { context, constants } = settings;\r\n ${constantsUpload.join('')}\r\n ${setupContextString ? setupContextString : ''}\r\n${result.join('\\n')}\r\n}`;\r\n}\r\n\r\nfunction getRenderString(targetName, kernel) {\r\n const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`;\r\n if (kernel.output[2]) {\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`;\r\n }\r\n if (kernel.output[1]) {\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`;\r\n }\r\n\r\n return `renderOutput(${readBackValue}, ${kernel.output[0]})`;\r\n}\r\n\r\nfunction getGetPixelsString(kernel) {\r\n const getPixels = kernel.getPixels.toString();\r\n const useFunctionKeyword = !/^function/.test(getPixels);\r\n return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, {\r\n findDependency: (object, name) => {\r\n if (object === 'utils') {\r\n return `const ${name} = ${utils[name].toString()};`;\r\n }\r\n return null;\r\n },\r\n thisLookup: (property) => {\r\n if (property === 'context') {\r\n return null;\r\n }\r\n if (kernel.hasOwnProperty(property)) {\r\n return JSON.stringify(kernel[property]);\r\n }\r\n throw new Error(`unhandled thisLookup ${ property }`);\r\n }\r\n });\r\n}\r\n\r\nfunction getToArrayString(kernelResult, textureName) {\r\n const toArray = kernelResult.toArray.toString();\r\n const useFunctionKeyword = !/^function/.test(toArray);\r\n const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, {\r\n findDependency: (object, name) => {\r\n if (object === 'utils') {\r\n return `const ${name} = ${utils[name].toString()};`;\r\n } else if (object === 'this') {\r\n return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`;\r\n } else {\r\n throw new Error('unhandled fromObject');\r\n }\r\n },\r\n thisLookup: (property) => {\r\n if (property === 'texture') {\r\n return textureName;\r\n }\r\n if (kernelResult.hasOwnProperty(property)) {\r\n return JSON.stringify(kernelResult[property]);\r\n }\r\n throw new Error(`unhandled thisLookup ${ property }`);\r\n }\r\n });\r\n return `() => {\r\n ${flattenedFunctions}\r\n return toArray();\r\n }`;\r\n}\r\n\r\n/**\r\n *\r\n * @param {KernelVariable} argument\r\n * @param {KernelValue[]} kernelValues\r\n * @param {KernelVariable[]} values\r\n * @param context\r\n * @param {KernelVariable[]} uploadedValues\r\n * @return {string|null}\r\n */\r\nfunction findKernelValue(argument, kernelValues, values, context, uploadedValues) {\r\n if (argument === null) return null;\r\n switch (typeof argument) {\r\n case 'boolean':\r\n case 'number':\r\n return null;\r\n }\r\n if (\r\n typeof HTMLImageElement !== 'undefined' &&\r\n argument instanceof HTMLImageElement\r\n ) {\r\n for (let i = 0; i < kernelValues.length; i++) {\r\n const kernelValue = kernelValues[i];\r\n if (kernelValue.type !== 'HTMLImageArray') continue;\r\n if (kernelValue.uploadValue !== argument) continue;\r\n // TODO: if we send two of the same image, the parser could get confused, and short circuit to the first, handle that here\r\n const variableIndex = values[i].indexOf(argument);\r\n if (variableIndex === -1) continue;\r\n const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`;\r\n context.insertVariable(variableName, argument);\r\n return variableName;\r\n }\r\n return null;\r\n }\r\n\r\n for (let i = 0; i < kernelValues.length; i++) {\r\n const kernelValue = kernelValues[i];\r\n if (argument !== kernelValue.uploadValue) continue;\r\n const variable = `uploadValue_${kernelValue.name}`;\r\n context.insertVariable(variable, kernelValue);\r\n return variable;\r\n }\r\n return null;\r\n}\r\n","/**\r\n * @class KernelValue\r\n */\r\nexport class KernelValue {\r\n /**\r\n *\r\n * @param {KernelVariable} value\r\n * @param {IKernelValueSettings} settings\r\n */\r\n constructor(value, settings) {\r\n const {\r\n name,\r\n kernel,\r\n context,\r\n checkContext,\r\n onRequestContextHandle,\r\n onUpdateValueMismatch,\r\n origin,\r\n strictIntegers,\r\n type,\r\n tactic,\r\n } = settings;\r\n if (!name) {\r\n throw new Error('name not set');\r\n }\r\n if (!type) {\r\n throw new Error('type not set');\r\n }\r\n if (!origin) {\r\n throw new Error('origin not set');\r\n }\r\n if (!tactic) {\r\n throw new Error('tactic not set');\r\n }\r\n if (origin !== 'user' && origin !== 'constants') {\r\n throw new Error(`origin must be \"user\" or \"constants\" value is \"${ origin }\"`);\r\n }\r\n if (!onRequestContextHandle) {\r\n throw new Error('onRequestContextHandle is not set');\r\n }\r\n this.name = name;\r\n this.origin = origin;\r\n this.tactic = tactic;\r\n this.id = `${this.origin}_${name}`;\r\n this.varName = origin === 'constants' ? `constants.${name}` : name;\r\n this.kernel = kernel;\r\n this.strictIntegers = strictIntegers;\r\n // handle textures\r\n this.type = value.type || type;\r\n this.size = value.size || null;\r\n this.index = null;\r\n this.context = context;\r\n this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true;\r\n this.contextHandle = null;\r\n this.onRequestContextHandle = onRequestContextHandle;\r\n this.onUpdateValueMismatch = onUpdateValueMismatch;\r\n this.forceUploadEachRun = null;\r\n }\r\n\r\n getSource() {\r\n throw new Error(`\"getSource\" not defined on ${ this.constructor.name }`);\r\n }\r\n\r\n updateValue(value) {\r\n throw new Error(`\"updateValue\" not defined on ${ this.constructor.name }`);\r\n }\r\n}\r\n","import { Input } from '../../../input';\r\nimport { KernelValue } from '../../kernel-value';\r\nimport { utils } from '../../../utils';\r\n\r\nexport class WebGLKernelValue extends KernelValue {\r\n /**\r\n * @param {KernelVariable} value\r\n * @param {IWebGLKernelValueSettings} settings\r\n */\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.dimensionsId = null;\r\n this.sizeId = null;\r\n this.initialValueConstructor = value.constructor;\r\n this.onRequestTexture = settings.onRequestTexture;\r\n this.onRequestIndex = settings.onRequestIndex;\r\n this.uploadValue = null;\r\n this.textureSize = null;\r\n this.bitRatio = null;\r\n }\r\n\r\n /**\r\n *\r\n * @param {number} width\r\n * @param {number} height\r\n */\r\n checkSize(width, height) {\r\n if (!this.kernel.validate) return;\r\n const { maxTextureSize } = this.kernel.constructor.features;\r\n if (width > maxTextureSize || height > maxTextureSize) {\r\n if (width > height) {\r\n throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`);\r\n } else {\r\n throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`);\r\n }\r\n }\r\n }\r\n\r\n requestTexture() {\r\n this.texture = this.onRequestTexture();\r\n this.setupTexture();\r\n }\r\n\r\n setupTexture() {\r\n this.contextHandle = this.onRequestContextHandle();\r\n this.index = this.onRequestIndex();\r\n this.dimensionsId = this.id + 'Dim';\r\n this.sizeId = this.id + 'Size';\r\n }\r\n\r\n getTransferArrayType(value) {\r\n if (Array.isArray(value[0])) {\r\n return this.getTransferArrayType(value[0]);\r\n }\r\n switch (value.constructor) {\r\n case Array:\r\n case Int32Array:\r\n case Int16Array:\r\n case Int8Array:\r\n return Float32Array;\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Uint16Array:\r\n case Uint32Array:\r\n case Float32Array:\r\n case Float64Array:\r\n return value.constructor;\r\n }\r\n console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros');\r\n return value.constructor;\r\n }\r\n /**\r\n * @desc Adds kernel parameters to the Value Texture,\r\n * binding it to the context, etc.\r\n *\r\n * @param {Array|Float32Array|Uint16Array} value - The actual Value supplied to the kernel\r\n * @param {Number} length - the expected total length of the output array\r\n * @param {Object} [Type]\r\n * @returns {Float32Array|Uint16Array|Uint8Array} flattened array to transfer\r\n */\r\n formatArrayTransfer(value, length, Type) {\r\n if (utils.isArray(value[0]) || this.optimizeFloatMemory) {\r\n // not already flat\r\n const valuesFlat = new Float32Array(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n } else {\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n case Uint16Array:\r\n case Int16Array:\r\n case Float32Array:\r\n case Int32Array: {\r\n const valuesFlat = new(Type || value.constructor)(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n }\r\n default: {\r\n const valuesFlat = new Float32Array(length);\r\n utils.flattenTo(value, valuesFlat);\r\n return valuesFlat;\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4\r\n * @param value\r\n * @returns {number}\r\n */\r\n getBitRatio(value) {\r\n if (Array.isArray(value[0])) {\r\n return this.getBitRatio(value[0]);\r\n } else if (value.constructor === Input) {\r\n return this.getBitRatio(value.value);\r\n }\r\n switch (value.constructor) {\r\n case Uint8ClampedArray:\r\n case Uint8Array:\r\n case Int8Array:\r\n return 1;\r\n case Uint16Array:\r\n case Int16Array:\r\n return 2;\r\n case Float32Array:\r\n case Int32Array:\r\n default:\r\n return 4;\r\n }\r\n }\r\n\r\n /**\r\n * Used for when we want a string output of our kernel, so we can still input values to the kernel\r\n */\r\n getStringValueHandler() {\r\n throw new Error(`\"getStringValueHandler\" not implemented on ${this.constructor.name}`);\r\n }\r\n\r\n getVariablePrecisionString() {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'lowp';\r\n case 'performance':\r\n return 'highp';\r\n case 'balanced':\r\n default:\r\n return 'mediump';\r\n }\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueBoolean extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const bool ${this.id} = ${value};\\n`;\r\n }\r\n return `uniform bool ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueFloat extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n if (Number.isInteger(value)) {\r\n return `const float ${this.id} = ${value}.0;\\n`;\r\n }\r\n return `const float ${this.id} = ${value};\\n`;\r\n }\r\n return `uniform float ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1f(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueInteger extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const int ${this.id} = ${ parseInt(value) };\\n`;\r\n }\r\n return `uniform int ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueHTMLImage extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const { width, height } = value;\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, 1];\r\n this.requestTexture();\r\n this.textureSize = [width, height];\r\n this.uploadValue = value;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputImage) {\r\n if (inputImage.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n const { width, height } = value;\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, 1];\r\n this.textureSize = [width, height];\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {}\r\n","import { WebGLKernelValueDynamicHTMLImage } from './dynamic-html-image';\r\n\r\nexport class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleInput extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}.value, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n if (input.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueUnsignedInput extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = this.getBitRatio(value);\r\n const [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n this.TranserArrayType = this.getTransferArrayType(value.value);\r\n this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,\r\n `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,\r\n `flattenTo(${this.varName}.value, preUploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n if (input.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.preUploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedInput } from './unsigned-input';\r\n\r\nexport class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n const Type = this.getTransferArrayType(value.value);\r\n this.preUploadValue = new Type(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const [width, height] = value.size;\r\n this.checkSize(width, height);\r\n this.setupTexture();\r\n this.dimensions = value.dimensions;\r\n this.textureSize = value.size;\r\n this.uploadValue = value.texture;\r\n this.forceUploadEachRun = true;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName}.texture;\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n if (inputTexture.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n if (this.checkContext && inputTexture.context !== this.context) {\r\n throw new Error(`Value ${this.name} (${this.type }) must be from same context`);\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from './memory-optimized-number-texture';\r\n\r\nexport class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n this.checkSize(inputTexture.size[0], inputTexture.size[1]);\r\n this.dimensions = inputTexture.dimensions;\r\n this.textureSize = inputTexture.size;\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(inputTexture);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueNumberTexture extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n const [width, height] = value.size;\r\n this.checkSize(width, height);\r\n this.setupTexture();\r\n const { size: textureSize, dimensions } = value;\r\n this.bitRatio = this.getBitRatio(value);\r\n this.dimensions = dimensions;\r\n this.textureSize = textureSize;\r\n this.uploadValue = value.texture;\r\n this.forceUploadEachRun = true;\r\n }\r\n\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName}.texture;\\n`;\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(inputTexture) {\r\n if (inputTexture.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n if (this.checkContext && inputTexture.context !== this.context) {\r\n throw new Error(`Value ${this.name} (${this.type}) must be from same context`);\r\n }\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueNumberTexture } from './number-texture';\r\n\r\nexport class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = value.dimensions;\r\n this.checkSize(value.size[0], value.size[1]);\r\n this.textureSize = value.size;\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray1DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], 1, 1]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten2dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray1DI } from './single-array1d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray2DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten3dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray2DI } from './single-array2d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray3DI extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = 4;\r\n this.setShape(value);\r\n }\r\n\r\n setShape(value) {\r\n const valueDimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio);\r\n this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`,\r\n `flattenTo(${this.varName}, uploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flatten4dArrayTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray3DI } from './single-array3d-i';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray2 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\\n`;\r\n }\r\n return `uniform vec2 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(2)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform2fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray3 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\\n`;\r\n }\r\n return `uniform vec3 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(3)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform3fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueSingleArray4 extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.uploadValue = value;\r\n }\r\n getSource(value) {\r\n if (this.origin === 'constants') {\r\n return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\\n`;\r\n }\r\n return `uniform vec4 ${this.id};\\n`;\r\n }\r\n\r\n getStringValueHandler() {\r\n // resetting isn't supported for Array(4)\r\n if (this.origin === 'constants') return '';\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform4fv(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from './index';\r\n\r\nexport class WebGLKernelValueUnsignedArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.requestTexture();\r\n this.bitRatio = this.getBitRatio(value);\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n this.TranserArrayType = this.getTransferArrayType(value);\r\n this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n }\r\n\r\n getStringValueHandler() {\r\n return utils.linesToString([\r\n `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`,\r\n `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`,\r\n `flattenTo(${this.varName}, preUploadValue_${this.name})`,\r\n ]);\r\n }\r\n\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.preUploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedArray } from './unsigned-array';\r\n\r\nexport class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio);\r\n this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio));\r\n const Type = this.getTransferArrayType(value);\r\n this.preUploadValue = new Type(this.uploadArrayLength);\r\n this.uploadValue = new Uint8Array(this.preUploadValue.buffer);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueBoolean } from './kernel-value/boolean';\r\nimport { WebGLKernelValueFloat } from './kernel-value/float';\r\nimport { WebGLKernelValueInteger } from './kernel-value/integer';\r\n\r\nimport { WebGLKernelValueHTMLImage } from './kernel-value/html-image';\r\nimport { WebGLKernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image';\r\n\r\nimport { WebGLKernelValueHTMLVideo } from './kernel-value/html-video';\r\nimport { WebGLKernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video';\r\n\r\nimport { WebGLKernelValueSingleInput } from './kernel-value/single-input';\r\nimport { WebGLKernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input';\r\n\r\nimport { WebGLKernelValueUnsignedInput } from './kernel-value/unsigned-input';\r\nimport { WebGLKernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input';\r\n\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture';\r\nimport { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nimport { WebGLKernelValueNumberTexture } from './kernel-value/number-texture';\r\nimport { WebGLKernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture';\r\n\r\nimport { WebGLKernelValueSingleArray } from './kernel-value/single-array';\r\nimport { WebGLKernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array';\r\n\r\nimport { WebGLKernelValueSingleArray1DI } from './kernel-value/single-array1d-i';\r\nimport { WebGLKernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i';\r\n\r\nimport { WebGLKernelValueSingleArray2DI } from './kernel-value/single-array2d-i';\r\nimport { WebGLKernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i';\r\n\r\nimport { WebGLKernelValueSingleArray3DI } from './kernel-value/single-array3d-i';\r\nimport { WebGLKernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i';\r\n\r\nimport { WebGLKernelValueSingleArray2 } from './kernel-value/single-array2';\r\nimport { WebGLKernelValueSingleArray3 } from './kernel-value/single-array3';\r\nimport { WebGLKernelValueSingleArray4 } from './kernel-value/single-array4';\r\n\r\nimport { WebGLKernelValueUnsignedArray } from './kernel-value/unsigned-array';\r\nimport { WebGLKernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array';\r\n\r\nexport const kernelValueMaps = {\r\n unsigned: {\r\n dynamic: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Array': WebGLKernelValueDynamicUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGLKernelValueDynamicUnsignedInput,\r\n 'NumberTexture': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Array': WebGLKernelValueUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGLKernelValueUnsignedInput,\r\n 'NumberTexture': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueHTMLVideo,\r\n }\r\n },\r\n single: {\r\n dynamic: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Array': WebGLKernelValueDynamicSingleArray,\r\n 'Array(2)': WebGLKernelValueSingleArray2,\r\n 'Array(3)': WebGLKernelValueSingleArray3,\r\n 'Array(4)': WebGLKernelValueSingleArray4,\r\n 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI,\r\n 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI,\r\n 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI,\r\n 'Input': WebGLKernelValueDynamicSingleInput,\r\n 'NumberTexture': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGLKernelValueBoolean,\r\n 'Float': WebGLKernelValueFloat,\r\n 'Integer': WebGLKernelValueInteger,\r\n 'Array': WebGLKernelValueSingleArray,\r\n 'Array(2)': WebGLKernelValueSingleArray2,\r\n 'Array(3)': WebGLKernelValueSingleArray3,\r\n 'Array(4)': WebGLKernelValueSingleArray4,\r\n 'Array1D(2)': WebGLKernelValueSingleArray1DI,\r\n 'Array1D(3)': WebGLKernelValueSingleArray1DI,\r\n 'Array1D(4)': WebGLKernelValueSingleArray1DI,\r\n 'Array2D(2)': WebGLKernelValueSingleArray2DI,\r\n 'Array2D(3)': WebGLKernelValueSingleArray2DI,\r\n 'Array2D(4)': WebGLKernelValueSingleArray2DI,\r\n 'Array3D(2)': WebGLKernelValueSingleArray3DI,\r\n 'Array3D(3)': WebGLKernelValueSingleArray3DI,\r\n 'Array3D(4)': WebGLKernelValueSingleArray3DI,\r\n 'Input': WebGLKernelValueSingleInput,\r\n 'NumberTexture': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGLKernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGLKernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGLKernelValueHTMLImage,\r\n 'HTMLImageArray': false,\r\n 'HTMLVideo': WebGLKernelValueHTMLVideo,\r\n }\r\n },\r\n};\r\n\r\nexport function lookupKernelValueType(type, dynamic, precision, value) {\r\n if (!type) {\r\n throw new Error('type missing');\r\n }\r\n if (!dynamic) {\r\n throw new Error('dynamic missing');\r\n }\r\n if (!precision) {\r\n throw new Error('precision missing');\r\n }\r\n if (value.type) {\r\n type = value.type;\r\n }\r\n const types = kernelValueMaps[precision][dynamic];\r\n if (types[type] === false) {\r\n return null;\r\n } else if (types[type] === undefined) {\r\n throw new Error(`Could not find a KernelValue for ${ type }`);\r\n }\r\n return types[type];\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray } from './single-array';\r\n\r\nexport class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleInput } from './single-input';\r\n\r\nexport class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { GLKernel } from '../gl/kernel';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { WebGLFunctionNode } from './function-node';\r\nimport { utils } from '../../utils';\r\nimport triangleNoise from '../../plugins/triangle-noise';\r\nimport { fragmentShader } from './fragment-shader';\r\nimport { vertexShader } from './vertex-shader';\r\nimport { glKernelString } from '../gl/kernel-string';\r\nimport { lookupKernelValueType } from './kernel-value-maps';\r\n\r\nlet isSupported = null;\r\nlet testCanvas = null;\r\nlet testContext = null;\r\nlet testExtensions = null;\r\nlet features = null;\r\n\r\nconst plugins = [triangleNoise];\r\nconst canvases = [];\r\nconst maxTexSizes = {};\r\n\r\n/**\r\n * @desc Kernel Implementation for WebGL.\r\n *\r\n * This builds the shaders and runs them on the GPU, then outputs the result\r\n * back as float (enabled by default) and Texture.\r\n *\r\n * @prop {Object} textureCache - webGl Texture cache\r\n * @prop {Object} programUniformLocationCache - Location of program variables in memory\r\n * @prop {Object} framebuffer - Webgl frameBuffer\r\n * @prop {Object} buffer - WebGL buffer\r\n * @prop {Object} program - The webGl Program\r\n * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel\r\n * @prop {Boolean} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float\r\n * @prop {String} endianness - Endian information like Little-endian, Big-endian.\r\n * @prop {Array} argumentTypes - Types of parameters sent to the Kernel\r\n * @prop {String} compiledFragmentShader - Compiled fragment shader string\r\n * @prop {String} compiledVertexShader - Compiled Vertical shader string\r\n * @extends GLKernel\r\n */\r\nexport class WebGLKernel extends GLKernel {\r\n static get isSupported() {\r\n if (isSupported !== null) {\r\n return isSupported;\r\n }\r\n this.setupFeatureChecks();\r\n isSupported = this.isContextMatch(testContext);\r\n return isSupported;\r\n }\r\n\r\n static setupFeatureChecks() {\r\n if (typeof document !== 'undefined') {\r\n testCanvas = document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n testCanvas = new OffscreenCanvas(0, 0);\r\n }\r\n if (!testCanvas) return;\r\n testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl');\r\n if (!testContext || !testContext.getExtension) return;\r\n testExtensions = {\r\n OES_texture_float: testContext.getExtension('OES_texture_float'),\r\n OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),\r\n OES_element_index_uint: testContext.getExtension('OES_element_index_uint'),\r\n WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'),\r\n };\r\n features = this.getFeatures();\r\n }\r\n\r\n static isContextMatch(context) {\r\n if (typeof WebGLRenderingContext !== 'undefined') {\r\n return context instanceof WebGLRenderingContext;\r\n }\r\n return false;\r\n }\r\n\r\n static getFeatures() {\r\n const isDrawBuffers = this.getIsDrawBuffers();\r\n return Object.freeze({\r\n isFloatRead: this.getIsFloatRead(),\r\n isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),\r\n isTextureFloat: this.getIsTextureFloat(),\r\n isDrawBuffers,\r\n kernelMap: isDrawBuffers,\r\n channelCount: this.getChannelCount(),\r\n });\r\n }\r\n\r\n static getIsTextureFloat() {\r\n return Boolean(testExtensions.OES_texture_float);\r\n }\r\n\r\n static getIsDrawBuffers() {\r\n return Boolean(testExtensions.WEBGL_draw_buffers);\r\n }\r\n\r\n static getChannelCount() {\r\n return testExtensions.WEBGL_draw_buffers ?\r\n testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) :\r\n 1;\r\n }\r\n\r\n static lookupKernelValueType(type, dynamic, precision, value) {\r\n return lookupKernelValueType(type, dynamic, precision, value);\r\n }\r\n\r\n static get testCanvas() {\r\n return testCanvas;\r\n }\r\n\r\n static get testContext() {\r\n return testContext;\r\n }\r\n\r\n static get features() {\r\n return features;\r\n }\r\n\r\n static get fragmentShader() {\r\n return fragmentShader;\r\n }\r\n\r\n static get vertexShader() {\r\n return vertexShader;\r\n }\r\n\r\n /**\r\n *\r\n * @param {String} source\r\n * @param {IKernelSettings} settings\r\n */\r\n constructor(source, settings) {\r\n super(source, settings);\r\n this.program = null;\r\n this.pipeline = settings.pipeline;\r\n this.endianness = utils.systemEndianness();\r\n this.extensions = {};\r\n this.subKernelOutputTextures = null;\r\n this.kernelArguments = null;\r\n this.argumentTextureCount = 0;\r\n this.constantTextureCount = 0;\r\n this.compiledFragmentShader = null;\r\n this.compiledVertexShader = null;\r\n this.fragShader = null;\r\n this.vertShader = null;\r\n this.drawBuffersMap = null;\r\n this.outputTexture = null;\r\n\r\n /**\r\n *\r\n * @type {Int32Array|null}\r\n */\r\n this.maxTexSize = null;\r\n this.switchingKernels = false;\r\n this.onRequestSwitchKernel = null;\r\n\r\n this.mergeSettings(source.settings || settings);\r\n\r\n /**\r\n * The thread dimensions, x, y and z\r\n * @type {Array|null}\r\n */\r\n this.threadDim = null;\r\n this.framebuffer = null;\r\n this.buffer = null;\r\n this.textureCache = {};\r\n this.programUniformLocationCache = {};\r\n this.uniform1fCache = {};\r\n this.uniform1iCache = {};\r\n this.uniform2fCache = {};\r\n this.uniform2fvCache = {};\r\n this.uniform2ivCache = {};\r\n this.uniform3fvCache = {};\r\n this.uniform3ivCache = {};\r\n this.uniform4fvCache = {};\r\n this.uniform4ivCache = {};\r\n }\r\n\r\n initCanvas() {\r\n if (typeof document !== 'undefined') {\r\n const canvas = document.createElement('canvas');\r\n // Default width and height, to fix webgl issue in safari\r\n canvas.width = 2;\r\n canvas.height = 2;\r\n return canvas;\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n return new OffscreenCanvas(0, 0);\r\n }\r\n }\r\n\r\n initContext() {\r\n const settings = {\r\n alpha: false,\r\n depth: false,\r\n antialias: false\r\n };\r\n return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings);\r\n }\r\n\r\n initPlugins(settings) {\r\n // default plugins\r\n const pluginsToUse = [];\r\n const { source } = this;\r\n if (typeof source === 'string') {\r\n for (let i = 0; i < plugins.length; i++) {\r\n const plugin = plugins[i];\r\n if (source.match(plugin.functionMatch)) {\r\n pluginsToUse.push(plugin);\r\n }\r\n }\r\n } else if (typeof source === 'object') {\r\n // `source` is from object, json\r\n if (settings.pluginNames) { //TODO: in context of JSON support, pluginNames may not exist here\r\n for (let i = 0; i < plugins.length; i++) {\r\n const plugin = plugins[i];\r\n const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name);\r\n if (usePlugin) {\r\n pluginsToUse.push(plugin);\r\n }\r\n }\r\n }\r\n }\r\n return pluginsToUse;\r\n }\r\n\r\n initExtensions() {\r\n this.extensions = {\r\n OES_texture_float: this.context.getExtension('OES_texture_float'),\r\n OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'),\r\n OES_element_index_uint: this.context.getExtension('OES_element_index_uint'),\r\n WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'),\r\n WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.validate) {\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n return;\r\n }\r\n\r\n const { features } = this.constructor;\r\n if (this.optimizeFloatMemory === true && !features.isTextureFloat) {\r\n throw new Error('Float textures are not supported');\r\n } else if (this.precision === 'single' && !features.isFloatRead) {\r\n throw new Error('Single precision not supported');\r\n } else if (!this.graphical && this.precision === null && features.isTextureFloat) {\r\n this.precision = features.isFloatRead ? 'single' : 'unsigned';\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) {\r\n throw new Error('could not instantiate draw buffers extension');\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy === null) {\r\n this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;\r\n } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {\r\n this.fixIntegerDivisionAccuracy = false;\r\n }\r\n\r\n this.checkOutput();\r\n\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n if (argType === 'Array') {\r\n this.output = utils.getDimensions(argType);\r\n } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') {\r\n this.output = args[0].output;\r\n } else {\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n\r\n if (this.precision === 'precision') {\r\n this.precision = 'unsigned';\r\n console.warn('Cannot use graphical mode and single precision at the same time');\r\n }\r\n\r\n this.texSize = utils.clone(this.output);\r\n return;\r\n } else if (this.precision === null && features.isTextureFloat) {\r\n this.precision = 'single';\r\n }\r\n\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n\r\n this.checkTextureSize();\r\n }\r\n\r\n updateMaxTexSize() {\r\n const { texSize, canvas } = this;\r\n if (this.maxTexSize === null) {\r\n let canvasIndex = canvases.indexOf(canvas);\r\n if (canvasIndex === -1) {\r\n canvasIndex = canvases.length;\r\n canvases.push(canvas);\r\n maxTexSizes[canvasIndex] = [texSize[0], texSize[1]];\r\n }\r\n this.maxTexSize = maxTexSizes[canvasIndex];\r\n }\r\n if (this.maxTexSize[0] < texSize[0]) {\r\n this.maxTexSize[0] = texSize[0];\r\n }\r\n if (this.maxTexSize[1] < texSize[1]) {\r\n this.maxTexSize[1] = texSize[1];\r\n }\r\n }\r\n\r\n // TODO: move channel checks to new place\r\n _oldtranslateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n\r\n // need this line to automatically get returnType\r\n const translatedSource = functionBuilder.getPrototypeString('kernel');\r\n\r\n if (!this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n let requiredChannels = 0;\r\n const returnTypes = functionBuilder.getReturnTypes();\r\n for (let i = 0; i < returnTypes.length; i++) {\r\n switch (returnTypes[i]) {\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n requiredChannels++;\r\n break;\r\n case 'Array(2)':\r\n requiredChannels += 2;\r\n break;\r\n case 'Array(3)':\r\n requiredChannels += 3;\r\n break;\r\n case 'Array(4)':\r\n requiredChannels += 4;\r\n break;\r\n }\r\n }\r\n\r\n if (features && requiredChannels > features.channelCount) {\r\n throw new Error('Too many channels!');\r\n }\r\n\r\n return this.translatedSource = translatedSource;\r\n }\r\n\r\n setupArguments(args) {\r\n this.kernelArguments = [];\r\n this.argumentTextureCount = 0;\r\n const needsArgumentTypes = this.argumentTypes === null;\r\n // TODO: remove\r\n if (needsArgumentTypes) {\r\n this.argumentTypes = [];\r\n }\r\n this.argumentSizes = [];\r\n this.argumentBitRatios = [];\r\n // TODO: end remove\r\n\r\n if (args.length < this.argumentNames.length) {\r\n throw new Error('not enough arguments for kernel');\r\n } else if (args.length > this.argumentNames.length) {\r\n throw new Error('too many arguments for kernel');\r\n }\r\n\r\n const { context: gl } = this;\r\n let textureIndexes = 0;\r\n for (let index = 0; index < args.length; index++) {\r\n const value = args[index];\r\n const name = this.argumentNames[index];\r\n let type;\r\n if (needsArgumentTypes) {\r\n type = utils.getVariableType(value, this.strictIntegers);\r\n this.argumentTypes.push(type);\r\n } else {\r\n type = this.argumentTypes[index];\r\n }\r\n const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]);\r\n if (KernelValue === null) {\r\n return this.requestFallback(args);\r\n }\r\n const kernelArgument = new KernelValue(value, {\r\n name,\r\n type,\r\n tactic: this.tactic,\r\n origin: 'user',\r\n context: gl,\r\n checkContext: this.checkContext,\r\n kernel: this,\r\n strictIntegers: this.strictIntegers,\r\n onRequestTexture: () => {\r\n return this.context.createTexture();\r\n },\r\n onRequestIndex: () => {\r\n return textureIndexes++;\r\n },\r\n onUpdateValueMismatch: () => {\r\n this.switchingKernels = true;\r\n },\r\n onRequestContextHandle: () => {\r\n return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++;\r\n }\r\n });\r\n this.kernelArguments.push(kernelArgument);\r\n this.argumentSizes.push(kernelArgument.textureSize);\r\n this.argumentBitRatios[index] = kernelArgument.bitRatio;\r\n }\r\n }\r\n\r\n setupConstants(args) {\r\n const { context: gl } = this;\r\n this.kernelConstants = [];\r\n this.forceUploadKernelConstants = [];\r\n let needsConstantTypes = this.constantTypes === null;\r\n if (needsConstantTypes) {\r\n this.constantTypes = {};\r\n }\r\n this.constantBitRatios = {};\r\n let textureIndexes = 0;\r\n for (const name in this.constants) {\r\n const value = this.constants[name];\r\n let type;\r\n if (needsConstantTypes) {\r\n type = utils.getVariableType(value, this.strictIntegers);\r\n this.constantTypes[name] = type;\r\n } else {\r\n type = this.constantTypes[name];\r\n }\r\n const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value);\r\n if (KernelValue === null) {\r\n return this.requestFallback(args);\r\n }\r\n const kernelValue = new KernelValue(value, {\r\n name,\r\n type,\r\n tactic: this.tactic,\r\n origin: 'constants',\r\n context: this.context,\r\n checkContext: this.checkContext,\r\n kernel: this,\r\n strictIntegers: this.strictIntegers,\r\n onRequestTexture: () => {\r\n return this.context.createTexture();\r\n },\r\n onRequestIndex: () => {\r\n return textureIndexes++;\r\n },\r\n onRequestContextHandle: () => {\r\n return gl.TEXTURE0 + this.constantTextureCount++;\r\n }\r\n });\r\n this.constantBitRatios[name] = kernelValue.bitRatio;\r\n this.kernelConstants.push(kernelValue);\r\n if (kernelValue.forceUploadEachRun) {\r\n this.forceUploadKernelConstants.push(kernelValue);\r\n }\r\n }\r\n }\r\n\r\n build() {\r\n this.initExtensions();\r\n this.validateSettings(arguments);\r\n this.setupConstants(arguments);\r\n if (this.fallbackRequested) return;\r\n this.setupArguments(arguments);\r\n if (this.fallbackRequested) return;\r\n this.updateMaxTexSize();\r\n this.translateSource();\r\n const failureResult = this.pickRenderStrategy(arguments);\r\n if (failureResult) {\r\n return failureResult;\r\n }\r\n const { texSize, context: gl, canvas } = this;\r\n gl.enable(gl.SCISSOR_TEST);\r\n if (this.pipeline && this.precision === 'single') {\r\n gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n canvas.width = this.maxTexSize[0];\r\n canvas.height = this.maxTexSize[1];\r\n } else {\r\n gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]);\r\n canvas.width = this.maxTexSize[0];\r\n canvas.height = this.maxTexSize[1];\r\n }\r\n const threadDim = this.threadDim = Array.from(this.output);\r\n while (threadDim.length < 3) {\r\n threadDim.push(1);\r\n }\r\n\r\n const compiledVertexShader = this.getVertexShader(arguments);\r\n const vertShader = gl.createShader(gl.VERTEX_SHADER);\r\n gl.shaderSource(vertShader, compiledVertexShader);\r\n gl.compileShader(vertShader);\r\n this.vertShader = vertShader;\r\n\r\n const compiledFragmentShader = this.getFragmentShader(arguments);\r\n const fragShader = gl.createShader(gl.FRAGMENT_SHADER);\r\n gl.shaderSource(fragShader, compiledFragmentShader);\r\n gl.compileShader(fragShader);\r\n this.fragShader = fragShader;\r\n\r\n if (this.debug) {\r\n console.log('GLSL Shader Output:');\r\n console.log(compiledFragmentShader);\r\n }\r\n\r\n if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) {\r\n throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader));\r\n }\r\n if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) {\r\n throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader));\r\n }\r\n\r\n const program = this.program = gl.createProgram();\r\n gl.attachShader(program, vertShader);\r\n gl.attachShader(program, fragShader);\r\n gl.linkProgram(program);\r\n this.framebuffer = gl.createFramebuffer();\r\n this.framebuffer.width = texSize[0];\r\n this.framebuffer.height = texSize[1];\r\n\r\n const vertices = new Float32Array([-1, -1,\r\n 1, -1, -1, 1,\r\n 1, 1\r\n ]);\r\n const texCoords = new Float32Array([\r\n 0, 0,\r\n 1, 0,\r\n 0, 1,\r\n 1, 1\r\n ]);\r\n\r\n const texCoordOffset = vertices.byteLength;\r\n\r\n let buffer = this.buffer;\r\n if (!buffer) {\r\n buffer = this.buffer = gl.createBuffer();\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\r\n gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW);\r\n } else {\r\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\r\n }\r\n\r\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices);\r\n gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords);\r\n\r\n const aPosLoc = gl.getAttribLocation(this.program, 'aPos');\r\n gl.enableVertexAttribArray(aPosLoc);\r\n gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0);\r\n const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord');\r\n gl.enableVertexAttribArray(aTexCoordLoc);\r\n gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n\r\n let i = 0;\r\n gl.useProgram(this.program);\r\n for (let p in this.constants) {\r\n this.kernelConstants[i++].updateValue(this.constants[p]);\r\n }\r\n\r\n if (!this.immutable) {\r\n this._setupOutputTexture();\r\n if (\r\n this.subKernels !== null &&\r\n this.subKernels.length > 0\r\n ) {\r\n this._setupSubOutputTextures();\r\n }\r\n }\r\n }\r\n\r\n translateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n this.translatedSource = functionBuilder.getPrototypeString('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (!subKernel.returnType) {\r\n subKernel.returnType = functionBuilder.getSubKernelResultType(i);\r\n }\r\n }\r\n }\r\n }\r\n\r\n run() {\r\n const { kernelArguments, forceUploadKernelConstants } = this;\r\n const texSize = this.texSize;\r\n const gl = this.context;\r\n\r\n gl.useProgram(this.program);\r\n gl.scissor(0, 0, texSize[0], texSize[1]);\r\n\r\n if (this.dynamicOutput) {\r\n this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));\r\n this.setUniform2iv('uTexSize', texSize);\r\n }\r\n\r\n this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);\r\n\r\n this.switchingKernels = false;\r\n for (let i = 0; i < forceUploadKernelConstants.length; i++) {\r\n const constant = forceUploadKernelConstants[i];\r\n constant.updateValue(this.constants[constant.name]);\r\n if (this.switchingKernels) return;\r\n }\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n kernelArguments[i].updateValue(arguments[i]);\r\n if (this.switchingKernels) return;\r\n }\r\n\r\n if (this.plugins) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.onBeforeRun) {\r\n plugin.onBeforeRun(this);\r\n }\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.pipeline) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (!this.outputTexture || this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context,\r\n });\r\n }\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return;\r\n }\r\n\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n\r\n if (this.subKernels !== null) {\r\n if (this.immutable) {\r\n this._setupSubOutputTextures();\r\n }\r\n this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap);\r\n }\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n }\r\n\r\n /**\r\n * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run()\r\n * @returns {Object} Output Texture Cache\r\n */\r\n getOutputTexture() {\r\n return this.outputTexture;\r\n }\r\n\r\n /**\r\n * @desc Setup and replace output texture\r\n */\r\n _setupOutputTexture() {\r\n const gl = this.context;\r\n const texSize = this.texSize;\r\n const texture = this.outputTexture = this.context.createTexture();\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // if (this.precision === 'single') {\r\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n // } else {\r\n // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n // }\r\n if (this.precision === 'single') {\r\n if (this.pipeline) {\r\n // TODO: investigate if webgl1 can handle gl.RED usage in gl.texImage2D, otherwise, simplify the below\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n }\r\n break;\r\n case 'Array(2)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n case 'Array(3)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n case 'Array(4)':\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n break;\r\n default:\r\n if (!this.graphical) {\r\n throw new Error('Unhandled return type');\r\n }\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n }\r\n\r\n /**\r\n * @desc Setup and replace sub-output textures\r\n */\r\n _setupSubOutputTextures() {\r\n const gl = this.context;\r\n const texSize = this.texSize;\r\n this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];\r\n this.subKernelOutputTextures = [];\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const texture = this.context.createTexture();\r\n this.subKernelOutputTextures.push(texture);\r\n this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n if (this.precision === 'single') {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);\r\n }\r\n }\r\n\r\n /**\r\n * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument)\r\n * @param {String} name - Name of the subkernel, argument, or kernel.\r\n * @returns {Object} Texture cache\r\n */\r\n getTextureCache(name) {\r\n if (this.textureCache.hasOwnProperty(name)) {\r\n return this.textureCache[name];\r\n }\r\n return this.textureCache[name] = this.context.createTexture();\r\n }\r\n\r\n /**\r\n * @desc removes a texture from the kernel's cache\r\n * @param {String} name - Name of texture\r\n */\r\n detachTextureCache(name) {\r\n delete this.textureCache[name];\r\n }\r\n\r\n setUniform1f(name, value) {\r\n if (this.uniform1fCache.hasOwnProperty(name)) {\r\n const cache = this.uniform1fCache[name];\r\n if (value === cache) {\r\n return;\r\n }\r\n }\r\n this.uniform1fCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform1f(loc, value);\r\n }\r\n\r\n setUniform1i(name, value) {\r\n if (this.uniform1iCache.hasOwnProperty(name)) {\r\n const cache = this.uniform1iCache[name];\r\n if (value === cache) {\r\n return;\r\n }\r\n }\r\n this.uniform1iCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform1i(loc, value);\r\n }\r\n\r\n setUniform2f(name, value1, value2) {\r\n if (this.uniform2fCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2fCache[name];\r\n if (\r\n value1 === cache[0] &&\r\n value2 === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2fCache[name] = [value1, value2];\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2f(loc, value1, value2);\r\n }\r\n\r\n setUniform2fv(name, value) {\r\n if (this.uniform2fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2fv(loc, value);\r\n }\r\n\r\n setUniform2iv(name, value) {\r\n if (this.uniform2ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform2ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform2ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform2iv(loc, value);\r\n }\r\n\r\n setUniform3fv(name, value) {\r\n if (this.uniform3fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3fv(loc, value);\r\n }\r\n\r\n setUniform3iv(name, value) {\r\n if (this.uniform3ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3iv(loc, value);\r\n }\r\n\r\n setUniform3fv(name, value) {\r\n if (this.uniform3fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform3fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform3fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform3fv(loc, value);\r\n }\r\n\r\n setUniform4iv(name, value) {\r\n if (this.uniform4ivCache.hasOwnProperty(name)) {\r\n const cache = this.uniform4ivCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2] &&\r\n value[3] === cache[3]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform4ivCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform4iv(loc, value);\r\n }\r\n\r\n setUniform4fv(name, value) {\r\n if (this.uniform4fvCache.hasOwnProperty(name)) {\r\n const cache = this.uniform4fvCache[name];\r\n if (\r\n value[0] === cache[0] &&\r\n value[1] === cache[1] &&\r\n value[2] === cache[2] &&\r\n value[3] === cache[3]\r\n ) {\r\n return;\r\n }\r\n }\r\n this.uniform4fvCache[name] = value;\r\n const loc = this.getUniformLocation(name);\r\n this.context.uniform4fv(loc, value);\r\n }\r\n\r\n /**\r\n * @desc Return WebGlUniformLocation for various variables\r\n * related to webGl program, such as user-defined variables,\r\n * as well as, dimension sizes, etc.\r\n */\r\n getUniformLocation(name) {\r\n if (this.programUniformLocationCache.hasOwnProperty(name)) {\r\n return this.programUniformLocationCache[name];\r\n }\r\n return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name);\r\n }\r\n\r\n /**\r\n * @desc Generate Shader artifacts for the kernel program.\r\n * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)\r\n */\r\n _getFragShaderArtifactMap(args) {\r\n return {\r\n HEADER: this._getHeaderString(),\r\n LOOP_MAX: this._getLoopMaxString(),\r\n PLUGINS: this._getPluginsString(),\r\n CONSTANTS: this._getConstantsString(),\r\n DECODE32_ENDIANNESS: this._getDecode32EndiannessString(),\r\n ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(),\r\n DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(),\r\n INJECTED_NATIVE: this._getInjectedNative(),\r\n MAIN_CONSTANTS: this._getMainConstantsString(),\r\n MAIN_ARGUMENTS: this._getMainArgumentsString(args),\r\n KERNEL: this.getKernelString(),\r\n MAIN_RESULT: this.getMainResultString(),\r\n FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),\r\n INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),\r\n SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),\r\n SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Generate Shader artifacts for the kernel program.\r\n * The final object contains HEADER, KERNEL, MAIN_RESULT, and others.\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.)\r\n */\r\n _getVertShaderArtifactMap(args) {\r\n return {\r\n FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(),\r\n INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(),\r\n SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(),\r\n SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Get the header string for the program.\r\n * This returns an empty string if no sub-kernels are defined.\r\n *\r\n * @returns {String} result\r\n */\r\n _getHeaderString() {\r\n return (\r\n this.subKernels !== null ?\r\n '#extension GL_EXT_draw_buffers : require\\n' :\r\n ''\r\n );\r\n }\r\n\r\n /**\r\n * @desc Get the maximum loop size String.\r\n * @returns {String} result\r\n */\r\n _getLoopMaxString() {\r\n return (\r\n this.loopMaxIterations ?\r\n ` ${parseInt(this.loopMaxIterations)};\\n` :\r\n ' 1000;\\n'\r\n );\r\n }\r\n\r\n _getPluginsString() {\r\n if (!this.plugins) return '\\n';\r\n return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\\n');\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel\r\n * @returns {String} result\r\n */\r\n _getConstantsString() {\r\n const result = [];\r\n const { threadDim, texSize } = this;\r\n if (this.dynamicOutput) {\r\n result.push(\r\n 'uniform ivec3 uOutputDim',\r\n 'uniform ivec2 uTexSize'\r\n );\r\n } else {\r\n result.push(\r\n `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`,\r\n `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})`\r\n );\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n /**\r\n * @desc Get texture coordinate string for the program\r\n * @returns {String} result\r\n */\r\n _getTextureCoordinate() {\r\n const subKernels = this.subKernels;\r\n if (subKernels === null || subKernels.length < 1) {\r\n return 'varying vec2 vTexCoord;\\n';\r\n } else {\r\n return 'out vec2 vTexCoord;\\n';\r\n }\r\n }\r\n\r\n /**\r\n * @desc Get Decode32 endianness string for little-endian and big-endian\r\n * @returns {String} result\r\n */\r\n _getDecode32EndiannessString() {\r\n return (\r\n this.endianness === 'LE' ?\r\n '' :\r\n ' texel.rgba = texel.abgr;\\n'\r\n );\r\n }\r\n\r\n /**\r\n * @desc Get Encode32 endianness string for little-endian and big-endian\r\n * @returns {String} result\r\n */\r\n _getEncode32EndiannessString() {\r\n return (\r\n this.endianness === 'LE' ?\r\n '' :\r\n ' texel.rgba = texel.abgr;\\n'\r\n );\r\n }\r\n\r\n /**\r\n * @desc if fixIntegerDivisionAccuracy provide method to replace /\r\n * @returns {String} result\r\n */\r\n _getDivideWithIntegerCheckString() {\r\n return this.fixIntegerDivisionAccuracy ?\r\n `float div_with_int_check(float x, float y) {\r\n if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) {\r\n return float(int(x)/int(y));\r\n }\r\n return x / y;\r\n}` :\r\n '';\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {String} result\r\n */\r\n _getMainArgumentsString(args) {\r\n const results = [];\r\n const { argumentNames } = this;\r\n for (let i = 0; i < argumentNames.length; i++) {\r\n results.push(this.kernelArguments[i].getSource(args[i]));\r\n }\r\n return results.join('');\r\n }\r\n\r\n _getInjectedNative() {\r\n return this.injectedNative || '';\r\n }\r\n\r\n _getMainConstantsString() {\r\n const result = [];\r\n const { constants } = this;\r\n if (constants) {\r\n let i = 0;\r\n for (const name in constants) {\r\n result.push(this.kernelConstants[i++].getSource(this.constants[name]));\r\n }\r\n }\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * @desc Get Kernel program string (in *glsl*) for a kernel.\r\n * @returns {String} result\r\n */\r\n getKernelString() {\r\n let kernelResultDeclaration;\r\n switch (this.returnType) {\r\n case 'Array(2)':\r\n kernelResultDeclaration = 'vec2 kernelResult';\r\n break;\r\n case 'Array(3)':\r\n kernelResultDeclaration = 'vec3 kernelResult';\r\n break;\r\n case 'Array(4)':\r\n kernelResultDeclaration = 'vec4 kernelResult';\r\n break;\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n kernelResultDeclaration = 'float kernelResult';\r\n break;\r\n default:\r\n if (this.graphical) {\r\n kernelResultDeclaration = 'float kernelResult';\r\n } else {\r\n throw new Error(`unrecognized output type \"${ this.returnType }\"`);\r\n }\r\n }\r\n\r\n const result = [];\r\n const subKernels = this.subKernels;\r\n if (subKernels !== null) {\r\n result.push(\r\n kernelResultDeclaration\r\n );\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const subKernel = subKernels[i];\r\n result.push(\r\n subKernel.returnType === 'Integer' ?\r\n `int subKernelResult_${ subKernel.name } = 0` :\r\n `float subKernelResult_${ subKernel.name } = 0.0`\r\n );\r\n }\r\n break;\r\n case 'Array(2)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec2 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n case 'Array(3)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec3 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n case 'Array(4)':\r\n for (let i = 0; i < subKernels.length; i++) {\r\n result.push(\r\n `vec4 subKernelResult_${ subKernels[i].name }`\r\n );\r\n }\r\n break;\r\n }\r\n } else {\r\n result.push(\r\n kernelResultDeclaration\r\n );\r\n }\r\n\r\n return utils.linesToString(result) + this.translatedSource;\r\n }\r\n\r\n getMainResultGraphical() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragColor = actualColor',\r\n ]);\r\n }\r\n\r\n getMainResultPackedPixels() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return this.getMainResultKernelPackedPixels() +\r\n this.getMainResultSubKernelPackedPixels();\r\n default:\r\n throw new Error(`packed output only usable with Numbers, \"${this.returnType}\" specified`);\r\n }\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultKernelPackedPixels() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`\r\n ]);\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultSubKernelPackedPixels() {\r\n const result = [];\r\n if (!this.subKernels) return '';\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`\r\n );\r\n }\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultMemoryOptimizedFloats() {\r\n const result = [\r\n ' index *= 4',\r\n ];\r\n\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n const channels = ['r', 'g', 'b', 'a'];\r\n for (let i = 0; i < channels.length; i++) {\r\n const channel = channels[i];\r\n this.getMainResultKernelMemoryOptimizedFloats(result, channel);\r\n this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);\r\n if (i + 1 < channels.length) {\r\n result.push(' index += 1');\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);\r\n }\r\n\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultKernelMemoryOptimizedFloats(result, channel) {\r\n result.push(\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` gl_FragData[0].${channel} = kernelResult`,\r\n );\r\n }\r\n\r\n getMainResultSubKernelMemoryOptimizedFloats(result, channel) {\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n getMainResultKernelNumberTexture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelNumberTexture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray2Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult[0]',\r\n ' gl_FragData[0][1] = kernelResult[1]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray2Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray3Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0][0] = kernelResult[0]',\r\n ' gl_FragData[0][1] = kernelResult[1]',\r\n ' gl_FragData[0][2] = kernelResult[2]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray3Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray4Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' gl_FragData[0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray4Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n }\r\n break;\r\n case 'Array(2)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n );\r\n }\r\n break;\r\n case 'Array(3)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n );\r\n }\r\n break;\r\n case 'Array(4)':\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`,\r\n ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`,\r\n ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`,\r\n ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`,\r\n );\r\n }\r\n break;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * @param {String} src - Shader string\r\n * @param {Object} map - Variables/Constants associated with shader\r\n */\r\n replaceArtifacts(src, map) {\r\n return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\\n/g, (match, artifact) => {\r\n if (map.hasOwnProperty(artifact)) {\r\n return map[artifact];\r\n }\r\n throw `unhandled artifact ${artifact}`;\r\n });\r\n }\r\n\r\n /**\r\n * @desc Get the fragment shader String.\r\n * If the String hasn't been compiled yet,\r\n * then this method compiles it as well\r\n *\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {string} Fragment Shader string\r\n */\r\n getFragmentShader(args) {\r\n if (this.compiledFragmentShader !== null) {\r\n return this.compiledFragmentShader;\r\n }\r\n return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args));\r\n }\r\n\r\n /**\r\n * @desc Get the vertical shader String\r\n * @param {Array|IArguments} args - The actual parameters sent to the Kernel\r\n * @returns {string} Vertical Shader string\r\n */\r\n getVertexShader(args) {\r\n if (this.compiledVertexShader !== null) {\r\n return this.compiledVertexShader;\r\n }\r\n return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args));\r\n }\r\n\r\n /**\r\n * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused.\r\n */\r\n toString() {\r\n const setupContextString = utils.linesToString([\r\n `const gl = context`,\r\n ]);\r\n return glKernelString(this.constructor, arguments, this, setupContextString);\r\n }\r\n\r\n destroy(removeCanvasReferences) {\r\n if (this.outputTexture) {\r\n this.context.deleteTexture(this.outputTexture);\r\n }\r\n if (this.buffer) {\r\n this.context.deleteBuffer(this.buffer);\r\n }\r\n if (this.framebuffer) {\r\n this.context.deleteFramebuffer(this.framebuffer);\r\n }\r\n if (this.vertShader) {\r\n this.context.deleteShader(this.vertShader);\r\n }\r\n if (this.fragShader) {\r\n this.context.deleteShader(this.fragShader);\r\n }\r\n if (this.program) {\r\n this.context.deleteProgram(this.program);\r\n }\r\n\r\n const keys = Object.keys(this.textureCache);\r\n\r\n for (let i = 0; i < keys.length; i++) {\r\n const name = keys[i];\r\n this.context.deleteTexture(this.textureCache[name]);\r\n }\r\n\r\n if (this.subKernelOutputTextures) {\r\n for (let i = 0; i < this.subKernelOutputTextures.length; i++) {\r\n this.context.deleteTexture(this.subKernelOutputTextures[i]);\r\n }\r\n }\r\n if (removeCanvasReferences) {\r\n const idx = canvases.indexOf(this.canvas);\r\n if (idx >= 0) {\r\n canvases[idx] = null;\r\n maxTexSizes[idx] = null;\r\n }\r\n }\r\n this.destroyExtensions();\r\n delete this.context;\r\n delete this.canvas;\r\n }\r\n\r\n destroyExtensions() {\r\n this.extensions.OES_texture_float = null;\r\n this.extensions.OES_texture_float_linear = null;\r\n this.extensions.OES_element_index_uint = null;\r\n this.extensions.WEBGL_draw_buffers = null;\r\n }\r\n\r\n static destroyContext(context) {\r\n const extension = context.getExtension('WEBGL_lose_context');\r\n if (extension) {\r\n extension.loseContext();\r\n }\r\n }\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON();\r\n return json;\r\n }\r\n}\r\n","import { WebGLFunctionNode } from '../web-gl/function-node';\r\n\r\n/**\r\n * @class WebGL2FunctionNode\r\n * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective webGL code.\r\n * @extends WebGLFunctionNode\r\n * @returns the converted webGL function string\r\n */\r\nexport class WebGL2FunctionNode extends WebGLFunctionNode {\r\n\r\n /**\r\n * @desc Parses the abstract syntax tree for *identifier* expression\r\n * @param {Object} idtNode - An ast Node\r\n * @param {Array} retArr - return array string\r\n * @returns {Array} the append retArr\r\n */\r\n astIdentifierExpression(idtNode, retArr) {\r\n if (idtNode.type !== 'Identifier') {\r\n throw this.astErrorOutput(\r\n 'IdentifierExpression - not an Identifier',\r\n idtNode\r\n );\r\n }\r\n\r\n const type = this.getType(idtNode);\r\n\r\n if (idtNode.name === 'Infinity') {\r\n retArr.push('intBitsToFloat(2139095039)');\r\n } else if (type === 'Boolean') {\r\n if (this.argumentNames.indexOf(idtNode.name) > -1) {\r\n retArr.push(`bool(user_${idtNode.name})`);\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n } else {\r\n retArr.push(`user_${idtNode.name}`);\r\n }\r\n\r\n return retArr;\r\n }\r\n}\r\n","// language=GLSL\r\nexport const fragmentShader = `#version 300 es\r\n__HEADER__;\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__;\r\n\r\nconst int LOOP_MAX = __LOOP_MAX__;\r\n\r\n__PLUGINS__;\r\n__CONSTANTS__;\r\n\r\nin vec2 vTexCoord;\r\n\r\nconst int BIT_COUNT = 32;\r\nint modi(int x, int y) {\r\n return x - y * (x / y);\r\n}\r\n\r\nint bitwiseOr(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseXOR(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 || b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseAnd(int a, int b) {\r\n int result = 0;\r\n int n = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n b = b / 2;\r\n n = n * 2;\r\n if(!(a > 0 && b > 0)) {\r\n break;\r\n }\r\n }\r\n return result;\r\n}\r\nint bitwiseNot(int a) {\r\n int result = 0;\r\n int n = 1;\r\n\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (modi(a, 2) == 0) {\r\n result += n;\r\n }\r\n a = a / 2;\r\n n = n * 2;\r\n }\r\n return result;\r\n}\r\nint bitwiseZeroFillLeftShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n *= 2;\r\n }\r\n\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nint bitwiseSignedRightShift(int num, int shifts) {\r\n return int(floor(float(num) / pow(2.0, float(shifts))));\r\n}\r\n\r\nint bitwiseZeroFillRightShift(int n, int shift) {\r\n int maxBytes = BIT_COUNT;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (maxBytes >= n) {\r\n break;\r\n }\r\n maxBytes *= 2;\r\n }\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= shift) {\r\n break;\r\n }\r\n n /= 2;\r\n }\r\n int result = 0;\r\n int byteVal = 1;\r\n for (int i = 0; i < BIT_COUNT; i++) {\r\n if (i >= maxBytes) break;\r\n if (modi(n, 2) > 0) { result += byteVal; }\r\n n = int(n / 2);\r\n byteVal *= 2;\r\n }\r\n return result;\r\n}\r\n\r\nvec2 integerMod(vec2 x, float y) {\r\n vec2 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec3 integerMod(vec3 x, float y) {\r\n vec3 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nvec4 integerMod(vec4 x, vec4 y) {\r\n vec4 res = floor(mod(x, y));\r\n return res * step(1.0 - floor(y), -res);\r\n}\r\n\r\nfloat integerMod(float x, float y) {\r\n float res = floor(mod(x, y));\r\n return res * (res > floor(y) - 1.0 ? 0.0 : 1.0);\r\n}\r\n\r\nint integerMod(int x, int y) {\r\n return x - (y * int(x/y));\r\n}\r\n\r\n__DIVIDE_WITH_INTEGER_CHECK__;\r\n\r\n// Here be dragons!\r\n// DO NOT OPTIMIZE THIS CODE\r\n// YOU WILL BREAK SOMETHING ON SOMEBODY\\'S MACHINE\r\n// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME\r\nconst vec2 MAGIC_VEC = vec2(1.0, -256.0);\r\nconst vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0);\r\nconst vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536\r\nfloat decode32(vec4 texel) {\r\n __DECODE32_ENDIANNESS__;\r\n texel *= 255.0;\r\n vec2 gte128;\r\n gte128.x = texel.b >= 128.0 ? 1.0 : 0.0;\r\n gte128.y = texel.a >= 128.0 ? 1.0 : 0.0;\r\n float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC);\r\n float res = exp2(round(exponent));\r\n texel.b = texel.b - 128.0 * gte128.x;\r\n res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res;\r\n res *= gte128.y * -2.0 + 1.0;\r\n return res;\r\n}\r\n\r\nfloat decode16(vec4 texel, int index) {\r\n int channel = integerMod(index, 2);\r\n return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0;\r\n}\r\n\r\nfloat decode8(vec4 texel, int index) {\r\n int channel = integerMod(index, 4);\r\n return texel[channel] * 255.0;\r\n}\r\n\r\nvec4 legacyEncode32(float f) {\r\n float F = abs(f);\r\n float sign = f < 0.0 ? 1.0 : 0.0;\r\n float exponent = floor(log2(F));\r\n float mantissa = (exp2(-exponent) * F);\r\n // exponent += floor(log2(mantissa));\r\n vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV;\r\n texel.rg = integerMod(texel.rg, 256.0);\r\n texel.b = integerMod(texel.b, 128.0);\r\n texel.a = exponent*0.5 + 63.5;\r\n texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0;\r\n texel = floor(texel);\r\n texel *= 0.003921569; // 1/255\r\n __ENCODE32_ENDIANNESS__;\r\n return texel;\r\n}\r\n\r\n// https://github.com/gpujs/gpu.js/wiki/Encoder-details\r\nvec4 encode32(float value) {\r\n if (value == 0.0) return vec4(0, 0, 0, 0);\r\n\r\n float exponent;\r\n float mantissa;\r\n vec4 result;\r\n float sgn;\r\n\r\n sgn = step(0.0, -value);\r\n value = abs(value);\r\n\r\n exponent = floor(log2(value));\r\n\r\n mantissa = value*pow(2.0, -exponent)-1.0;\r\n exponent = exponent+127.0;\r\n result = vec4(0,0,0,0);\r\n\r\n result.a = floor(exponent/2.0);\r\n exponent = exponent - result.a*2.0;\r\n result.a = result.a + 128.0*sgn;\r\n\r\n result.b = floor(mantissa * 128.0);\r\n mantissa = mantissa - result.b / 128.0;\r\n result.b = result.b + exponent*128.0;\r\n\r\n result.g = floor(mantissa*32768.0);\r\n mantissa = mantissa - result.g/32768.0;\r\n\r\n result.r = floor(mantissa*8388608.0);\r\n return result/255.0;\r\n}\r\n// Dragons end here\r\n\r\nint index;\r\nivec3 threadId;\r\n\r\nivec3 indexTo3D(int idx, ivec3 texDim) {\r\n int z = int(idx / (texDim.x * texDim.y));\r\n idx -= z * int(texDim.x * texDim.y);\r\n int y = int(idx / texDim.x);\r\n int x = int(integerMod(idx, texDim.x));\r\n return ivec3(x, y, z);\r\n}\r\n\r\nfloat get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return decode32(texel);\r\n}\r\n\r\nfloat get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int w = texSize.x * 2;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y));\r\n return decode16(texel, index);\r\n}\r\n\r\nfloat get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int w = texSize.x * 4;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y));\r\n return decode8(texel, index);\r\n}\r\n\r\nfloat getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + (texDim.x * (y + (texDim.y * z)));\r\n int channel = integerMod(index, 4);\r\n index = index / 4;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n index = index / 4;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return texel[channel];\r\n}\r\n\r\nvec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture(tex, st / vec2(texSize));\r\n}\r\n\r\nvec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n return texture(tex, vec3(st / vec2(texSize), z));\r\n}\r\n\r\nfloat getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return result[0];\r\n}\r\n\r\nvec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec2(result[0], result[1]);\r\n}\r\n\r\nvec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n index = index / 2;\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n if (channel == 0) return vec2(texel.r, texel.g);\r\n if (channel == 1) return vec2(texel.b, texel.a);\r\n return vec2(0.0, 0.0);\r\n}\r\n\r\nvec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n vec4 result = getImage2D(tex, texSize, texDim, z, y, x);\r\n return vec3(result[0], result[1], result[2]);\r\n}\r\n\r\nvec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z));\r\n int vectorIndex = fieldIndex / 4;\r\n int vectorOffset = fieldIndex - vectorIndex * 4;\r\n int readY = vectorIndex / texSize.x;\r\n int readX = vectorIndex - readY * texSize.x;\r\n vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize));\r\n\r\n if (vectorOffset == 0) {\r\n return tex1.xyz;\r\n } else if (vectorOffset == 1) {\r\n return tex1.yzw;\r\n } else {\r\n readX++;\r\n if (readX >= texSize.x) {\r\n readX = 0;\r\n readY++;\r\n }\r\n vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize));\r\n if (vectorOffset == 2) {\r\n return vec3(tex1.z, tex1.w, tex2.x);\r\n } else {\r\n return vec3(tex1.w, tex2.x, tex2.y);\r\n }\r\n }\r\n}\r\n\r\nvec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n return getImage2D(tex, texSize, texDim, z, y, x);\r\n}\r\n\r\nvec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) {\r\n int index = x + texDim.x * (y + texDim.y * z);\r\n int channel = integerMod(index, 2);\r\n int w = texSize.x;\r\n vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5;\r\n vec4 texel = texture(tex, st / vec2(texSize));\r\n return vec4(texel.r, texel.g, texel.b, texel.a);\r\n}\r\n\r\nvec4 actualColor;\r\nvoid color(float r, float g, float b, float a) {\r\n actualColor = vec4(r,g,b,a);\r\n}\r\n\r\nvoid color(float r, float g, float b) {\r\n color(r,g,b,1.0);\r\n}\r\n\r\n__INJECTED_NATIVE__;\r\n__MAIN_CONSTANTS__;\r\n__MAIN_ARGUMENTS__;\r\n__KERNEL__;\r\n\r\nvoid main(void) {\r\n index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x;\r\n __MAIN_RESULT__;\r\n}`;\r\n","// language=GLSL\r\nexport const vertexShader = `#version 300 es\r\n__FLOAT_TACTIC_DECLARATION__;\r\n__INT_TACTIC_DECLARATION__;\r\n__SAMPLER_2D_TACTIC_DECLARATION__;\r\n\r\nin vec2 aPos;\r\nin vec2 aTexCoord;\r\n\r\nout vec2 vTexCoord;\r\nuniform vec2 ratio;\r\n\r\nvoid main(void) {\r\n gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1);\r\n vTexCoord = aTexCoord;\r\n}`;\r\n","import { WebGLKernelValueBoolean } from '../../web-gl/kernel-value/boolean';\r\n\r\nexport class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {}\r\n","import { WebGLKernelValueFloat } from '../../web-gl/kernel-value/float';\r\n\r\nexport class WebGL2KernelValueFloat extends WebGLKernelValueFloat {}\r\n","import { WebGLKernelValueInteger } from '../../web-gl/kernel-value/integer';\r\n\r\nexport class WebGL2KernelValueInteger extends WebGLKernelValueInteger {\r\n getSource(value) {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n if (this.origin === 'constants') {\r\n return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\\n`;\r\n }\r\n return `uniform ${ variablePrecision } int ${this.id};\\n`;\r\n }\r\n\r\n updateValue(value) {\r\n if (this.origin === 'constants') return;\r\n this.kernel.setUniform1i(this.id, this.uploadValue = value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueHTMLImage } from '../../web-gl/kernel-value/html-image';\r\n\r\nexport class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicHTMLImage } from '../../web-gl/kernel-value/dynamic-html-image';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValue } from '../../web-gl/kernel-value/index';\r\n\r\nexport class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue {\r\n constructor(value, settings) {\r\n super(value, settings);\r\n this.checkSize(value[0].width, value[0].height);\r\n this.requestTexture();\r\n this.dimensions = [value[0].width, value[0].height, value.length];\r\n this.textureSize = [value[0].width, value[0].height];\r\n }\r\n getStringValueHandler() {\r\n return `const uploadValue_${this.name} = ${this.varName};\\n`;\r\n }\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2DArray ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(images) {\r\n const { context: gl } = this;\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);\r\n // Upload the images into the texture.\r\n gl.texImage3D(\r\n gl.TEXTURE_2D_ARRAY,\r\n 0,\r\n gl.RGBA,\r\n images[0].width,\r\n images[0].height,\r\n images.length,\r\n 0,\r\n gl.RGBA,\r\n gl.UNSIGNED_BYTE,\r\n null\r\n );\r\n for (let i = 0; i < images.length; i++) {\r\n const xOffset = 0;\r\n const yOffset = 0;\r\n const imageDepth = 1;\r\n gl.texSubImage3D(\r\n gl.TEXTURE_2D_ARRAY,\r\n 0,\r\n xOffset,\r\n yOffset,\r\n i,\r\n images[i].width,\r\n images[i].height,\r\n imageDepth,\r\n gl.RGBA,\r\n gl.UNSIGNED_BYTE,\r\n this.uploadValue = images[i]\r\n );\r\n }\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { WebGL2KernelValueHTMLImageArray } from './html-image-array';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2DArray ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(images) {\r\n const { width, height } = images[0];\r\n this.checkSize(width, height);\r\n this.dimensions = [width, height, images.length];\r\n this.textureSize = [width, height];\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(images);\r\n }\r\n}\r\n","import { WebGL2KernelValueHTMLImage } from './html-image';\r\n\r\nexport class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {}\r\n","import { WebGL2KernelValueDynamicHTMLImage } from './dynamic-html-image';\r\n\r\nexport class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleInput } from '../../web-gl/kernel-value/single-input';\r\n\r\nexport class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(input) {\r\n const { context: gl } = this;\r\n utils.flattenTo(input.value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nexport class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture {\r\n getSource() {\r\n return utils.linesToString([\r\n `uniform sampler2D ${this.id}`,\r\n `uniform ivec2 ${this.sizeId}`,\r\n `uniform ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueNumberTexture } from '../../web-gl/kernel-value/number-texture';\r\n\r\nexport class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture {\r\n getSource() {\r\n const { id, sizeId, textureSize, dimensionsId, dimensions } = this;\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${id}`,\r\n `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicNumberTexture } from '../../web-gl/kernel-value/dynamic-number-texture';\r\n\r\nexport class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray } from '../../web-gl/kernel-value/single-array';\r\n\r\nexport class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray1DI } from '../../web-gl/kernel-value/single-array1d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray1DI } from '../../web-gl2/kernel-value/single-array1d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray2DI } from '../../web-gl/kernel-value/single-array2d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray2DI } from '../../web-gl2/kernel-value/single-array2d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueSingleArray3DI } from '../../web-gl/kernel-value/single-array3d-i';\r\n\r\nexport class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI {\r\n updateValue(value) {\r\n if (value.constructor !== this.initialValueConstructor) {\r\n this.onUpdateValueMismatch();\r\n return;\r\n }\r\n const { context: gl } = this;\r\n utils.flattenTo(value, this.uploadValue);\r\n gl.activeTexture(this.contextHandle);\r\n gl.bindTexture(gl.TEXTURE_2D, this.texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue);\r\n this.kernel.setUniform1i(this.id, this.index);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray3DI } from '../../web-gl2/kernel-value/single-array3d-i';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.setShape(value);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { WebGLKernelValueSingleArray2 } from '../../web-gl/kernel-value/single-array2';\r\n\r\nexport class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {}\r\n","import { WebGLKernelValueSingleArray3 } from '../../web-gl/kernel-value/single-array3';\r\n\r\nexport class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {}\r\n","import { WebGLKernelValueSingleArray4 } from '../../web-gl/kernel-value/single-array4';\r\n\r\nexport class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {}\r\n","import { WebGL2KernelValueBoolean } from './kernel-value/boolean';\r\nimport { WebGL2KernelValueFloat } from './kernel-value/float';\r\nimport { WebGL2KernelValueInteger } from './kernel-value/integer';\r\n\r\nimport { WebGL2KernelValueHTMLImage } from './kernel-value/html-image';\r\nimport { WebGL2KernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image';\r\n\r\nimport { WebGL2KernelValueHTMLImageArray } from './kernel-value/html-image-array';\r\nimport { WebGL2KernelValueDynamicHTMLImageArray } from './kernel-value/dynamic-html-image-array';\r\n\r\nimport { WebGL2KernelValueHTMLVideo } from './kernel-value/html-video';\r\nimport { WebGL2KernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video';\r\n\r\nimport { WebGL2KernelValueSingleInput } from './kernel-value/single-input';\r\nimport { WebGL2KernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input';\r\n\r\nimport { WebGL2KernelValueUnsignedInput } from './kernel-value/unsigned-input';\r\nimport { WebGL2KernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input';\r\n\r\nimport { WebGL2KernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture';\r\nimport { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture';\r\n\r\nimport { WebGL2KernelValueNumberTexture } from './kernel-value/number-texture';\r\nimport { WebGL2KernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture';\r\n\r\nimport { WebGL2KernelValueSingleArray } from './kernel-value/single-array';\r\nimport { WebGL2KernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array';\r\n\r\nimport { WebGL2KernelValueSingleArray1DI } from './kernel-value/single-array1d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray2DI } from './kernel-value/single-array2d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray3DI } from './kernel-value/single-array3d-i';\r\nimport { WebGL2KernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i';\r\n\r\nimport { WebGL2KernelValueSingleArray2 } from './kernel-value/single-array2';\r\nimport { WebGL2KernelValueSingleArray3 } from './kernel-value/single-array3';\r\nimport { WebGL2KernelValueSingleArray4 } from './kernel-value/single-array4';\r\n\r\nimport { WebGL2KernelValueUnsignedArray } from './kernel-value/unsigned-array';\r\nimport { WebGL2KernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array';\r\n\r\nexport const kernelValueMaps = {\r\n unsigned: {\r\n dynamic: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Array': WebGL2KernelValueDynamicUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGL2KernelValueDynamicUnsignedInput,\r\n 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Array': WebGL2KernelValueUnsignedArray,\r\n 'Array(2)': false,\r\n 'Array(3)': false,\r\n 'Array(4)': false,\r\n 'Array1D(2)': false,\r\n 'Array1D(3)': false,\r\n 'Array1D(4)': false,\r\n 'Array2D(2)': false,\r\n 'Array2D(3)': false,\r\n 'Array2D(4)': false,\r\n 'Array3D(2)': false,\r\n 'Array3D(3)': false,\r\n 'Array3D(4)': false,\r\n 'Input': WebGL2KernelValueUnsignedInput,\r\n 'NumberTexture': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueHTMLVideo,\r\n }\r\n },\r\n single: {\r\n dynamic: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Array': WebGL2KernelValueDynamicSingleArray,\r\n 'Array(2)': WebGL2KernelValueSingleArray2,\r\n 'Array(3)': WebGL2KernelValueSingleArray3,\r\n 'Array(4)': WebGL2KernelValueSingleArray4,\r\n 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI,\r\n 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI,\r\n 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI,\r\n 'Input': WebGL2KernelValueDynamicSingleInput,\r\n 'NumberTexture': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueDynamicHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo,\r\n },\r\n static: {\r\n 'Boolean': WebGL2KernelValueBoolean,\r\n 'Float': WebGL2KernelValueFloat,\r\n 'Integer': WebGL2KernelValueInteger,\r\n 'Array': WebGL2KernelValueSingleArray,\r\n 'Array(2)': WebGL2KernelValueSingleArray2,\r\n 'Array(3)': WebGL2KernelValueSingleArray3,\r\n 'Array(4)': WebGL2KernelValueSingleArray4,\r\n 'Array1D(2)': WebGL2KernelValueSingleArray1DI,\r\n 'Array1D(3)': WebGL2KernelValueSingleArray1DI,\r\n 'Array1D(4)': WebGL2KernelValueSingleArray1DI,\r\n 'Array2D(2)': WebGL2KernelValueSingleArray2DI,\r\n 'Array2D(3)': WebGL2KernelValueSingleArray2DI,\r\n 'Array2D(4)': WebGL2KernelValueSingleArray2DI,\r\n 'Array3D(2)': WebGL2KernelValueSingleArray3DI,\r\n 'Array3D(3)': WebGL2KernelValueSingleArray3DI,\r\n 'Array3D(4)': WebGL2KernelValueSingleArray3DI,\r\n 'Input': WebGL2KernelValueSingleInput,\r\n 'NumberTexture': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(1)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(2)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(3)': WebGL2KernelValueNumberTexture,\r\n 'ArrayTexture(4)': WebGL2KernelValueNumberTexture,\r\n 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture,\r\n 'HTMLImage': WebGL2KernelValueHTMLImage,\r\n 'HTMLImageArray': WebGL2KernelValueHTMLImageArray,\r\n 'HTMLVideo': WebGL2KernelValueHTMLVideo,\r\n }\r\n },\r\n};\r\n\r\nexport function lookupKernelValueType(type, dynamic, precision, value) {\r\n if (!type) {\r\n throw new Error('type missing');\r\n }\r\n if (!dynamic) {\r\n throw new Error('dynamic missing');\r\n }\r\n if (!precision) {\r\n throw new Error('precision missing');\r\n }\r\n if (value.type) {\r\n type = value.type;\r\n }\r\n const types = kernelValueMaps[precision][dynamic];\r\n if (types[type] === false) {\r\n return null;\r\n } else if (types[type] === undefined) {\r\n throw new Error(`Could not find a KernelValue for ${ type }`);\r\n }\r\n return types[type];\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicUnsignedArray } from '../../web-gl/kernel-value/dynamic-unsigned-array';\r\n\r\nexport class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueDynamicUnsignedInput } from '../../web-gl/kernel-value/dynamic-unsigned-input';\r\n\r\nexport class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedArray } from '../../web-gl/kernel-value/unsigned-array';\r\n\r\nexport class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueUnsignedInput } from '../../web-gl/kernel-value/unsigned-input';\r\n\r\nexport class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleArray } from '../../web-gl2/kernel-value/single-array';\r\n\r\nexport class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n this.dimensions = utils.getDimensions(value, true);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGL2KernelValueSingleInput } from '../../web-gl2/kernel-value/single-input';\r\n\r\nexport class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput {\r\n getSource() {\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform ${ variablePrecision } sampler2D ${this.id}`,\r\n `uniform ${ variablePrecision } ivec2 ${this.sizeId}`,\r\n `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`,\r\n ]);\r\n }\r\n\r\n updateValue(value) {\r\n let [w, h, d] = value.size;\r\n this.dimensions = new Int32Array([w || 1, h || 1, d || 1]);\r\n this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio);\r\n this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio;\r\n this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio);\r\n this.uploadValue = new Float32Array(this.uploadArrayLength);\r\n this.kernel.setUniform3iv(this.dimensionsId, this.dimensions);\r\n this.kernel.setUniform2iv(this.sizeId, this.textureSize);\r\n super.updateValue(value);\r\n }\r\n}\r\n","import { utils } from '../../../utils';\r\nimport { WebGLKernelValueMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/memory-optimized-number-texture';\r\n\r\nexport class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture {\r\n getSource() {\r\n const { id, sizeId, textureSize, dimensionsId, dimensions } = this;\r\n const variablePrecision = this.getVariablePrecisionString();\r\n return utils.linesToString([\r\n `uniform sampler2D ${id}`,\r\n `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`,\r\n `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`,\r\n ]);\r\n }\r\n}\r\n","import { WebGLKernel } from '../web-gl/kernel';\r\nimport { WebGL2FunctionNode } from './function-node';\r\nimport { FunctionBuilder } from '../function-builder';\r\nimport { utils } from '../../utils';\r\nimport { fragmentShader } from './fragment-shader';\r\nimport { vertexShader } from './vertex-shader';\r\nimport { lookupKernelValueType } from './kernel-value-maps';\r\n\r\nlet isSupported = null;\r\nlet testCanvas = null;\r\nlet testContext = null;\r\nlet testExtensions = null;\r\n\r\n/**\r\n *\r\n * @type {IKernelFeatures}\r\n */\r\nlet features = null;\r\n\r\n/**\r\n * @extends WebGLKernel\r\n */\r\nexport class WebGL2Kernel extends WebGLKernel {\r\n static get isSupported() {\r\n if (isSupported !== null) {\r\n return isSupported;\r\n }\r\n this.setupFeatureChecks();\r\n isSupported = this.isContextMatch(testContext);\r\n return isSupported;\r\n }\r\n\r\n static setupFeatureChecks() {\r\n if (typeof document !== 'undefined') {\r\n testCanvas = document.createElement('canvas');\r\n } else if (typeof OffscreenCanvas !== 'undefined') {\r\n testCanvas = new OffscreenCanvas(0, 0);\r\n }\r\n if (!testCanvas) return;\r\n testContext = testCanvas.getContext('webgl2');\r\n if (!testContext || !testContext.getExtension) return;\r\n testExtensions = {\r\n EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'),\r\n OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'),\r\n };\r\n features = this.getFeatures();\r\n }\r\n\r\n static isContextMatch(context) {\r\n // from global\r\n if (typeof WebGL2RenderingContext !== 'undefined') {\r\n return context instanceof WebGL2RenderingContext;\r\n }\r\n return false;\r\n }\r\n\r\n static getFeatures() {\r\n return Object.freeze({\r\n isFloatRead: this.getIsFloatRead(),\r\n isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(),\r\n kernelMap: true,\r\n isTextureFloat: true,\r\n channelCount: this.getChannelCount(),\r\n maxTextureSize: this.getMaxTextureSize(),\r\n });\r\n }\r\n\r\n static getIsTextureFloat() {\r\n return true;\r\n }\r\n\r\n static getIsIntegerDivisionAccurate() {\r\n return super.getIsIntegerDivisionAccurate();\r\n }\r\n\r\n static getChannelCount() {\r\n return testContext.getParameter(testContext.MAX_DRAW_BUFFERS);\r\n }\r\n\r\n static getMaxTextureSize() {\r\n return testContext.getParameter(testContext.MAX_TEXTURE_SIZE);\r\n }\r\n\r\n static lookupKernelValueType(type, dynamic, precision, value) {\r\n return lookupKernelValueType(type, dynamic, precision, value);\r\n }\r\n\r\n static get testCanvas() {\r\n return testCanvas;\r\n }\r\n\r\n static get testContext() {\r\n return testContext;\r\n }\r\n\r\n /**\r\n *\r\n * @returns {{isFloatRead: Boolean, isIntegerDivisionAccurate: Boolean, kernelMap: Boolean, isTextureFloat: Boolean}}\r\n */\r\n static get features() {\r\n return features;\r\n }\r\n\r\n static get fragmentShader() {\r\n return fragmentShader;\r\n }\r\n static get vertexShader() {\r\n return vertexShader;\r\n }\r\n\r\n initContext() {\r\n const settings = {\r\n alpha: false,\r\n depth: false,\r\n antialias: false\r\n };\r\n const context = this.canvas.getContext('webgl2', settings);\r\n return context;\r\n }\r\n\r\n initExtensions() {\r\n this.extensions = {\r\n EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'),\r\n OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'),\r\n };\r\n }\r\n\r\n /**\r\n * @desc Validate settings related to Kernel, such as dimensions size, and auto output support.\r\n * @param {IArguments} args\r\n */\r\n validateSettings(args) {\r\n if (!this.validate) {\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n return;\r\n }\r\n\r\n const features = this.constructor.features;\r\n if (this.precision === 'single' && !features.isFloatRead) {\r\n throw new Error('Float texture outputs are not supported');\r\n } else if (!this.graphical && this.precision === null) {\r\n this.precision = features.isFloatRead ? 'single' : 'unsigned';\r\n }\r\n\r\n if (this.fixIntegerDivisionAccuracy === null) {\r\n this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate;\r\n } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) {\r\n this.fixIntegerDivisionAccuracy = false;\r\n }\r\n\r\n this.checkOutput();\r\n\r\n if (!this.output || this.output.length === 0) {\r\n if (args.length !== 1) {\r\n throw new Error('Auto output only supported for kernels with only one input');\r\n }\r\n\r\n const argType = utils.getVariableType(args[0], this.strictIntegers);\r\n switch (argType) {\r\n case 'Array':\r\n this.output = utils.getDimensions(argType);\r\n break;\r\n case 'NumberTexture':\r\n case 'MemoryOptimizedNumberTexture':\r\n case 'ArrayTexture(1)':\r\n case 'ArrayTexture(2)':\r\n case 'ArrayTexture(3)':\r\n case 'ArrayTexture(4)':\r\n this.output = args[0].output;\r\n break;\r\n default:\r\n throw new Error('Auto output not supported for input type: ' + argType);\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.output.length !== 2) {\r\n throw new Error('Output must have 2 dimensions on graphical mode');\r\n }\r\n\r\n if (this.precision === 'single') {\r\n console.warn('Cannot use graphical mode and single precision at the same time');\r\n this.precision = 'unsigned';\r\n }\r\n\r\n this.texSize = utils.clone(this.output);\r\n return;\r\n } else if (!this.graphical && this.precision === null && features.isTextureFloat) {\r\n this.precision = 'single';\r\n }\r\n\r\n this.texSize = utils.getKernelTextureSize({\r\n optimizeFloatMemory: this.optimizeFloatMemory,\r\n precision: this.precision,\r\n }, this.output);\r\n\r\n this.checkTextureSize();\r\n }\r\n\r\n translateSource() {\r\n const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, {\r\n fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy\r\n });\r\n this.translatedSource = functionBuilder.getPrototypeString('kernel');\r\n if (!this.graphical && !this.returnType) {\r\n this.returnType = functionBuilder.getKernelResultType();\r\n }\r\n\r\n if (this.subKernels && this.subKernels.length > 0) {\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (!subKernel.returnType) {\r\n subKernel.returnType = functionBuilder.getSubKernelResultType(i);\r\n }\r\n }\r\n }\r\n }\r\n\r\n run() {\r\n const { kernelArguments, texSize, forceUploadKernelConstants } = this;\r\n const gl = this.context;\r\n\r\n gl.useProgram(this.program);\r\n gl.scissor(0, 0, texSize[0], texSize[1]);\r\n\r\n if (this.dynamicOutput) {\r\n this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim));\r\n this.setUniform2iv('uTexSize', texSize);\r\n }\r\n\r\n this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]);\r\n\r\n this.switchingKernels = false;\r\n for (let i = 0; i < forceUploadKernelConstants.length; i++) {\r\n const constant = forceUploadKernelConstants[i];\r\n constant.updateValue(this.constants[constant.name]);\r\n if (this.switchingKernels) return;\r\n }\r\n for (let i = 0; i < kernelArguments.length; i++) {\r\n kernelArguments[i].updateValue(arguments[i]);\r\n if (this.switchingKernels) return;\r\n }\r\n\r\n if (this.plugins) {\r\n for (let i = 0; i < this.plugins.length; i++) {\r\n const plugin = this.plugins[i];\r\n if (plugin.onBeforeRun) {\r\n plugin.onBeforeRun(this);\r\n }\r\n }\r\n }\r\n\r\n if (this.graphical) {\r\n if (this.pipeline) {\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (!this.outputTexture || this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return new this.TextureConstructor({\r\n texture: this.outputTexture,\r\n size: texSize,\r\n dimensions: this.threadDim,\r\n output: this.output,\r\n context: this.context\r\n });\r\n }\r\n gl.bindRenderbuffer(gl.RENDERBUFFER, null);\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n return;\r\n }\r\n\r\n gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\r\n if (this.immutable) {\r\n this._setupOutputTexture();\r\n }\r\n\r\n if (this.subKernels !== null) {\r\n if (this.immutable) {\r\n this._setupSubOutputTextures();\r\n }\r\n gl.drawBuffers(this.drawBuffersMap);\r\n }\r\n\r\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\r\n }\r\n\r\n drawBuffers() {\r\n this.context.drawBuffers(this.drawBuffersMap);\r\n }\r\n\r\n getOutputTexture() {\r\n return this.outputTexture;\r\n }\r\n\r\n _setupOutputTexture() {\r\n const { texSize } = this;\r\n const gl = this.context;\r\n const texture = this.outputTexture = gl.createTexture();\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n if (this.precision === 'single') {\r\n if (this.pipeline) {\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Float':\r\n case 'Integer':\r\n if (this.optimizeFloatMemory) {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n } else {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]);\r\n }\r\n break;\r\n case 'Array(2)':\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]);\r\n break;\r\n case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable\r\n case 'Array(4)':\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n break;\r\n default:\r\n throw new Error('Unhandled return type');\r\n }\r\n } else {\r\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]);\r\n }\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\r\n }\r\n\r\n _setupSubOutputTextures() {\r\n const { texSize } = this;\r\n const gl = this.context;\r\n this.drawBuffersMap = [gl.COLOR_ATTACHMENT0];\r\n this.subKernelOutputTextures = [];\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const texture = this.context.createTexture();\r\n this.subKernelOutputTextures.push(texture);\r\n this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1);\r\n gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i);\r\n gl.bindTexture(gl.TEXTURE_2D, texture);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\r\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\r\n // TODO: upgrade this\r\n if (this.precision === 'single') {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null);\r\n } else {\r\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\r\n }\r\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0);\r\n }\r\n }\r\n\r\n /**\r\n *\r\n * @desc Get the header string for the program.\r\n * This returns an empty string if no sub-kernels are defined.\r\n *\r\n * @returns {String} result\r\n */\r\n _getHeaderString() {\r\n return '';\r\n }\r\n\r\n /**\r\n * @desc Get texture coordinate string for the program\r\n * @returns {String} result\r\n */\r\n _getTextureCoordinate() {\r\n const subKernels = this.subKernels;\r\n if (subKernels === null || subKernels.length < 1) {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'in lowp vec2 vTexCoord;\\n';\r\n case 'performance':\r\n return 'in highp vec2 vTexCoord;\\n';\r\n case 'balanced':\r\n default:\r\n return 'in mediump vec2 vTexCoord;\\n';\r\n }\r\n } else {\r\n switch (this.tactic) {\r\n case 'speed':\r\n return 'out lowp vec2 vTexCoord;\\n';\r\n case 'performance':\r\n return 'out highp vec2 vTexCoord;\\n';\r\n case 'balanced':\r\n default:\r\n return 'out mediump vec2 vTexCoord;\\n';\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel\r\n * @param {Array} args - The actual parameters sent to the Kernel\r\n * @returns {String} result\r\n */\r\n _getMainArgumentsString(args) {\r\n const result = [];\r\n const argumentNames = this.argumentNames;\r\n for (let i = 0; i < argumentNames.length; i++) {\r\n result.push(this.kernelArguments[i].getSource(args[i]));\r\n }\r\n return result.join('');\r\n }\r\n\r\n /**\r\n * @desc Get Kernel program string (in *glsl*) for a kernel.\r\n * @returns {String} result\r\n */\r\n getKernelString() {\r\n let kernelResultDeclaration;\r\n switch (this.returnType) {\r\n case 'Array(2)':\r\n kernelResultDeclaration = 'vec2 kernelResult';\r\n break;\r\n case 'Array(3)':\r\n kernelResultDeclaration = 'vec3 kernelResult';\r\n break;\r\n case 'Array(4)':\r\n kernelResultDeclaration = 'vec4 kernelResult';\r\n break;\r\n case 'LiteralInteger':\r\n case 'Float':\r\n case 'Number':\r\n case 'Integer':\r\n kernelResultDeclaration = 'float kernelResult';\r\n break;\r\n default:\r\n if (this.graphical) {\r\n kernelResultDeclaration = 'float kernelResult';\r\n } else {\r\n throw new Error(`unrecognized output type \"${ this.returnType }\"`);\r\n }\r\n }\r\n\r\n const result = [];\r\n const subKernels = this.subKernels;\r\n if (subKernels !== null) {\r\n result.push(\r\n kernelResultDeclaration,\r\n 'layout(location = 0) out vec4 data0'\r\n );\r\n for (let i = 0; i < subKernels.length; i++) {\r\n const subKernel = subKernels[i];\r\n result.push(\r\n subKernel.returnType === 'Integer' ?\r\n `int subKernelResult_${ subKernel.name } = 0` :\r\n `float subKernelResult_${ subKernel.name } = 0.0`,\r\n `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }`\r\n );\r\n }\r\n } else {\r\n result.push(\r\n 'out vec4 data0',\r\n kernelResultDeclaration\r\n );\r\n }\r\n\r\n return utils.linesToString(result) + this.translatedSource;\r\n }\r\n\r\n getMainResultGraphical() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0 = actualColor',\r\n ]);\r\n }\r\n\r\n getMainResultPackedPixels() {\r\n switch (this.returnType) {\r\n case 'LiteralInteger':\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n return this.getMainResultKernelPackedPixels() +\r\n this.getMainResultSubKernelPackedPixels();\r\n default:\r\n throw new Error(`packed output only usable with Numbers, \"${this.returnType}\" specified`);\r\n }\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultKernelPackedPixels() {\r\n return utils.linesToString([\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)`\r\n ]);\r\n }\r\n\r\n /**\r\n * @return {String}\r\n */\r\n getMainResultSubKernelPackedPixels() {\r\n const result = [];\r\n if (!this.subKernels) return '';\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))`\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})`\r\n );\r\n }\r\n }\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultMemoryOptimizedFloats() {\r\n const result = [\r\n ' index *= 4',\r\n ];\r\n\r\n switch (this.returnType) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n const channels = ['r', 'g', 'b', 'a'];\r\n for (let i = 0; i < channels.length; i++) {\r\n const channel = channels[i];\r\n this.getMainResultKernelMemoryOptimizedFloats(result, channel);\r\n this.getMainResultSubKernelMemoryOptimizedFloats(result, channel);\r\n if (i + 1 < channels.length) {\r\n result.push(' index += 1');\r\n }\r\n }\r\n break;\r\n default:\r\n throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`);\r\n }\r\n\r\n return utils.linesToString(result);\r\n }\r\n\r\n getMainResultKernelMemoryOptimizedFloats(result, channel) {\r\n result.push(\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ` data0.${channel} = kernelResult`,\r\n );\r\n }\r\n\r\n getMainResultSubKernelMemoryOptimizedFloats(result, channel) {\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; i++) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n }\r\n\r\n getMainResultKernelNumberTexture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelNumberTexture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n if (subKernel.returnType === 'Integer') {\r\n result.push(\r\n ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`,\r\n );\r\n } else {\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}`,\r\n );\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray2Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult[0]',\r\n ' data0[1] = kernelResult[1]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray2Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,\r\n ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray3Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0[0] = kernelResult[0]',\r\n ' data0[1] = kernelResult[1]',\r\n ' data0[2] = kernelResult[2]',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray3Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n const subKernel = this.subKernels[i];\r\n result.push(\r\n ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`,\r\n ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`,\r\n ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n getMainResultKernelArray4Texture() {\r\n return [\r\n ' threadId = indexTo3D(index, uOutputDim)',\r\n ' kernel()',\r\n ' data0 = kernelResult',\r\n ];\r\n }\r\n\r\n getMainResultSubKernelArray4Texture() {\r\n const result = [];\r\n if (!this.subKernels) return result;\r\n for (let i = 0; i < this.subKernels.length; ++i) {\r\n result.push(\r\n ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`,\r\n );\r\n }\r\n return result;\r\n }\r\n\r\n destroyExtensions() {\r\n this.extensions.EXT_color_buffer_float = null;\r\n this.extensions.OES_texture_float_linear = null;\r\n }\r\n\r\n toJSON() {\r\n const json = super.toJSON();\r\n json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON();\r\n return json;\r\n }\r\n}\r\n","import { utils } from './utils';\r\n\r\n/**\r\n * Makes kernels easier for mortals (including me)\r\n * @param kernel\r\n * @returns {function()}\r\n */\r\nexport function kernelRunShortcut(kernel) {\r\n let run = function() {\r\n kernel.build.apply(kernel, arguments);\r\n if (kernel.renderKernels) {\r\n run = function() {\r\n kernel.run.apply(kernel, arguments);\r\n if (kernel.switchingKernels) {\r\n kernel.switchingKernels = false;\r\n return kernel.onRequestSwitchKernel(arguments, kernel);\r\n }\r\n return kernel.renderKernels();\r\n };\r\n } else if (kernel.renderOutput) {\r\n run = function() {\r\n kernel.run.apply(kernel, arguments);\r\n if (kernel.switchingKernels) {\r\n kernel.switchingKernels = false;\r\n return kernel.onRequestSwitchKernel(arguments, kernel);\r\n }\r\n return kernel.renderOutput();\r\n };\r\n } else {\r\n run = function() {\r\n return kernel.run.apply(kernel, arguments);\r\n };\r\n }\r\n return run.apply(kernel, arguments);\r\n };\r\n const shortcut = function() {\r\n return run.apply(kernel, arguments);\r\n };\r\n /**\r\n * Run kernel in async mode\r\n * @returns {Promise}\r\n */\r\n shortcut.exec = function() {\r\n return new Promise((accept, reject) => {\r\n try {\r\n accept(run.apply(this, arguments));\r\n } catch (e) {\r\n reject(e);\r\n }\r\n });\r\n };\r\n shortcut.replaceKernel = function(replacementKernel) {\r\n kernel = replacementKernel;\r\n bindKernelToShortcut(kernel, shortcut);\r\n shortcut.kernel = kernel;\r\n };\r\n\r\n bindKernelToShortcut(kernel, shortcut);\r\n shortcut.kernel = kernel;\r\n return shortcut;\r\n}\r\n\r\nfunction bindKernelToShortcut(kernel, shortcut) {\r\n const properties = utils.allPropertiesOf(kernel);\r\n for (let i = 0; i < properties.length; i++) {\r\n const property = properties[i];\r\n if (property[0] === '_' && property[1] === '_') continue;\r\n if (typeof kernel[property] === 'function') {\r\n if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') {\r\n shortcut[property] = function() {\r\n kernel[property].apply(kernel, arguments);\r\n return shortcut;\r\n };\r\n } else {\r\n if (property === 'toString') {\r\n shortcut.toString = function() {\r\n return kernel.toString.apply(kernel, arguments);\r\n };\r\n } else {\r\n shortcut[property] = kernel[property].bind(kernel);\r\n }\r\n }\r\n } else {\r\n shortcut.__defineGetter__(property, () => {\r\n return kernel[property];\r\n });\r\n shortcut.__defineSetter__(property, (value) => {\r\n kernel[property] = value;\r\n });\r\n }\r\n }\r\n}\r\n","import { gpuMock } from 'gpu-mock.js';\r\nimport { CPUKernel } from './backend/cpu/kernel';\r\nimport { WebGL2Kernel } from './backend/web-gl2/kernel';\r\nimport { WebGLKernel } from './backend/web-gl/kernel';\r\nimport { kernelRunShortcut } from './kernel-run-shortcut';\r\nimport {\r\n functionToIFunction,\r\n getFunctionNameFromString,\r\n isFunction,\r\n warnDeprecated\r\n} from './common';\r\nimport { getVariableType } from './utils';\r\n\r\n/**\r\n * @type {Kernel[]}\r\n */\r\nconst kernelOrder = [ WebGL2Kernel, WebGLKernel ];\r\n\r\n/**\r\n * @type {string[]}\r\n */\r\nconst kernelTypes = [ 'gpu', 'cpu' ];\r\n\r\nconst internalKernels = {\r\n 'webgl2': WebGL2Kernel,\r\n 'webgl': WebGLKernel,\r\n};\r\n\r\nlet validate = true;\r\n\r\n/**\r\n * The GPU.js library class which manages the GPU context for the creating kernels\r\n */\r\nexport class GPU {\r\n static disableValidation() {\r\n validate = false;\r\n }\r\n\r\n static enableValidation() {\r\n validate = true;\r\n }\r\n\r\n static get isGPUSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported);\r\n }\r\n\r\n /**\r\n *\r\n * @returns {boolean}\r\n */\r\n static get isKernelMapSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap);\r\n }\r\n\r\n /**\r\n * @desc TRUE is platform supports OffscreenCanvas\r\n */\r\n static get isOffscreenCanvasSupported() {\r\n return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined';\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports WebGL\r\n */\r\n static get isWebGLSupported() {\r\n return WebGLKernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports WebGL2\r\n */\r\n static get isWebGL2Supported() {\r\n return WebGL2Kernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports HeadlessGL\r\n */\r\n static get isHeadlessGLSupported() {\r\n return false;\r\n }\r\n\r\n /**\r\n *\r\n * @desc TRUE if platform supports Canvas\r\n */\r\n static get isCanvasSupported() {\r\n return typeof HTMLCanvasElement !== 'undefined';\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports HTMLImageArray}\r\n */\r\n static get isGPUHTMLImageArraySupported() {\r\n return WebGL2Kernel.isSupported;\r\n }\r\n\r\n /**\r\n * @desc TRUE if platform supports single precision}\r\n * @returns {boolean}\r\n */\r\n static get isSinglePrecisionSupported() {\r\n return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat);\r\n }\r\n\r\n /**\r\n * Creates an instance of GPU.\r\n * @param {IGPUSettings} [settings] - Settings to set mode, and other properties\r\n */\r\n constructor(settings) {\r\n settings = settings || {};\r\n this.canvas = settings.canvas || null;\r\n this.context = settings.context || null;\r\n this.mode = settings.mode;\r\n this.Kernel = null;\r\n this.kernels = [];\r\n this.functions = [];\r\n this.nativeFunctions = [];\r\n this.injectedNative = null;\r\n if (this.mode === 'dev') return;\r\n this.chooseKernel();\r\n // add functions from settings\r\n if (settings.functions) {\r\n for (let i = 0; i < settings.functions.length; i++) {\r\n this.addFunction(settings.functions[i]);\r\n }\r\n }\r\n\r\n // add native functions from settings\r\n if (settings.nativeFunctions) {\r\n for (const p in settings.nativeFunctions) {\r\n this.addNativeFunction(p, settings.nativeFunctions[p]);\r\n }\r\n }\r\n }\r\n\r\n getValidate() {\r\n return validate;\r\n }\r\n\r\n /**\r\n * Choose kernel type and save on .Kernel property of GPU\r\n */\r\n chooseKernel() {\r\n if (this.Kernel) return;\r\n\r\n let Kernel = null;\r\n\r\n if (this.context) {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n const ExternalKernel = kernelOrder[i];\r\n if (ExternalKernel.isContextMatch(this.context)) {\r\n if (!ExternalKernel.isSupported) {\r\n throw new Error(`Kernel type ${ExternalKernel.name} not supported`);\r\n }\r\n Kernel = ExternalKernel;\r\n break;\r\n }\r\n }\r\n if (Kernel === null) {\r\n throw new Error('unknown Context');\r\n }\r\n } else if (this.mode) {\r\n if (this.mode in internalKernels) {\r\n if (!validate || internalKernels[this.mode].isSupported) {\r\n Kernel = internalKernels[this.mode];\r\n }\r\n } else if (this.mode === 'gpu') {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n if (kernelOrder[i].isSupported) {\r\n Kernel = kernelOrder[i];\r\n break;\r\n }\r\n }\r\n } else if (this.mode === 'cpu') {\r\n Kernel = CPUKernel;\r\n }\r\n if (!Kernel) {\r\n throw new Error(`A requested mode of \"${this.mode}\" and is not supported`);\r\n }\r\n } else {\r\n for (let i = 0; i < kernelOrder.length; i++) {\r\n if (kernelOrder[i].isSupported) {\r\n Kernel = kernelOrder[i];\r\n break;\r\n }\r\n }\r\n if (!Kernel) {\r\n Kernel = CPUKernel;\r\n }\r\n }\r\n\r\n if (!this.mode) {\r\n this.mode = Kernel.mode;\r\n }\r\n this.Kernel = Kernel;\r\n }\r\n\r\n /**\r\n * @desc This creates a callable function object to call the kernel function with the argument parameter set\r\n * @param {Function|String|object} source - The calling to perform the conversion\r\n * @param {Object} [settings] - The parameter configuration object\r\n * @return {Kernel} callable function to run\r\n */\r\n createKernel(source, settings) {\r\n if (typeof source === 'undefined') {\r\n throw new Error('Missing source parameter');\r\n }\r\n if (typeof source !== 'object' && !isFunction(source) && typeof source !== 'string') {\r\n throw new Error('source parameter not a function');\r\n }\r\n\r\n if (this.mode === 'dev') {\r\n const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings));\r\n this.kernels.push(devKernel);\r\n return devKernel;\r\n }\r\n\r\n source = typeof source === 'function' ? source.toString() : source;\r\n const switchableKernels = {};\r\n const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {};\r\n // handle conversion of argumentTypes\r\n if (settings && typeof settings.argumentTypes === 'object') {\r\n settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);\r\n }\r\n\r\n function onRequestFallback(args) {\r\n const fallbackKernel = new CPUKernel(source, {\r\n argumentTypes: kernelRun.argumentTypes,\r\n constantTypes: kernelRun.constantTypes,\r\n graphical: kernelRun.graphical,\r\n loopMaxIterations: kernelRun.loopMaxIterations,\r\n constants: kernelRun.constants,\r\n dynamicOutput: kernelRun.dynamicOutput,\r\n dynamicArgument: kernelRun.dynamicArguments,\r\n output: kernelRun.output,\r\n precision: kernelRun.precision,\r\n pipeline: kernelRun.pipeline,\r\n immutable: kernelRun.immutable,\r\n optimizeFloatMemory: kernelRun.optimizeFloatMemory,\r\n fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy,\r\n functions: kernelRun.functions,\r\n nativeFunctions: kernelRun.nativeFunctions,\r\n injectedNative: kernelRun.injectedNative,\r\n subKernels: kernelRun.subKernels,\r\n strictIntegers: kernelRun.strictIntegers,\r\n debug: kernelRun.debug,\r\n warnVarUsage: kernelRun.warnVarUsage,\r\n });\r\n fallbackKernel.build.apply(fallbackKernel, args);\r\n const result = fallbackKernel.run.apply(fallbackKernel, args);\r\n kernelRun.replaceKernel(fallbackKernel);\r\n return result;\r\n }\r\n\r\n function onRequestSwitchKernel(args, kernel) {\r\n const argumentTypes = new Array(args.length);\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n const type = kernel.argumentTypes[i];\r\n if (arg.type) {\r\n argumentTypes[i] = arg.type;\r\n } else {\r\n switch (type) {\r\n case 'Number':\r\n case 'Integer':\r\n case 'Float':\r\n case 'ArrayTexture(1)':\r\n argumentTypes[i] = getVariableType(arg);\r\n break;\r\n default:\r\n argumentTypes[i] = type;\r\n }\r\n }\r\n }\r\n const signature = argumentTypes.join(',');\r\n const existingKernel = switchableKernels[signature];\r\n if (existingKernel) {\r\n existingKernel.run.apply(existingKernel, args);\r\n if (existingKernel.renderKernels) {\r\n return existingKernel.renderKernels();\r\n } else {\r\n return existingKernel.renderOutput();\r\n }\r\n }\r\n\r\n const newKernel = switchableKernels[signature] = new kernel.constructor(source, {\r\n argumentTypes,\r\n constantTypes: kernel.constantTypes,\r\n graphical: kernel.graphical,\r\n loopMaxIterations: kernel.loopMaxIterations,\r\n constants: kernel.constants,\r\n dynamicOutput: kernel.dynamicOutput,\r\n dynamicArgument: kernel.dynamicArguments,\r\n context: kernel.context,\r\n canvas: kernel.canvas,\r\n output: kernel.output,\r\n precision: kernel.precision,\r\n pipeline: kernel.pipeline,\r\n immutable: kernel.immutable,\r\n optimizeFloatMemory: kernel.optimizeFloatMemory,\r\n fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy,\r\n functions: kernel.functions,\r\n nativeFunctions: kernel.nativeFunctions,\r\n injectedNative: kernel.injectedNative,\r\n subKernels: kernel.subKernels,\r\n strictIntegers: kernel.strictIntegers,\r\n debug: kernel.debug,\r\n gpu: kernel.gpu,\r\n validate,\r\n warnVarUsage: kernel.warnVarUsage,\r\n returnType: kernel.returnType,\r\n onRequestFallback,\r\n onRequestSwitchKernel,\r\n });\r\n newKernel.build.apply(newKernel, args);\r\n newKernel.run.apply(newKernel, args);\r\n kernelRun.replaceKernel(newKernel);\r\n if (newKernel.renderKernels) {\r\n return newKernel.renderKernels();\r\n } else {\r\n return newKernel.renderOutput();\r\n }\r\n }\r\n const mergedSettings = Object.assign({\r\n context: this.context,\r\n canvas: this.canvas,\r\n functions: this.functions,\r\n nativeFunctions: this.nativeFunctions,\r\n injectedNative: this.injectedNative,\r\n gpu: this,\r\n validate,\r\n onRequestFallback,\r\n onRequestSwitchKernel\r\n }, settingsCopy);\r\n\r\n const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings));\r\n\r\n //if canvas didn't come from this, propagate from kernel\r\n if (!this.canvas) {\r\n this.canvas = kernelRun.canvas;\r\n }\r\n\r\n //if context didn't come from this, propagate from kernel\r\n if (!this.context) {\r\n this.context = kernelRun.context;\r\n }\r\n\r\n this.kernels.push(kernelRun);\r\n\r\n return kernelRun;\r\n }\r\n\r\n /**\r\n *\r\n * Create a super kernel which executes sub kernels\r\n * and saves their output to be used with the next sub kernel.\r\n * This can be useful if we want to save the output on one kernel,\r\n * and then use it as an input to another kernel. *Machine Learning*\r\n *\r\n * @param {Object|Array} subKernels - Sub kernels for this kernel\r\n * @param {Function} rootKernel - Root kernel\r\n *\r\n * @returns {Function} callable kernel function\r\n *\r\n * @example\r\n * const megaKernel = gpu.createKernelMap({\r\n * addResult: function add(a, b) {\r\n * return a[this.thread.x] + b[this.thread.x];\r\n * },\r\n * multiplyResult: function multiply(a, b) {\r\n * return a[this.thread.x] * b[this.thread.x];\r\n * },\r\n * }, function(a, b, c) {\r\n * return multiply(add(a, b), c);\r\n * });\r\n *\r\n * megaKernel(a, b, c);\r\n *\r\n * Note: You can also define subKernels as an array of functions.\r\n * > [add, multiply]\r\n *\r\n */\r\n createKernelMap() {\r\n let fn;\r\n let settings;\r\n if (typeof arguments[arguments.length - 2] === 'function') {\r\n fn = arguments[arguments.length - 2];\r\n settings = arguments[arguments.length - 1];\r\n } else {\r\n fn = arguments[arguments.length - 1];\r\n }\r\n\r\n if (this.mode !== 'dev') {\r\n if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) {\r\n if (this.mode && kernelTypes.indexOf(this.mode) < 0) {\r\n throw new Error(`kernelMap not supported on ${this.Kernel.name}`);\r\n }\r\n }\r\n }\r\n\r\n const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings);\r\n // handle conversion of argumentTypes\r\n if (settings && typeof settings.argumentTypes === 'object') {\r\n settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]);\r\n }\r\n\r\n if (Array.isArray(arguments[0])) {\r\n settingsCopy.subKernels = [];\r\n const functions = arguments[0];\r\n for (let i = 0; i < functions.length; i++) {\r\n const source = functions[i].toString();\r\n const name = getFunctionNameFromString(source);\r\n settingsCopy.subKernels.push({\r\n name,\r\n source,\r\n property: i,\r\n });\r\n }\r\n } else {\r\n settingsCopy.subKernels = [];\r\n const functions = arguments[0];\r\n for (let p in functions) {\r\n if (!functions.hasOwnProperty(p)) continue;\r\n const source = functions[p].toString();\r\n const name = getFunctionNameFromString(source);\r\n settingsCopy.subKernels.push({\r\n name: name || p,\r\n source,\r\n property: p,\r\n });\r\n }\r\n }\r\n const kernel = this.createKernel(fn, settingsCopy);\r\n\r\n return kernel;\r\n }\r\n\r\n /**\r\n *\r\n * Combine different kernels into one super Kernel,\r\n * useful to perform multiple operations inside one\r\n * kernel without the penalty of data transfer between\r\n * cpu and gpu.\r\n *\r\n * The number of kernel functions sent to this method can be variable.\r\n * You can send in one, two, etc.\r\n *\r\n * @param {Function} subKernels - Kernel function(s) to combine.\r\n * @param {Function} rootKernel - Root kernel to combine kernels into\r\n *\r\n * @example\r\n * combineKernels(add, multiply, function(a,b,c){\r\n * return add(multiply(a,b), c)\r\n * })\r\n *\r\n * @returns {Function} Callable kernel function\r\n *\r\n */\r\n combineKernels() {\r\n const firstKernel = arguments[0];\r\n const combinedKernel = arguments[arguments.length - 1];\r\n if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel;\r\n const canvas = arguments[0].canvas;\r\n const context = arguments[0].context;\r\n const max = arguments.length - 1;\r\n for (let i = 0; i < max; i++) {\r\n arguments[i]\r\n .setCanvas(canvas)\r\n .setContext(context)\r\n .setPipeline(true);\r\n }\r\n\r\n return function() {\r\n const texture = combinedKernel.apply(this, arguments);\r\n if (texture.toArray) {\r\n return texture.toArray();\r\n }\r\n return texture;\r\n };\r\n }\r\n\r\n /**\r\n * @desc Adds additional functions, that the kernel may call.\r\n * @param {Function|String} source - Javascript function to convert\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {GPU} returns itself\r\n */\r\n addFunction(source, settings) {\r\n this.functions.push(functionToIFunction(source, settings));\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Adds additional native functions, that the kernel may call.\r\n * @param {String} name - native function name, used for reverse lookup\r\n * @param {String} source - the native function implementation, as it would be defined in it's entirety\r\n * @param {object} [settings]\r\n * @returns {GPU} returns itself\r\n */\r\n addNativeFunction(name, source, settings) {\r\n if (this.kernels.length > 0) {\r\n throw new Error('Cannot call \"addNativeFunction\" after \"createKernels\" has been called.');\r\n }\r\n settings = settings || {};\r\n const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {};\r\n this.nativeFunctions.push({\r\n name,\r\n source,\r\n settings,\r\n argumentTypes,\r\n argumentNames,\r\n returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source),\r\n });\r\n return this;\r\n }\r\n\r\n /**\r\n * Inject a string just before translated kernel functions\r\n * @param {String} source\r\n * @return {GPU}\r\n */\r\n injectNative(source) {\r\n this.injectedNative = source;\r\n return this;\r\n }\r\n\r\n /**\r\n * @desc Destroys all memory associated with gpu.js & the webGl if we created it\r\n */\r\n destroy() {\r\n if (!this.kernels) return;\r\n // perform on next run loop - for some reason we dont get lose context events\r\n // if webGl is created and destroyed in the same run loop.\r\n setTimeout(() => {\r\n for (let i = 0; i < this.kernels.length; i++) {\r\n this.kernels[i].destroy(true); // remove canvas if exists\r\n }\r\n // all kernels are associated with one context, go ahead and take care of it here\r\n let firstKernel = this.kernels[0];\r\n if (firstKernel) {\r\n // if it is shortcut\r\n if (firstKernel.kernel) {\r\n firstKernel = firstKernel.kernel;\r\n }\r\n if (firstKernel.constructor.destroyContext) {\r\n firstKernel.constructor.destroyContext(this.context);\r\n }\r\n }\r\n }, 0);\r\n }\r\n}\r\n\r\nfunction upgradeDeprecatedCreateKernelSettings(settings) {\r\n if (!settings) {\r\n return {};\r\n }\r\n const upgradedSettings = Object.assign({}, settings);\r\n\r\n if (settings.hasOwnProperty('floatOutput')) {\r\n warnDeprecated('setting', 'floatOutput', 'precision');\r\n upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned';\r\n }\r\n if (settings.hasOwnProperty('outputToTexture')) {\r\n warnDeprecated('setting', 'outputToTexture', 'pipeline');\r\n upgradedSettings.pipeline = Boolean(settings.outputToTexture);\r\n }\r\n if (settings.hasOwnProperty('outputImmutable')) {\r\n warnDeprecated('setting', 'outputImmutable', 'immutable');\r\n upgradedSettings.immutable = Boolean(settings.outputImmutable);\r\n }\r\n if (settings.hasOwnProperty('floatTextures')) {\r\n warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory');\r\n upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures);\r\n }\r\n return upgradedSettings;\r\n}\r\n","import { GPU } from './base-gpu';\r\nimport { alias } from './alias';\r\nimport { utils } from './utils';\r\nimport * as common from './common';\r\nimport { Input, input } from './input';\r\nimport { Texture } from './texture';\r\nimport { FunctionBuilder } from './backend/function-builder';\r\nimport { FunctionNode } from './backend/function-node';\r\nimport { CPUFunctionNode } from './backend/cpu/function-node';\r\nimport { CPUKernel } from './backend/cpu/kernel';\r\nimport { WebGLFunctionNode } from './backend/web-gl/function-node';\r\nimport { WebGLKernel } from './backend/web-gl/kernel';\r\nimport { WebGL2FunctionNode } from './backend/web-gl2/function-node';\r\nimport { WebGL2Kernel } from './backend/web-gl2/kernel';\r\nimport { GLKernel } from './backend/gl/kernel';\r\nimport { Kernel } from './backend/kernel';\r\n\r\n/**\r\n * Stub for HeadlessGL.\r\n */\r\nclass HeadlessGLKernel extends WebGLKernel {\r\n static get isSupported() { return false }\r\n static isContextMatch() { return false }\r\n static getIsTextureFloat() { return false }\r\n static getIsDrawBuffers() { return false }\r\n static getChannelCount() { return 1 }\r\n static get testCanvas() { return null }\r\n static get testContext() { return null }\r\n static get features() { return null }\r\n static setupFeatureChecks() {}\r\n static destroyContext() {}\r\n initCanvas() { return {} }\r\n initContext() { return null }\r\n toString() { return '' }\r\n initExtensions() {}\r\n build() {}\r\n destroyExtensions() {}\r\n setOutput() {}\r\n\r\n static getFeatures() {\r\n return Object.freeze({\r\n isFloatRead: false,\r\n isIntegerDivisionAccurate: false,\r\n isTextureFloat: false,\r\n isDrawBuffers: false,\r\n kernelMap: false,\r\n channelCount: 1,\r\n });\r\n }\r\n};\r\n\r\nconst lib = GPU;\r\nlib.alias = alias;\r\nlib.CPUFunctionNode = CPUFunctionNode;\r\nlib.CPUKernel = CPUKernel;\r\nlib.FunctionBuilder = FunctionBuilder;\r\nlib.FunctionNode = FunctionNode;\r\nlib.HeadlessGLKernel = HeadlessGLKernel;\r\nlib.Input = Input;\r\nlib.input = input;\r\nlib.Texture = Texture;\r\nlib.utils = { ...common, ...utils };\r\nlib.WebGL2FunctionNode = WebGL2FunctionNode;\r\nlib.WebGL2Kernel = WebGL2Kernel;\r\nlib.WebGLFunctionNode = WebGLFunctionNode;\r\nlib.WebGLKernel = WebGLKernel;\r\nlib.GLKernel = GLKernel;\r\nlib.Kernel = Kernel;\r\n\r\nexport default lib;\r\n","import { utils } from './utils';\r\n\r\n/**\r\n * @param name\r\n * @param source\r\n * @returns {Function}\r\n */\r\nexport function alias(name, source) {\r\n const fnString = source.toString();\r\n return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) {\r\n ${ utils.getFunctionBodyFromString(fnString) }\r\n}`)();\r\n}\r\n"],"names":["setupArguments","args","newArguments","Array","length","i","arg","toArray","mock1D","arguments","row","Float32Array","this","output","x","thread","y","z","_fn","apply","mock2D","matrix","mock2DGraphical","mock3D","cube","apiDecorate","kernel","setOutput","setupOutput","graphical","setupGraphical","toJSON","Error","setConstants","flag","constants","setGraphical","setCanvas","canvas","setContext","context","exec","Promise","resolve","reject","e","getPixels","flip","pixels","width","height","halfHeight","bytesPerRow","temp","Uint8ClampedArray","result","slice","topOffset","bottomOffset","set","subarray","copyWithin","flipPixels","_imageData","data","color","r","g","b","a","Math","floor","index","_colorData","setWarnVarUsage","setOptimizeFloatMemory","setArgumentTypes","setDebug","setLoopMaxIterations","setPipeline","setPrecision","setImmutable","setFunctions","addSubKernel","destroy","validateSettings","createImageData","fn","settings","ARGUMENT_NAMES","FUNCTION_NAME","STRIP_COMMENTS","isFunction","funcObj","getFunctionNameFromString","funcStr","trim","functionToIFunction","source","sourceString","toString","argumentTypes","isArray","getArgumentNamesFromString","map","name","returnType","warnDeprecated","type","oldName","newName","msg","console","warn","isFunctionString","toLowerCase","fnStr","replace","indexOf","match","array","isNaN","erectMemoryOptimized2DFloat","yResults","offset","erectMemoryOptimized3DFloat","depth","zResults","getAstString","ast","lines","split","start","loc","end","line","push","substring","column","join","Input","[object Object]","value","size","Int32Array","w","h","d","Texture","texture","dimensions","constructor","deleteTexture","getSystemEndianness","ArrayBuffer","Uint32Array","c","Uint8Array","_systemEndianness","getVariableType","strictIntegers","nodeName","Boolean","Number","isInteger","hasOwnProperty","utils","systemEndianness","getFunctionBodyFromString","lastIndexOf","obj","key","Object","prototype","call","isActiveClone","clone","texelCount","optimizeFloatMemory","precision","ceil","closestSquareDimensions","sqrt","high","low","bitRatio","roundTo","n","pad","ret","dim","reverse","from","target","l","flatten4dArrayTo","flatten3dArrayTo","flatten2dArrayTo","part","buffer","byteOffset","props","getOwnPropertyNames","getPrototypeOf","linesToString","erectPackedFloat","erect2DPackedFloat","xStart","xEnd","erect3DPackedFloat","erectMemoryOptimizedFloat","erectFloat","xResults","erect2DFloat","erect3DFloat","erectArray2","xResultsMax","erect2DArray2","XResultsMax","erect3DArray2","erectArray3","erect2DArray3","erect3DArray3","erectArray4","erect2DArray4","erect3DArray4","flattenFunctionToString","findDependency","thisLookup","doNotDefine","flattened","parse","functionDependencies","flatten","results","body","id","params","declarations","init","properties","declaration","test","lookups","lookup","property","kind","callee","object","foundSource","argument","left","operator","right","prefix","expression","raw","computed","update","consequent","elements","alternate","flattenedFunctionDependencies","functionDependency","Kernel","isSupported","useLegacyEncoder","fallbackRequested","onRequestFallback","argumentNames","argumentSizes","argumentBitRatios","kernelArguments","kernelConstants","debug","loopMaxIterations","constantTypes","constantBitRatios","dynamicArguments","dynamicOutput","checkContext","gpu","functions","nativeFunctions","injectedNative","subKernels","validate","immutable","pipeline","tactic","plugins","leadingReturnStatement","followingReturnStatement","fixIntegerDivisionAccuracy","warnVarUsage","p","initCanvas","initContext","initPlugins","argType","getBitRatio","needsConstantTypes","max","setDynamicOutput","setDynamicArguments","argumentIndex","subKernel","removeCanvasReferences","Int8Array","Uint16Array","Int16Array","threadDim","argumentsTypes","pluginNames","plugin","FunctionBuilder","FunctionNode","extraNodeOptions","kernelConstant","needsArgumentType","functionName","functionBuilder","assignArgumentType","lookupReturnType","requestingNode","lookupFunctionArgumentTypes","lookupFunctionArgumentName","lookupFunctionArgumentBitRatio","argumentName","triggerImplyArgumentType","argumentType","triggerTrackArgumentSynonym","calleeFunctionName","trackArgumentSynonym","lookupArgumentSynonym","originFunctionName","onFunctionCall","trackFunctionCall","nodeOptions","assign","isRootKernel","onNestedFunction","nestedFunction","traceFunctionAST","addFunctionNode","rootNodeOptions","functionNodes","fromJSON","rootNode","subKernelNodes","isSubKernel","functionMap","nativeFunctionNames","lookupChain","argumentChain","functionNodeDependencies","functionCalls","nativeFunction","functionNode","retList","functionIndex","calledFunctions","traceFunctionCalls","dependantFunctionName","splice","getPrototypes","getPrototypesFromFunctionNames","keys","functionList","node","nativeIndex","jsonFunctionNodes","jsonFunctionNode","getStringFromFunctionNames","_isNativeFunction","_lookupNativeFunctionReturnType","_isFunction","_getFunction","j","getType","pop","getJsAST","_getNativeFunction","argumentSynonym","synonymIndex","fnNode","calleeArgumentName","synonymUseIndex","Set","add","subKernelNode","called","functionCallIndex","list","FunctionTracer","runningContexts","contexts","identifiers","returnStatements","inLoopInit","scan","currentContext","run","newContext","origin","forceInteger","assignable","discriminant","cases","states","triggerImplyArgumentBitRatio","strictTypingChecking","literalTypes","_string","_internalVariableNames","state","astMemberExpressionUnroll","firstExpression","expressions","astErrorOutput","inParser","parser","freeze","locations","functionAST","dependencies","getDependencies","valueType","realType","isSafe","isSafeDependencies","identifier","getDeclaration","typeLookupMap","constantName","astGeneric","literalKey","isAstMathFunction","inferArgumentTypesIfNeeded","isState","rightType","lastType","isAstVariable","getVariableSignature","findIdentifierOrigin","getLookupType","getConstantType","isAstMathVariable","lastReturn","findLastReturn","every","dependency","isNotSafe","Infinity","details","getMemberExpressionDetails","signature","xProperty","yProperty","zProperty","unshift","signatureString","retArr","astFunctionDeclaration","astFunctionExpression","astReturnStatement","astLiteral","astBinaryExpression","astIdentifierExpression","astAssignmentExpression","astExpressionStatement","astEmptyStatement","astBlockStatement","astIfStatement","astSwitchStatement","astBreakStatement","astContinueStatement","astForStatement","astWhileStatement","astDoWhileStatement","astVariableDeclaration","astVariableDeclarator","astThisExpression","astSequenceExpression","astUnaryExpression","astUpdateExpression","astLogicalExpression","astMemberExpression","astCallExpression","astArrayExpression","astDebuggerStatement","astConditionalExpression","error","debugString","splitLines","substr","lineBefore","arrNode","isChildFunction","astFunction","esNode","eNode","brNode","crNode","varDecNode","firstDeclaration","markupType","typeMap","iVarDecNode","sNode","uNode","checkAndUpconvertBitwiseUnary","logNode","variableSignature","astToFind","stack","atNode","shift","Float","Integer","Array(2)","Array(3)","Array(4)","Array2D","Array3D","HTMLImage","HTMLVideo","HTMLImageArray","NumberTexture","MemoryOptimizedNumberTexture","Array1D(2)","Array1D(3)","Array1D(4)","Array2D(2)","Array2D(3)","Array2D(4)","Array3D(2)","Array3D(3)","Array3D(4)","ArrayTexture(1)","ArrayTexture(2)","ArrayTexture(3)","ArrayTexture(4)","CPUFunctionNode","idtNode","forNode","initArr","testArr","updateArr","bodyArr","pushState","includes","popState","iVariableName","getInternalVariableName","whileNode","doWhileNode","assNode","bNode","varWarn","ifNode","tNode","mNode","markupName","isInput","constant","targetTypes","arrLen","subNode","cpuKernelString","cpuKernel","header","thisProperties","beforeReturn","useFunctionKeyword","JSON","stringify","types","constantsToString","colorFn","propertyName","getPixelsFn","constantKeys","flattenedImageTo3DArray","_imageTo3DArray","flattenedImageTo2DArray","_mediaTo2DArray","_kernelString","CPUKernel","features","kernelMap","isIntegerDivisionAccurate","mode","combinedKernel","super","mergeSettings","translatedSources","document","createElement","OffscreenCanvas","getContext","getDimensions","checkOutput","fromKernel","getKernelResultType","setupConstants","translateSource","kernelString","getKernelString","log","Function","bind","kernelThreadString","filter","_getLoopMaxString","_processConstants","_processArguments","_graphicalKernelBody","_resultKernelBody","parseInt","variableName","media","videoWidth","videoHeight","ctx","drawImage","pixelsData","getImageData","imageArray","pixel","images","imagesArray","_resultKernel1DLoop","_kernelOutput","_resultKernel2DLoop","_resultKernel3DLoop","_graphicalKernel2DLoop","_graphicalOutput","constructorString","_getKernelResultTypeConstructorString","_mapSubKernels","removeCanvasReference","json","GLTextureFloat","gl","framebuffer","createFramebuffer","bindFramebuffer","FRAMEBUFFER","framebufferTexture2D","COLOR_ATTACHMENT0","TEXTURE_2D","readPixels","RGBA","FLOAT","renderRawOutput","renderValues","GLTextureArray2Float","GLTextureArray2Float2D","GLTextureArray2Float3D","GLTextureArray3Float","GLTextureArray3Float2D","GLTextureArray3Float3D","GLTextureArray4Float","GLTextureArray4Float2D","GLTextureArray4Float3D","GLTextureFloat2D","GLTextureFloat3D","GLTextureMemoryOptimized","GLTextureMemoryOptimized2D","GLTextureMemoryOptimized3D","GLTextureUnsigned","UNSIGNED_BYTE","GLTextureUnsigned2D","GLTextureUnsigned3D","GLTextureGraphical","GLKernel","testContext","testCanvas","build","renderOutput","v1","v2","fix","floatTextures","isStartingVariableName","isVariableChar","char","nextChar","lastKernel","texSize","bytes","splitArray","transferValues","formatValues","TextureConstructor","translatedSource","renderStrategy","compiledFragmentShader","compiledVertexShader","maxTextureSize","readPackedPixelsToUint8Array","readPackedPixelsToFloat32Array","renderTexture","renderKernels","renderKernelsToTextures","PackedPixelTo3DFloat","PackedPixelTo2DFloat","PackedPixelToFloat","requestFallback","renderKernelsToArrays","readFloatPixelsToFloat32Array","FloatTexture","MemoryOptimizedFloatPixelToMemoryOptimized3DFloat","MemoryOptimizedFloatPixelToMemoryOptimized2DFloat","MemoryOptimizedFloatPixelToMemoryOptimizedFloat","FloatPixelTo3DArray2","FloatPixelTo2DArray2","FloatPixelToArray2","FloatPixelTo3DArray3","FloatPixelTo2DArray3","FloatPixelToArray3","FloatPixelTo3DArray4","FloatPixelTo2DArray4","FloatPixelToArray4","FloatPixelTo3DFloat","FloatPixelTo2DFloat","FloatPixelToFloat","getMainResultNumberTexture","getMainResultArray2Texture","getMainResultArray3Texture","getMainResultArray4Texture","getMainResultGraphical","getMainResultMemoryOptimizedFloats","getMainResultTexture","getMainResultPackedPixels","getMainResultKernelNumberTexture","getMainResultSubKernelNumberTexture","getMainResultKernelArray2Texture","getMainResultSubKernelArray2Texture","getMainResultKernelArray3Texture","getMainResultSubKernelArray3Texture","getMainResultKernelArray4Texture","getMainResultSubKernelArray4Texture","outputTexture","subKernelOutputTextures","program","getKernelTextureSize","updateMaxTexSize","viewport","maxTexSize","_setupOutputTexture","_setupSubOutputTextures","PackedPixelToUint8Array","Symbol","PackedTexture","FloatPixelToFloat32Array","int","float","vec2","vec3","vec4","WebGLFunctionNode","castLiteralToFloat","castValueToInteger","castLiteralToInteger","round","checkAndUpconvertOperator","castValueToFloat","leftType","operatorMap","literalResult","bitwiseResult","checkAndUpconvertBitwiseOperators","foundOperator","%","**","&","|","^","<<",">>",">>>","~","inForLoopInit","info","actualType","declarationResult","varName","fallingThrough","defaultResult","movingDefaultToEnd","pastFirstIf","memberExpressionPropertyMarkup","memberExpressionXYZ","isMathFunction","functionMatch","functionReplace","targetType","LiteralInteger","===","!==","onBeforeRun","setUniform1f","random","functionReturnType","fragmentShader","vertexShader","glWiretap","options","contextName","throwGetError","useTrackablePrimitives","readPixelsFile","recording","variables","onReadPixels","onUnrecognizedArgumentLookup","proxy","Proxy","get","addComment","checkThrowError","readPixelsVariableName","insertVariable","reset","setIndent","getContextVariableName","indent","getError","contextVariables","extension","getExtension","tappedExtension","glExtensionWiretap","getEntity","targetVariableName","getVariableName","argumentAsStrings","writePPM","argumentsToString","addVariable","drawBuffers","methodCallToString","trackablePrimitive","entityNames","imageCount","spaces","repeat","sourceVariable","imageVariable","method","getExtensionEntity","drawBuffersWEBGL","extensionEntityNames","hasLines","hasSingleQuotes","hasDoubleQuotes","instantiationString","argumentToString","module","window","toStringWithoutUtils","glKernelString","originKernel","setupContextString","destroyContextString","postResult","targetName","subKernelsResultVariableSetup","subKernelsResultIndex","getRenderString","findKernelValue","forEach","kernelArgument","uploadValue","imageIndex","flattenTo","getStringValueHandler","textureName","getToArrayString","subKernelResult","subKernelTextureName","getGetPixelsString","constantsUpload","readBackValue","kernelResult","kernelValues","values","uploadedValues","HTMLImageElement","kernelValue","variableIndex","variable","KernelValue","onRequestContextHandle","onUpdateValueMismatch","contextHandle","forceUploadEachRun","WebGLKernelValue","dimensionsId","sizeId","initialValueConstructor","onRequestTexture","onRequestIndex","textureSize","setupTexture","getTransferArrayType","Float64Array","Type","valuesFlat","WebGLKernelValueBoolean","setUniform1i","WebGLKernelValueFloat","WebGLKernelValueInteger","WebGLKernelValueHTMLImage","checkSize","requestTexture","inputImage","activeTexture","bindTexture","texParameteri","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","TEXTURE_MIN_FILTER","NEAREST","TEXTURE_MAG_FILTER","pixelStorei","UNPACK_FLIP_Y_WEBGL","texImage2D","WebGLKernelValueDynamicHTMLImage","setUniform3iv","setUniform2iv","updateValue","WebGLKernelValueHTMLVideo","WebGLKernelValueDynamicHTMLVideo","WebGLKernelValueSingleInput","getMemoryOptimizedFloatTextureSize","uploadArrayLength","input","WebGLKernelValueUnsignedInput","getMemoryOptimizedPackedTextureSize","TranserArrayType","preUploadValue","WebGLKernelValueDynamicUnsignedInput","WebGLKernelValueMemoryOptimizedNumberTexture","inputTexture","WebGLKernelValueDynamicMemoryOptimizedNumberTexture","WebGLKernelValueNumberTexture","WebGLKernelValueDynamicNumberTexture","WebGLKernelValueSingleArray","WebGLKernelValueSingleArray1DI","setShape","valueDimensions","WebGLKernelValueDynamicSingleArray1DI","WebGLKernelValueSingleArray2DI","WebGLKernelValueDynamicSingleArray2DI","WebGLKernelValueSingleArray3DI","WebGLKernelValueDynamicSingleArray3DI","WebGLKernelValueSingleArray2","setUniform2fv","WebGLKernelValueSingleArray3","setUniform3fv","WebGLKernelValueSingleArray4","setUniform4fv","WebGLKernelValueUnsignedArray","WebGLKernelValueDynamicUnsignedArray","kernelValueMaps","unsigned","dynamic","static","single","testExtensions","triangleNoise","canvases","maxTexSizes","WebGLKernel","setupFeatureChecks","isContextMatch","OES_texture_float","OES_texture_float_linear","OES_element_index_uint","WEBGL_draw_buffers","getFeatures","WebGLRenderingContext","isDrawBuffers","getIsDrawBuffers","isFloatRead","getIsFloatRead","getIsIntegerDivisionAccurate","isTextureFloat","getIsTextureFloat","channelCount","getChannelCount","getParameter","MAX_DRAW_BUFFERS_WEBGL","undefined","lookupKernelValueType","endianness","extensions","argumentTextureCount","constantTextureCount","fragShader","vertShader","drawBuffersMap","switchingKernels","onRequestSwitchKernel","textureCache","programUniformLocationCache","uniform1fCache","uniform1iCache","uniform2fCache","uniform2fvCache","uniform2ivCache","uniform3fvCache","uniform3ivCache","uniform4fvCache","uniform4ivCache","alpha","antialias","pluginsToUse","some","pluginName","WEBGL_color_buffer_float","checkTextureSize","canvasIndex","getPrototypeString","requiredChannels","returnTypes","getReturnTypes","needsArgumentTypes","textureIndexes","createTexture","TEXTURE0","forceUploadKernelConstants","initExtensions","failureResult","pickRenderStrategy","enable","SCISSOR_TEST","getVertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","getFragmentShader","FRAGMENT_SHADER","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","createProgram","attachShader","linkProgram","vertices","texCoords","texCoordOffset","byteLength","bindBuffer","ARRAY_BUFFER","createBuffer","bufferData","STATIC_DRAW","bufferSubData","aPosLoc","getAttribLocation","enableVertexAttribArray","vertexAttribPointer","aTexCoordLoc","useProgram","getSubKernelResultType","scissor","setUniform2f","bindRenderbuffer","RENDERBUFFER","drawArrays","TRIANGLE_STRIP","getUniformLocation","uniform1f","uniform1i","value1","value2","cache","uniform2f","uniform2fv","uniform2iv","uniform3fv","uniform3iv","uniform4iv","uniform4fv","HEADER","_getHeaderString","LOOP_MAX","PLUGINS","_getPluginsString","CONSTANTS","_getConstantsString","DECODE32_ENDIANNESS","_getDecode32EndiannessString","ENCODE32_ENDIANNESS","_getEncode32EndiannessString","DIVIDE_WITH_INTEGER_CHECK","_getDivideWithIntegerCheckString","INJECTED_NATIVE","_getInjectedNative","MAIN_CONSTANTS","_getMainConstantsString","MAIN_ARGUMENTS","_getMainArgumentsString","KERNEL","MAIN_RESULT","getMainResultString","FLOAT_TACTIC_DECLARATION","getFloatTacticDeclaration","INT_TACTIC_DECLARATION","getIntTacticDeclaration","SAMPLER_2D_TACTIC_DECLARATION","getSampler2DTacticDeclaration","SAMPLER_2D_ARRAY_TACTIC_DECLARATION","getSampler2DArrayTacticDeclaration","getSource","kernelResultDeclaration","getMainResultKernelPackedPixels","getMainResultSubKernelPackedPixels","channels","channel","getMainResultKernelMemoryOptimizedFloats","getMainResultSubKernelMemoryOptimizedFloats","src","artifact","replaceArtifacts","_getFragShaderArtifactMap","_getVertShaderArtifactMap","deleteBuffer","deleteFramebuffer","deleteShader","deleteProgram","idx","destroyExtensions","loseContext","WebGL2FunctionNode","WebGL2KernelValueBoolean","WebGL2KernelValueFloat","WebGL2KernelValueInteger","variablePrecision","getVariablePrecisionString","WebGL2KernelValueHTMLImage","WebGL2KernelValueDynamicHTMLImage","WebGL2KernelValueHTMLImageArray","TEXTURE_2D_ARRAY","texImage3D","xOffset","yOffset","imageDepth","texSubImage3D","WebGL2KernelValueDynamicHTMLImageArray","WebGL2KernelValueHTMLVideo","WebGL2KernelValueDynamicHTMLVideo","WebGL2KernelValueSingleInput","RGBA32F","WebGL2KernelValueDynamicMemoryOptimizedNumberTexture","WebGL2KernelValueNumberTexture","WebGL2KernelValueDynamicNumberTexture","WebGL2KernelValueSingleArray","WebGL2KernelValueSingleArray1DI","WebGL2KernelValueDynamicSingleArray1DI","WebGL2KernelValueSingleArray2DI","WebGL2KernelValueDynamicSingleArray2DI","WebGL2KernelValueSingleArray3DI","WebGL2KernelValueDynamicSingleArray3DI","WebGL2KernelValueSingleArray2","WebGL2KernelValueSingleArray3","WebGL2KernelValueSingleArray4","WebGL2Kernel","EXT_color_buffer_float","WebGL2RenderingContext","getMaxTextureSize","MAX_DRAW_BUFFERS","MAX_TEXTURE_SIZE","texStorage2D","R32F","RG32F","bindKernelToShortcut","shortcut","allPropertiesOf","__defineGetter__","__defineSetter__","kernelOrder","kernelTypes","internalKernels","webgl2","webgl","upgradeDeprecatedCreateKernelSettings","upgradedSettings","floatOutput","outputToTexture","outputImmutable","lib","isGPUSupported","isKernelMapSupported","isOffscreenCanvasSupported","Worker","importScripts","isWebGLSupported","isWebGL2Supported","isHeadlessGLSupported","isCanvasSupported","HTMLCanvasElement","isGPUHTMLImageArraySupported","isSinglePrecisionSupported","kernels","chooseKernel","addFunction","addNativeFunction","ExternalKernel","devKernel","gpuMock","switchableKernels","settingsCopy","fallbackKernel","kernelRun","dynamicArgument","replaceKernel","mergedSettings","existingKernel","newKernel","accept","replacementKernel","kernelRunShortcut","createKernel","firstKernel","nativeFunctionArguments","nativeFunctionReturnType","setTimeout","destroyContext","alias","fnString","HeadlessGLKernel","common"],"mappings":"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"} \ No newline at end of file diff --git a/dist/gpu-browser.js b/dist/gpu-browser.js index a02e3462..cfd9dae4 100644 --- a/dist/gpu-browser.js +++ b/dist/gpu-browser.js @@ -1,18882 +1,16271 @@ /** * gpu.js - * http://gpu.rocks/ + * https://gpu.rocks/ * * GPU Accelerated JavaScript * * @version 2.0.5 - * @date Fri Oct 11 2019 07:23:33 GMT-0400 (Eastern Daylight Time) + * @date Tue Oct 29 2019 10:46:59 GMT-0400 (Eastern Daylight Time) * * @license MIT * The MIT License * * Copyright (c) 2019 gpu.js Team - */(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GPU = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i code) { return false } - pos += set[i + 1]; - if (pos >= code) { return true } - } -} - - -function isIdentifierStart(code, astral) { - if (code < 65) { return code === 36 } - if (code < 91) { return true } - if (code < 97) { return code === 95 } - if (code < 123) { return true } - if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } - if (astral === false) { return false } - return isInAstralSet(code, astralIdentifierStartCodes) -} - - -function isIdentifierChar(code, astral) { - if (code < 48) { return code === 36 } - if (code < 58) { return true } - if (code < 65) { return false } - if (code < 91) { return true } - if (code < 97) { return code === 95 } - if (code < 123) { return true } - if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } - if (astral === false) { return false } - return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) -} - - - - - -var TokenType = function TokenType(label, conf) { - if ( conf === void 0 ) conf = {}; - - this.label = label; - this.keyword = conf.keyword; - this.beforeExpr = !!conf.beforeExpr; - this.startsExpr = !!conf.startsExpr; - this.isLoop = !!conf.isLoop; - this.isAssign = !!conf.isAssign; - this.prefix = !!conf.prefix; - this.postfix = !!conf.postfix; - this.binop = conf.binop || null; - this.updateContext = null; -}; - -function binop(name, prec) { - return new TokenType(name, {beforeExpr: true, binop: prec}) -} -var beforeExpr = {beforeExpr: true}; -var startsExpr = {startsExpr: true}; - - -var keywords$1 = {}; - -function kw(name, options) { - if ( options === void 0 ) options = {}; - - options.keyword = name; - return keywords$1[name] = new TokenType(name, options) -} - -var types = { - num: new TokenType("num", startsExpr), - regexp: new TokenType("regexp", startsExpr), - string: new TokenType("string", startsExpr), - name: new TokenType("name", startsExpr), - eof: new TokenType("eof"), - - bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), - bracketR: new TokenType("]"), - braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), - braceR: new TokenType("}"), - parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), - parenR: new TokenType(")"), - comma: new TokenType(",", beforeExpr), - semi: new TokenType(";", beforeExpr), - colon: new TokenType(":", beforeExpr), - dot: new TokenType("."), - question: new TokenType("?", beforeExpr), - arrow: new TokenType("=>", beforeExpr), - template: new TokenType("template"), - invalidTemplate: new TokenType("invalidTemplate"), - ellipsis: new TokenType("...", beforeExpr), - backQuote: new TokenType("`", startsExpr), - dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), - - - eq: new TokenType("=", {beforeExpr: true, isAssign: true}), - assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), - incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), - prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), - logicalOR: binop("||", 1), - logicalAND: binop("&&", 2), - bitwiseOR: binop("|", 3), - bitwiseXOR: binop("^", 4), - bitwiseAND: binop("&", 5), - equality: binop("==/!=/===/!==", 6), - relational: binop("/<=/>=", 7), - bitShift: binop("<>/>>>", 8), - plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), - modulo: binop("%", 10), - star: binop("*", 10), - slash: binop("/", 10), - starstar: new TokenType("**", {beforeExpr: true}), - - _break: kw("break"), - _case: kw("case", beforeExpr), - _catch: kw("catch"), - _continue: kw("continue"), - _debugger: kw("debugger"), - _default: kw("default", beforeExpr), - _do: kw("do", {isLoop: true, beforeExpr: true}), - _else: kw("else", beforeExpr), - _finally: kw("finally"), - _for: kw("for", {isLoop: true}), - _function: kw("function", startsExpr), - _if: kw("if"), - _return: kw("return", beforeExpr), - _switch: kw("switch"), - _throw: kw("throw", beforeExpr), - _try: kw("try"), - _var: kw("var"), - _const: kw("const"), - _while: kw("while", {isLoop: true}), - _with: kw("with"), - _new: kw("new", {beforeExpr: true, startsExpr: true}), - _this: kw("this", startsExpr), - _super: kw("super", startsExpr), - _class: kw("class", startsExpr), - _extends: kw("extends", beforeExpr), - _export: kw("export"), - _import: kw("import"), - _null: kw("null", startsExpr), - _true: kw("true", startsExpr), - _false: kw("false", startsExpr), - _in: kw("in", {beforeExpr: true, binop: 7}), - _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), - _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), - _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), - _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) -}; - - -var lineBreak = /\r\n?|\n|\u2028|\u2029/; -var lineBreakG = new RegExp(lineBreak.source, "g"); - -function isNewLine(code, ecma2019String) { - return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029)) -} - -var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; - -var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; - -var ref = Object.prototype; -var hasOwnProperty = ref.hasOwnProperty; -var toString = ref.toString; - - -function has(obj, propName) { - return hasOwnProperty.call(obj, propName) -} - -var isArray = Array.isArray || (function (obj) { return ( - toString.call(obj) === "[object Array]" -); }); - - -var Position = function Position(line, col) { - this.line = line; - this.column = col; -}; - -Position.prototype.offset = function offset (n) { - return new Position(this.line, this.column + n) -}; - -var SourceLocation = function SourceLocation(p, start, end) { - this.start = start; - this.end = end; - if (p.sourceFile !== null) { this.source = p.sourceFile; } -}; - - -function getLineInfo(input, offset) { - for (var line = 1, cur = 0;;) { - lineBreakG.lastIndex = cur; - var match = lineBreakG.exec(input); - if (match && match.index < offset) { - ++line; - cur = match.index + match[0].length; - } else { - return new Position(line, offset - cur) + function setupArguments(args) { + const newArguments = new Array(args.length); + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + if (arg.toArray) { + newArguments[i] = arg.toArray(); + } else { + newArguments[i] = arg; + } } + return newArguments; } -} - - -var defaultOptions = { - ecmaVersion: 7, - sourceType: "script", - onInsertedSemicolon: null, - onTrailingComma: null, - allowReserved: null, - allowReturnOutsideFunction: false, - allowImportExportEverywhere: false, - allowAwaitOutsideFunction: false, - allowHashBang: false, - locations: false, - onToken: null, - onComment: null, - ranges: false, - program: null, - sourceFile: null, - directSourceFile: null, - preserveParens: false, - plugins: {} -}; - - -function getOptions(opts) { - var options = {}; - - for (var opt in defaultOptions) - { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } - - if (options.ecmaVersion >= 2015) - { options.ecmaVersion -= 2009; } - - if (options.allowReserved == null) - { options.allowReserved = options.ecmaVersion < 5; } - - if (isArray(options.onToken)) { - var tokens = options.onToken; - options.onToken = function (token) { return tokens.push(token); }; - } - if (isArray(options.onComment)) - { options.onComment = pushComment(options, options.onComment); } - - return options -} - -function pushComment(options, array) { - return function(block, text, start, end, startLoc, endLoc) { - var comment = { - type: block ? "Block" : "Line", - value: text, - start: start, - end: end - }; - if (options.locations) - { comment.loc = new SourceLocation(this, startLoc, endLoc); } - if (options.ranges) - { comment.range = [start, end]; } - array.push(comment); - } -} - -var plugins = {}; - -function keywordRegexp(words) { - return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") -} - -var Parser = function Parser(options, input, startPos) { - this.options = options = getOptions(options); - this.sourceFile = options.sourceFile; - this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]); - var reserved = ""; - if (!options.allowReserved) { - for (var v = options.ecmaVersion;; v--) - { if (reserved = reservedWords[v]) { break } } - if (options.sourceType === "module") { reserved += " await"; } - } - this.reservedWords = keywordRegexp(reserved); - var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; - this.reservedWordsStrict = keywordRegexp(reservedStrict); - this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind); - this.input = String(input); - - this.containsEsc = false; - - this.loadPlugins(options.plugins); - - - if (startPos) { - this.pos = startPos; - this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; - this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; - } else { - this.pos = this.lineStart = 0; - this.curLine = 1; - } - - this.type = types.eof; - this.value = null; - this.start = this.end = this.pos; - this.startLoc = this.endLoc = this.curPosition(); - - this.lastTokEndLoc = this.lastTokStartLoc = null; - this.lastTokStart = this.lastTokEnd = this.pos; - - this.context = this.initialContext(); - this.exprAllowed = true; - - this.inModule = options.sourceType === "module"; - this.strict = this.inModule || this.strictDirective(this.pos); - - this.potentialArrowAt = -1; - - this.inFunction = this.inGenerator = this.inAsync = false; - this.yieldPos = this.awaitPos = 0; - this.labels = []; - - if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") - { this.skipLineComment(2); } - - this.scopeStack = []; - this.enterFunctionScope(); - - this.regexpState = null; -}; - -Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; -Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; - -Parser.prototype.extend = function extend (name, f) { - this[name] = f(this[name]); -}; - -Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { - var this$1 = this; - - for (var name in pluginConfigs) { - var plugin = plugins[name]; - if (!plugin) { throw new Error("Plugin '" + name + "' not found") } - plugin(this$1, pluginConfigs[name]); - } -}; - -Parser.prototype.parse = function parse () { - var node = this.options.program || this.startNode(); - this.nextToken(); - return this.parseTopLevel(node) -}; - -var pp = Parser.prototype; - - -var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/; -pp.strictDirective = function(start) { - var this$1 = this; - - for (;;) { - skipWhiteSpace.lastIndex = start; - start += skipWhiteSpace.exec(this$1.input)[0].length; - var match = literal.exec(this$1.input.slice(start)); - if (!match) { return false } - if ((match[1] || match[2]) === "use strict") { return true } - start += match[0].length; - } -}; - - -pp.eat = function(type) { - if (this.type === type) { - this.next(); - return true - } else { - return false - } -}; - - -pp.isContextual = function(name) { - return this.type === types.name && this.value === name && !this.containsEsc -}; - - -pp.eatContextual = function(name) { - if (!this.isContextual(name)) { return false } - this.next(); - return true -}; - - -pp.expectContextual = function(name) { - if (!this.eatContextual(name)) { this.unexpected(); } -}; - - -pp.canInsertSemicolon = function() { - return this.type === types.eof || - this.type === types.braceR || - lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) -}; - -pp.insertSemicolon = function() { - if (this.canInsertSemicolon()) { - if (this.options.onInsertedSemicolon) - { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } - return true - } -}; - - -pp.semicolon = function() { - if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); } -}; - -pp.afterTrailingComma = function(tokType, notNext) { - if (this.type === tokType) { - if (this.options.onTrailingComma) - { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } - if (!notNext) - { this.next(); } - return true - } -}; - - -pp.expect = function(type) { - this.eat(type) || this.unexpected(); -}; - - -pp.unexpected = function(pos) { - this.raise(pos != null ? pos : this.start, "Unexpected token"); -}; - -function DestructuringErrors() { - this.shorthandAssign = - this.trailingComma = - this.parenthesizedAssign = - this.parenthesizedBind = - this.doubleProto = - -1; -} - -pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { - if (!refDestructuringErrors) { return } - if (refDestructuringErrors.trailingComma > -1) - { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } - var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; - if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); } -}; - -pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { - if (!refDestructuringErrors) { return false } - var shorthandAssign = refDestructuringErrors.shorthandAssign; - var doubleProto = refDestructuringErrors.doubleProto; - if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } - if (shorthandAssign >= 0) - { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } - if (doubleProto >= 0) - { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } -}; - -pp.checkYieldAwaitInDefaultParams = function() { - if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) - { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } - if (this.awaitPos) - { this.raise(this.awaitPos, "Await expression cannot be a default value"); } -}; - -pp.isSimpleAssignTarget = function(expr) { - if (expr.type === "ParenthesizedExpression") - { return this.isSimpleAssignTarget(expr.expression) } - return expr.type === "Identifier" || expr.type === "MemberExpression" -}; - -var pp$1 = Parser.prototype; - - - -pp$1.parseTopLevel = function(node) { - var this$1 = this; - - var exports = {}; - if (!node.body) { node.body = []; } - while (this.type !== types.eof) { - var stmt = this$1.parseStatement(true, true, exports); - node.body.push(stmt); - } - this.adaptDirectivePrologue(node.body); - this.next(); - if (this.options.ecmaVersion >= 6) { - node.sourceType = this.options.sourceType; - } - return this.finishNode(node, "Program") -}; - -var loopLabel = {kind: "loop"}; -var switchLabel = {kind: "switch"}; - -pp$1.isLet = function() { - if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } - skipWhiteSpace.lastIndex = this.pos; - var skip = skipWhiteSpace.exec(this.input); - var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); - if (nextCh === 91 || nextCh === 123) { return true } - if (isIdentifierStart(nextCh, true)) { - var pos = next + 1; - while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; } - var ident = this.input.slice(next, pos); - if (!keywordRelationalOperator.test(ident)) { return true } - } - return false -}; - -pp$1.isAsyncFunction = function() { - if (this.options.ecmaVersion < 8 || !this.isContextual("async")) - { return false } - - skipWhiteSpace.lastIndex = this.pos; - var skip = skipWhiteSpace.exec(this.input); - var next = this.pos + skip[0].length; - return !lineBreak.test(this.input.slice(this.pos, next)) && - this.input.slice(next, next + 8) === "function" && - (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) -}; - - -pp$1.parseStatement = function(declaration, topLevel, exports) { - var starttype = this.type, node = this.startNode(), kind; - - if (this.isLet()) { - starttype = types._var; - kind = "let"; - } - - - switch (starttype) { - case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword) - case types._debugger: return this.parseDebuggerStatement(node) - case types._do: return this.parseDoStatement(node) - case types._for: return this.parseForStatement(node) - case types._function: - if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); } - return this.parseFunctionStatement(node, false) - case types._class: - if (!declaration) { this.unexpected(); } - return this.parseClass(node, true) - case types._if: return this.parseIfStatement(node) - case types._return: return this.parseReturnStatement(node) - case types._switch: return this.parseSwitchStatement(node) - case types._throw: return this.parseThrowStatement(node) - case types._try: return this.parseTryStatement(node) - case types._const: case types._var: - kind = kind || this.value; - if (!declaration && kind !== "var") { this.unexpected(); } - return this.parseVarStatement(node, kind) - case types._while: return this.parseWhileStatement(node) - case types._with: return this.parseWithStatement(node) - case types.braceL: return this.parseBlock() - case types.semi: return this.parseEmptyStatement(node) - case types._export: - case types._import: - if (!this.options.allowImportExportEverywhere) { - if (!topLevel) - { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } - if (!this.inModule) - { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } - } - return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports) - - default: - if (this.isAsyncFunction()) { - if (!declaration) { this.unexpected(); } - this.next(); - return this.parseFunctionStatement(node, true) + function mock1D() { + const args = setupArguments(arguments); + const row = new Float32Array(this.output.x); + for (let x = 0; x < this.output.x; x++) { + this.thread.x = x; + this.thread.y = 0; + this.thread.z = 0; + row[x] = this._fn.apply(this, args); } - - var maybeName = this.value, expr = this.parseExpression(); - if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) - { return this.parseLabeledStatement(node, maybeName, expr) } - else { return this.parseExpressionStatement(node, expr) } - } -}; - -pp$1.parseBreakContinueStatement = function(node, keyword) { - var this$1 = this; - - var isBreak = keyword === "break"; - this.next(); - if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; } - else if (this.type !== types.name) { this.unexpected(); } - else { - node.label = this.parseIdent(); - this.semicolon(); + return row; } - - var i = 0; - for (; i < this.labels.length; ++i) { - var lab = this$1.labels[i]; - if (node.label == null || lab.name === node.label.name) { - if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } - if (node.label && isBreak) { break } + function mock2D() { + const args = setupArguments(arguments); + const matrix = new Array(this.output.y); + for (let y = 0; y < this.output.y; y++) { + const row = new Float32Array(this.output.x); + for (let x = 0; x < this.output.x; x++) { + this.thread.x = x; + this.thread.y = y; + this.thread.z = 0; + row[x] = this._fn.apply(this, args); + } + matrix[y] = row; } + return matrix; } - if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } - return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") -}; - -pp$1.parseDebuggerStatement = function(node) { - this.next(); - this.semicolon(); - return this.finishNode(node, "DebuggerStatement") -}; - -pp$1.parseDoStatement = function(node) { - this.next(); - this.labels.push(loopLabel); - node.body = this.parseStatement(false); - this.labels.pop(); - this.expect(types._while); - node.test = this.parseParenExpression(); - if (this.options.ecmaVersion >= 6) - { this.eat(types.semi); } - else - { this.semicolon(); } - return this.finishNode(node, "DoWhileStatement") -}; - - -pp$1.parseForStatement = function(node) { - this.next(); - var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1; - this.labels.push(loopLabel); - this.enterLexicalScope(); - this.expect(types.parenL); - if (this.type === types.semi) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, null) + function mock2DGraphical() { + const args = setupArguments(arguments); + for (let y = 0; y < this.output.y; y++) { + for (let x = 0; x < this.output.x; x++) { + this.thread.x = x; + this.thread.y = y; + this.thread.z = 0; + this._fn.apply(this, args); + } + } } - var isLet = this.isLet(); - if (this.type === types._var || this.type === types._const || isLet) { - var init$1 = this.startNode(), kind = isLet ? "let" : this.value; - this.next(); - this.parseVar(init$1, true, kind); - this.finishNode(init$1, "VariableDeclaration"); - if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && - !(kind !== "var" && init$1.declarations[0].init)) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } + function mock3D() { + const args = setupArguments(arguments); + const cube = new Array(this.output.z); + for (let z = 0; z < this.output.z; z++) { + const matrix = new Array(this.output.y); + for (let y = 0; y < this.output.y; y++) { + const row = new Float32Array(this.output.x); + for (let x = 0; x < this.output.x; x++) { + this.thread.x = x; + this.thread.y = y; + this.thread.z = z; + row[x] = this._fn.apply(this, args); + } + matrix[y] = row; } - return this.parseForIn(node, init$1) + cube[z] = matrix; } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init$1) + return cube; } - var refDestructuringErrors = new DestructuringErrors; - var init = this.parseExpression(true, refDestructuringErrors); - if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { - if (this.options.ecmaVersion >= 9) { - if (this.type === types._in) { - if (awaitAt > -1) { this.unexpected(awaitAt); } - } else { node.await = awaitAt > -1; } - } - this.toAssignable(init, false, refDestructuringErrors); - this.checkLVal(init); - return this.parseForIn(node, init) - } else { - this.checkExpressionErrors(refDestructuringErrors, true); + function apiDecorate(kernel) { + kernel.setOutput = (output) => { + kernel.output = setupOutput(output); + if (kernel.graphical) { + setupGraphical(kernel); + } + }; + kernel.toJSON = () => { + throw new Error('Not usable with gpuMock'); + }; + kernel.setConstants = (flag) => { + kernel.constants = flag; + return kernel; + }; + kernel.setGraphical = (flag) => { + kernel.graphical = flag; + return kernel; + }; + kernel.setCanvas = (flag) => { + kernel.canvas = flag; + return kernel; + }; + kernel.setContext = (flag) => { + kernel.context = flag; + return kernel; + }; + kernel.exec = function() { + return new Promise((resolve, reject) => { + try { + resolve(kernel.apply(kernel, arguments)); + } catch(e) { + reject(e); + } + }); + }; + kernel.getPixels = (flip) => { + const {x, y} = kernel.output; + return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0); + }; + kernel.color = function(r, g, b, a) { + if (typeof a === 'undefined') { + a = 1; + } + r = Math.floor(r * 255); + g = Math.floor(g * 255); + b = Math.floor(b * 255); + a = Math.floor(a * 255); + const width = kernel.output.x; + const height = kernel.output.y; + const x = kernel.thread.x; + const y = height - kernel.thread.y - 1; + const index = x + y * width; + kernel._colorData[index * 4 + 0] = r; + kernel._colorData[index * 4 + 1] = g; + kernel._colorData[index * 4 + 2] = b; + kernel._colorData[index * 4 + 3] = a; + }; + kernel.setWarnVarUsage = () => { + return kernel; + }; + kernel.setOptimizeFloatMemory = () => { + return kernel; + }; + kernel.setArgumentTypes = () => { + return kernel; + }; + kernel.setDebug = () => { + return kernel; + }; + kernel.setLoopMaxIterations = () => { + return kernel; + }; + kernel.setPipeline = () => { + return kernel; + }; + kernel.setPrecision = () => { + return kernel; + }; + kernel.setImmutable = () => { + return kernel; + }; + kernel.setFunctions = () => { + return kernel; + }; + kernel.addSubKernel = () => { + return kernel; + }; + kernel.destroy = () => {}; + kernel.validateSettings = () => {}; + if (kernel.graphical && kernel.output) { + setupGraphical(kernel); + } + return kernel; } - if (awaitAt > -1) { this.unexpected(awaitAt); } - return this.parseFor(node, init) -}; - -pp$1.parseFunctionStatement = function(node, isAsync) { - this.next(); - return this.parseFunction(node, true, false, isAsync) -}; - -pp$1.parseIfStatement = function(node) { - this.next(); - node.test = this.parseParenExpression(); - node.consequent = this.parseStatement(!this.strict && this.type === types._function); - node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : null; - return this.finishNode(node, "IfStatement") -}; - -pp$1.parseReturnStatement = function(node) { - if (!this.inFunction && !this.options.allowReturnOutsideFunction) - { this.raise(this.start, "'return' outside of function"); } - this.next(); - - - if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; } - else { node.argument = this.parseExpression(); this.semicolon(); } - return this.finishNode(node, "ReturnStatement") -}; - -pp$1.parseSwitchStatement = function(node) { - var this$1 = this; - - this.next(); - node.discriminant = this.parseParenExpression(); - node.cases = []; - this.expect(types.braceL); - this.labels.push(switchLabel); - this.enterLexicalScope(); - - - var cur; - for (var sawDefault = false; this.type !== types.braceR;) { - if (this$1.type === types._case || this$1.type === types._default) { - var isCase = this$1.type === types._case; - if (cur) { this$1.finishNode(cur, "SwitchCase"); } - node.cases.push(cur = this$1.startNode()); - cur.consequent = []; - this$1.next(); - if (isCase) { - cur.test = this$1.parseExpression(); + function setupGraphical(kernel) { + const {x, y} = kernel.output; + if (kernel.context && kernel.context.createImageData) { + const data = new Uint8ClampedArray(x * y * 4); + kernel._imageData = kernel.context.createImageData(x, y); + kernel._colorData = data; + } else { + const data = new Uint8ClampedArray(x * y * 4); + kernel._imageData = { data }; + kernel._colorData = data; + } + } + function setupOutput(output) { + let result = null; + if (output.length) { + if (output.length === 3) { + const [x,y,z] = output; + result = { x, y, z }; + } else if (output.length === 2) { + const [x,y] = output; + result = { x, y }; } else { - if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); } - sawDefault = true; - cur.test = null; + const [x] = output; + result = { x }; } - this$1.expect(types.colon); } else { - if (!cur) { this$1.unexpected(); } - cur.consequent.push(this$1.parseStatement(true)); + result = output; } + return result; } - this.exitLexicalScope(); - if (cur) { this.finishNode(cur, "SwitchCase"); } - this.next(); - this.labels.pop(); - return this.finishNode(node, "SwitchStatement") -}; - -pp$1.parseThrowStatement = function(node) { - this.next(); - if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) - { this.raise(this.lastTokEnd, "Illegal newline after throw"); } - node.argument = this.parseExpression(); - this.semicolon(); - return this.finishNode(node, "ThrowStatement") -}; - - -var empty = []; - -pp$1.parseTryStatement = function(node) { - this.next(); - node.block = this.parseBlock(); - node.handler = null; - if (this.type === types._catch) { - var clause = this.startNode(); - this.next(); - if (this.eat(types.parenL)) { - clause.param = this.parseBindingAtom(); - this.enterLexicalScope(); - this.checkLVal(clause.param, "let"); - this.expect(types.parenR); - } else { - if (this.options.ecmaVersion < 10) { this.unexpected(); } - clause.param = null; - this.enterLexicalScope(); + function gpuMock(fn, settings = {}) { + const output = settings.output ? setupOutput(settings.output) : null; + function kernel() { + if (kernel.output.z) { + return mock3D.apply(kernel, arguments); + } else if (kernel.output.y) { + if (kernel.graphical) { + return mock2DGraphical.apply(kernel, arguments); + } + return mock2D.apply(kernel, arguments); + } else { + return mock1D.apply(kernel, arguments); + } + } + kernel._fn = fn; + kernel.constants = settings.constants || null; + kernel.context = settings.context || null; + kernel.canvas = settings.canvas || null; + kernel.graphical = settings.graphical || false; + kernel._imageData = null; + kernel._colorData = null; + kernel.output = output; + kernel.thread = { + x: 0, + y: 0, + z: 0 + }; + return apiDecorate(kernel); + } + function flipPixels(pixels, width, height) { + const halfHeight = height / 2 | 0; + const bytesPerRow = width * 4; + const temp = new Uint8ClampedArray(width * 4); + const result = pixels.slice(0); + for (let y = 0; y < halfHeight; ++y) { + const topOffset = y * bytesPerRow; + const bottomOffset = (height - y - 1) * bytesPerRow; + temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); + result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); + result.set(temp, bottomOffset); } - clause.body = this.parseBlock(false); - this.exitLexicalScope(); - node.handler = this.finishNode(clause, "CatchClause"); + return result; } - node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; - if (!node.handler && !node.finalizer) - { this.raise(node.start, "Missing catch or finally clause"); } - return this.finishNode(node, "TryStatement") -}; + var gpuMock_js = { + gpuMock + }; + var gpuMock_js_1 = gpuMock_js.gpuMock; -pp$1.parseVarStatement = function(node, kind) { - this.next(); - this.parseVar(node, false, kind); - this.semicolon(); - return this.finishNode(node, "VariableDeclaration") -}; - -pp$1.parseWhileStatement = function(node) { - this.next(); - node.test = this.parseParenExpression(); - this.labels.push(loopLabel); - node.body = this.parseStatement(false); - this.labels.pop(); - return this.finishNode(node, "WhileStatement") -}; - -pp$1.parseWithStatement = function(node) { - if (this.strict) { this.raise(this.start, "'with' in strict mode"); } - this.next(); - node.object = this.parseParenExpression(); - node.body = this.parseStatement(false); - return this.finishNode(node, "WithStatement") -}; - -pp$1.parseEmptyStatement = function(node) { - this.next(); - return this.finishNode(node, "EmptyStatement") -}; - -pp$1.parseLabeledStatement = function(node, maybeName, expr) { - var this$1 = this; - - for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1) - { - var label = list[i$1]; - - if (label.name === maybeName) - { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared"); - } } - var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null; - for (var i = this.labels.length - 1; i >= 0; i--) { - var label$1 = this$1.labels[i]; - if (label$1.statementStart === node.start) { - label$1.statementStart = this$1.start; - label$1.kind = kind; - } else { break } - } - this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); - node.body = this.parseStatement(true); - if (node.body.type === "ClassDeclaration" || - node.body.type === "VariableDeclaration" && node.body.kind !== "var" || - node.body.type === "FunctionDeclaration" && (this.strict || node.body.generator || node.body.async)) - { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); } - this.labels.pop(); - node.label = expr; - return this.finishNode(node, "LabeledStatement") -}; - -pp$1.parseExpressionStatement = function(node, expr) { - node.expression = expr; - this.semicolon(); - return this.finishNode(node, "ExpressionStatement") -}; - - -pp$1.parseBlock = function(createNewLexicalScope) { - var this$1 = this; - if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; - - var node = this.startNode(); - node.body = []; - this.expect(types.braceL); - if (createNewLexicalScope) { - this.enterLexicalScope(); - } - while (!this.eat(types.braceR)) { - var stmt = this$1.parseStatement(true); - node.body.push(stmt); - } - if (createNewLexicalScope) { - this.exitLexicalScope(); - } - return this.finishNode(node, "BlockStatement") -}; - - -pp$1.parseFor = function(node, init) { - node.init = init; - this.expect(types.semi); - node.test = this.type === types.semi ? null : this.parseExpression(); - this.expect(types.semi); - node.update = this.type === types.parenR ? null : this.parseExpression(); - this.expect(types.parenR); - this.exitLexicalScope(); - node.body = this.parseStatement(false); - this.labels.pop(); - return this.finishNode(node, "ForStatement") -}; - - -pp$1.parseForIn = function(node, init) { - var type = this.type === types._in ? "ForInStatement" : "ForOfStatement"; - this.next(); - if (type === "ForInStatement") { - if (init.type === "AssignmentPattern" || - (init.type === "VariableDeclaration" && init.declarations[0].init != null && - (this.strict || init.declarations[0].id.type !== "Identifier"))) - { this.raise(init.start, "Invalid assignment in for-in loop head"); } - } - node.left = init; - node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); - this.expect(types.parenR); - this.exitLexicalScope(); - node.body = this.parseStatement(false); - this.labels.pop(); - return this.finishNode(node, type) -}; - - -pp$1.parseVar = function(node, isFor, kind) { - var this$1 = this; - - node.declarations = []; - node.kind = kind; - for (;;) { - var decl = this$1.startNode(); - this$1.parseVarId(decl, kind); - if (this$1.eat(types.eq)) { - decl.init = this$1.parseMaybeAssign(isFor); - } else if (kind === "const" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { - this$1.unexpected(); - } else if (decl.id.type !== "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) { - this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value"); + const ARGUMENT_NAMES = /([^\s,]+)/g; + const FUNCTION_NAME = /function ([^(]*)/; + const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; + function isFunction(funcObj) { + return typeof(funcObj) === 'function'; + }function getFunctionNameFromString(funcStr) { + return FUNCTION_NAME.exec(funcStr)[1].trim(); + }function functionToIFunction(source, settings) { + settings = settings || {}; + if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function'); + const sourceString = typeof source === 'string' ? source : source.toString(); + let argumentTypes = []; + if (Array.isArray(settings.argumentTypes)) { + argumentTypes = settings.argumentTypes; + } else if (typeof settings.argumentTypes === 'object') { + argumentTypes = getArgumentNamesFromString(sourceString) + .map(name => settings.argumentTypes[name]) || []; } else { - decl.init = null; + argumentTypes = settings.argumentTypes || []; } - node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")); - if (!this$1.eat(types.comma)) { break } - } - return node -}; - -pp$1.parseVarId = function(decl, kind) { - decl.id = this.parseBindingAtom(kind); - this.checkLVal(decl.id, kind, false); -}; - - -pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { - this.initFunction(node); - if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) - { node.generator = this.eat(types.star); } - if (this.options.ecmaVersion >= 8) - { node.async = !!isAsync; } - - if (isStatement) { - node.id = isStatement === "nullableID" && this.type !== types.name ? null : this.parseIdent(); - if (node.id) { - this.checkLVal(node.id, this.inModule && !this.inFunction ? "let" : "var"); + return { + source: sourceString, + argumentTypes, + returnType: settings.returnType || null, + }; + }function warnDeprecated(type, oldName, newName) { + const msg = newName + ? `It has been replaced with "${ newName }"` + : 'It has been removed'; + console.warn(`You are using a deprecated ${ type } "${ oldName }". ${msg}. Fixing, but please upgrade as it will soon be removed.`); + }function isFunctionString(fn) { + if (typeof fn === 'string') { + return (fn + .slice(0, 'function'.length) + .toLowerCase() === 'function'); + } + return false; + }function getArgumentNamesFromString(fn) { + const fnStr = fn.replace(STRIP_COMMENTS, ''); + let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); + if (result === null) { + result = []; + } + return result; + }function isArray(array) { + return !isNaN(array.length); + }function erectMemoryOptimized2DFloat(array, width, height) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const offset = y * width; + yResults[y] = array.subarray(offset, offset + width); + } + return yResults; + }function erectMemoryOptimized3DFloat(array, width, height, depth) { + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const offset = (z * height * width) + (y * width); + yResults[y] = array.subarray(offset, offset + width); + } + zResults[z] = yResults; + } + return zResults; + }function getAstString(source, ast) { + const lines = Array.isArray(source) ? source : source.split(/\r?\n/g); + const start = ast.loc.start; + const end = ast.loc.end; + const result = []; + if (start.line === end.line) { + result.push(lines[start.line - 1].substring(start.column, end.column)); + } else { + result.push(lines[start.line - 1].slice(start.column)); + for (let i = start.line; i < end.line; i++) { + result.push(lines[i]); + } + result.push(lines[end.line - 1].slice(0, end.column)); } + return result.join('\n'); } - var oldInGen = this.inGenerator, oldInAsync = this.inAsync, - oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; - this.inGenerator = node.generator; - this.inAsync = node.async; - this.yieldPos = 0; - this.awaitPos = 0; - this.inFunction = true; - this.enterFunctionScope(); - - if (!isStatement) - { node.id = this.type === types.name ? this.parseIdent() : null; } - - this.parseFunctionParams(node); - this.parseFunctionBody(node, allowExpressionBody); - - this.inGenerator = oldInGen; - this.inAsync = oldInAsync; - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.inFunction = oldInFunc; - return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") -}; - -pp$1.parseFunctionParams = function(node) { - this.expect(types.parenL); - node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); - this.checkYieldAwaitInDefaultParams(); -}; - - -pp$1.parseClass = function(node, isStatement) { - var this$1 = this; - - this.next(); + var common = /*#__PURE__*/Object.freeze({ + isFunction: isFunction, + getFunctionNameFromString: getFunctionNameFromString, + functionToIFunction: functionToIFunction, + warnDeprecated: warnDeprecated, + isFunctionString: isFunctionString, + getArgumentNamesFromString: getArgumentNamesFromString, + isArray: isArray, + erectMemoryOptimized2DFloat: erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat: erectMemoryOptimized3DFloat, + getAstString: getAstString + }); - this.parseClassId(node, isStatement); - this.parseClassSuper(node); - var classBody = this.startNode(); - var hadConstructor = false; - classBody.body = []; - this.expect(types.braceL); - while (!this.eat(types.braceR)) { - var member = this$1.parseClassMember(classBody); - if (member && member.type === "MethodDefinition" && member.kind === "constructor") { - if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); } - hadConstructor = true; + class Input { + constructor(value, size) { + this.value = value; + if (Array.isArray(size)) { + this.size = size; + } else { + this.size = new Int32Array(3); + if (size.z) { + this.size = new Int32Array([size.x, size.y, size.z]); + } else if (size.y) { + this.size = new Int32Array([size.x, size.y]); + } else { + this.size = new Int32Array([size.x]); + } + } + const [w, h, d] = this.size; + if (d) { + if (this.value.length !== (w * h * d)) { + throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`); + } + } else if (h) { + if (this.value.length !== (w * h)) { + throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`); + } + } else { + if (this.value.length !== w) { + throw new Error(`Input size ${this.value.length} does not match ${w}`); + } + } } + toArray() { + const [ w, h, d ] = this.size; + if (d) { + return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); + } else if (h) { + return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h); + } else { + return this.value; + } + } + }function input(value, size) { + return new Input(value, size); } - node.body = this.finishNode(classBody, "ClassBody"); - return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") -}; - -pp$1.parseClassMember = function(classBody) { - var this$1 = this; - if (this.eat(types.semi)) { return null } - - var method = this.startNode(); - var tryContextual = function (k, noLineBreak) { - if ( noLineBreak === void 0 ) noLineBreak = false; - - var start = this$1.start, startLoc = this$1.startLoc; - if (!this$1.eatContextual(k)) { return false } - if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } - if (method.key) { this$1.unexpected(); } - method.computed = false; - method.key = this$1.startNodeAt(start, startLoc); - method.key.name = k; - this$1.finishNode(method.key, "Identifier"); - return false + var reservedWords = { + 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile", + 5: "class enum extends super const export import", + 6: "enum", + strict: "implements interface let package private protected public static yield", + strictBind: "eval arguments" }; - - method.kind = "method"; - method.static = tryContextual("static"); - var isGenerator = this.eat(types.star); - var isAsync = false; - if (!isGenerator) { - if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { - isAsync = true; - isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); - } else if (tryContextual("get")) { - method.kind = "get"; - } else if (tryContextual("set")) { - method.kind = "set"; + var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this"; + var keywords = { + 5: ecma5AndLessKeywords, + 6: ecma5AndLessKeywords + " const class extends export import super" + }; + var keywordRelationalOperator = /^in(stanceof)?$/; + var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7b9\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; + var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; + var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); + var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); + nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; + var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,190,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,26,230,43,117,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,68,12,0,67,12,65,1,31,6129,15,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541]; + var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239]; + function isInAstralSet(code, set) { + var pos = 0x10000; + for (var i = 0; i < set.length; i += 2) { + pos += set[i]; + if (pos > code) { return false } + pos += set[i + 1]; + if (pos >= code) { return true } + } + } + function isIdentifierStart(code, astral) { + if (code < 65) { return code === 36 } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) + } + function isIdentifierChar(code, astral) { + if (code < 48) { return code === 36 } + if (code < 58) { return true } + if (code < 65) { return false } + if (code < 91) { return true } + if (code < 97) { return code === 95 } + if (code < 123) { return true } + if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) } + if (astral === false) { return false } + return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes) + } + var TokenType = function TokenType(label, conf) { + if ( conf === void 0 ) conf = {}; + this.label = label; + this.keyword = conf.keyword; + this.beforeExpr = !!conf.beforeExpr; + this.startsExpr = !!conf.startsExpr; + this.isLoop = !!conf.isLoop; + this.isAssign = !!conf.isAssign; + this.prefix = !!conf.prefix; + this.postfix = !!conf.postfix; + this.binop = conf.binop || null; + this.updateContext = null; + }; + function binop(name, prec) { + return new TokenType(name, {beforeExpr: true, binop: prec}) + } + var beforeExpr = {beforeExpr: true}; + var startsExpr = {startsExpr: true}; + var keywords$1 = {}; + function kw(name, options) { + if ( options === void 0 ) options = {}; + options.keyword = name; + return keywords$1[name] = new TokenType(name, options) + } + var types = { + num: new TokenType("num", startsExpr), + regexp: new TokenType("regexp", startsExpr), + string: new TokenType("string", startsExpr), + name: new TokenType("name", startsExpr), + eof: new TokenType("eof"), + bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}), + bracketR: new TokenType("]"), + braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}), + braceR: new TokenType("}"), + parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}), + parenR: new TokenType(")"), + comma: new TokenType(",", beforeExpr), + semi: new TokenType(";", beforeExpr), + colon: new TokenType(":", beforeExpr), + dot: new TokenType("."), + question: new TokenType("?", beforeExpr), + arrow: new TokenType("=>", beforeExpr), + template: new TokenType("template"), + invalidTemplate: new TokenType("invalidTemplate"), + ellipsis: new TokenType("...", beforeExpr), + backQuote: new TokenType("`", startsExpr), + dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}), + eq: new TokenType("=", {beforeExpr: true, isAssign: true}), + assign: new TokenType("_=", {beforeExpr: true, isAssign: true}), + incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}), + prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}), + logicalOR: binop("||", 1), + logicalAND: binop("&&", 2), + bitwiseOR: binop("|", 3), + bitwiseXOR: binop("^", 4), + bitwiseAND: binop("&", 5), + equality: binop("==/!=/===/!==", 6), + relational: binop("/<=/>=", 7), + bitShift: binop("<>/>>>", 8), + plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}), + modulo: binop("%", 10), + star: binop("*", 10), + slash: binop("/", 10), + starstar: new TokenType("**", {beforeExpr: true}), + _break: kw("break"), + _case: kw("case", beforeExpr), + _catch: kw("catch"), + _continue: kw("continue"), + _debugger: kw("debugger"), + _default: kw("default", beforeExpr), + _do: kw("do", {isLoop: true, beforeExpr: true}), + _else: kw("else", beforeExpr), + _finally: kw("finally"), + _for: kw("for", {isLoop: true}), + _function: kw("function", startsExpr), + _if: kw("if"), + _return: kw("return", beforeExpr), + _switch: kw("switch"), + _throw: kw("throw", beforeExpr), + _try: kw("try"), + _var: kw("var"), + _const: kw("const"), + _while: kw("while", {isLoop: true}), + _with: kw("with"), + _new: kw("new", {beforeExpr: true, startsExpr: true}), + _this: kw("this", startsExpr), + _super: kw("super", startsExpr), + _class: kw("class", startsExpr), + _extends: kw("extends", beforeExpr), + _export: kw("export"), + _import: kw("import"), + _null: kw("null", startsExpr), + _true: kw("true", startsExpr), + _false: kw("false", startsExpr), + _in: kw("in", {beforeExpr: true, binop: 7}), + _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}), + _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}), + _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}), + _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true}) + }; + var lineBreak = /\r\n?|\n|\u2028|\u2029/; + var lineBreakG = new RegExp(lineBreak.source, "g"); + function isNewLine(code, ecma2019String) { + return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029)) + } + var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + var ref = Object.prototype; + var hasOwnProperty = ref.hasOwnProperty; + var toString = ref.toString; + function has(obj, propName) { + return hasOwnProperty.call(obj, propName) + } + var isArray$1 = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" + ); }); + var Position = function Position(line, col) { + this.line = line; + this.column = col; + }; + Position.prototype.offset = function offset (n) { + return new Position(this.line, this.column + n) + }; + var SourceLocation = function SourceLocation(p, start, end) { + this.start = start; + this.end = end; + if (p.sourceFile !== null) { this.source = p.sourceFile; } + }; + function getLineInfo(input, offset) { + for (var line = 1, cur = 0;;) { + lineBreakG.lastIndex = cur; + var match = lineBreakG.exec(input); + if (match && match.index < offset) { + ++line; + cur = match.index + match[0].length; + } else { + return new Position(line, offset - cur) + } + } + } + var defaultOptions = { + ecmaVersion: 7, + sourceType: "script", + onInsertedSemicolon: null, + onTrailingComma: null, + allowReserved: null, + allowReturnOutsideFunction: false, + allowImportExportEverywhere: false, + allowAwaitOutsideFunction: false, + allowHashBang: false, + locations: false, + onToken: null, + onComment: null, + ranges: false, + program: null, + sourceFile: null, + directSourceFile: null, + preserveParens: false, + plugins: {} + }; + function getOptions(opts) { + var options = {}; + for (var opt in defaultOptions) + { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; } + if (options.ecmaVersion >= 2015) + { options.ecmaVersion -= 2009; } + if (options.allowReserved == null) + { options.allowReserved = options.ecmaVersion < 5; } + if (isArray$1(options.onToken)) { + var tokens = options.onToken; + options.onToken = function (token) { return tokens.push(token); }; + } + if (isArray$1(options.onComment)) + { options.onComment = pushComment(options, options.onComment); } + return options + } + function pushComment(options, array) { + return function(block, text, start, end, startLoc, endLoc) { + var comment = { + type: block ? "Block" : "Line", + value: text, + start: start, + end: end + }; + if (options.locations) + { comment.loc = new SourceLocation(this, startLoc, endLoc); } + if (options.ranges) + { comment.range = [start, end]; } + array.push(comment); + } + } + var plugins = {}; + function keywordRegexp(words) { + return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") + } + var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]); + var reserved = ""; + if (!options.allowReserved) { + for (var v = options.ecmaVersion;; v--) + { if (reserved = reservedWords[v]) { break } } + if (options.sourceType === "module") { reserved += " await"; } + } + this.reservedWords = keywordRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = keywordRegexp(reservedStrict); + this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); + this.containsEsc = false; + this.loadPlugins(options.plugins); + if (startPos) { + this.pos = startPos; + this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1; + this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length; + } else { + this.pos = this.lineStart = 0; + this.curLine = 1; + } + this.type = types.eof; + this.value = null; + this.start = this.end = this.pos; + this.startLoc = this.endLoc = this.curPosition(); + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + this.context = this.initialContext(); + this.exprAllowed = true; + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); + this.potentialArrowAt = -1; + this.inFunction = this.inGenerator = this.inAsync = false; + this.yieldPos = this.awaitPos = 0; + this.labels = []; + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } + this.scopeStack = []; + this.enterFunctionScope(); + this.regexpState = null; + }; + Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) }; + Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) }; + Parser.prototype.extend = function extend (name, f) { + this[name] = f(this[name]); + }; + Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) { + var this$1 = this; + for (var name in pluginConfigs) { + var plugin = plugins[name]; + if (!plugin) { throw new Error("Plugin '" + name + "' not found") } + plugin(this$1, pluginConfigs[name]); } - } - if (!method.key) { this.parsePropertyName(method); } - var key = method.key; - if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || - key.type === "Literal" && key.value === "constructor")) { - if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } - if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } - if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } - method.kind = "constructor"; - } else if (method.static && key.type === "Identifier" && key.name === "prototype") { - this.raise(key.start, "Classes may not have a static property named prototype"); - } - this.parseClassMethod(classBody, method, isGenerator, isAsync); - if (method.kind === "get" && method.value.params.length !== 0) - { this.raiseRecoverable(method.value.start, "getter should have no params"); } - if (method.kind === "set" && method.value.params.length !== 1) - { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } - if (method.kind === "set" && method.value.params[0].type === "RestElement") - { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } - return method -}; - -pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { - method.value = this.parseMethod(isGenerator, isAsync); - classBody.body.push(this.finishNode(method, "MethodDefinition")); -}; - -pp$1.parseClassId = function(node, isStatement) { - node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null; -}; - -pp$1.parseClassSuper = function(node) { - node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; -}; - - -pp$1.parseExport = function(node, exports) { - var this$1 = this; - - this.next(); - if (this.eat(types.star)) { - this.expectContextual("from"); - if (this.type !== types.string) { this.unexpected(); } - node.source = this.parseExprAtom(); - this.semicolon(); - return this.finishNode(node, "ExportAllDeclaration") - } - if (this.eat(types._default)) { - this.checkExport(exports, "default", this.lastTokStart); - var isAsync; - if (this.type === types._function || (isAsync = this.isAsyncFunction())) { - var fNode = this.startNode(); + }; + Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) + }; + var pp = Parser.prototype; + var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/; + pp.strictDirective = function(start) { + var this$1 = this; + for (;;) { + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this$1.input)[0].length; + var match = literal.exec(this$1.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { return true } + start += match[0].length; + } + }; + pp.eat = function(type) { + if (this.type === type) { this.next(); - if (isAsync) { this.next(); } - node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync); - } else if (this.type === types._class) { - var cNode = this.startNode(); - node.declaration = this.parseClass(cNode, "nullableID"); + return true } else { - node.declaration = this.parseMaybeAssign(); + return false + } + }; + pp.isContextual = function(name) { + return this.type === types.name && this.value === name && !this.containsEsc + }; + pp.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true + }; + pp.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } + }; + pp.canInsertSemicolon = function() { + return this.type === types.eof || + this.type === types.braceR || + lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + pp.insertSemicolon = function() { + if (this.canInsertSemicolon()) { + if (this.options.onInsertedSemicolon) + { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); } + return true + } + }; + pp.semicolon = function() { + if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); } + }; + pp.afterTrailingComma = function(tokType, notNext) { + if (this.type === tokType) { + if (this.options.onTrailingComma) + { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); } + if (!notNext) + { this.next(); } + return true + } + }; + pp.expect = function(type) { + this.eat(type) || this.unexpected(); + }; + pp.unexpected = function(pos) { + this.raise(pos != null ? pos : this.start, "Unexpected token"); + }; + function DestructuringErrors() { + this.shorthandAssign = + this.trailingComma = + this.parenthesizedAssign = + this.parenthesizedBind = + this.doubleProto = + -1; + } + pp.checkPatternErrors = function(refDestructuringErrors, isAssign) { + if (!refDestructuringErrors) { return } + if (refDestructuringErrors.trailingComma > -1) + { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); } + var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind; + if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); } + }; + pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) { + if (!refDestructuringErrors) { return false } + var shorthandAssign = refDestructuringErrors.shorthandAssign; + var doubleProto = refDestructuringErrors.doubleProto; + if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 } + if (shorthandAssign >= 0) + { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); } + if (doubleProto >= 0) + { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); } + }; + pp.checkYieldAwaitInDefaultParams = function() { + if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos)) + { this.raise(this.yieldPos, "Yield expression cannot be a default value"); } + if (this.awaitPos) + { this.raise(this.awaitPos, "Await expression cannot be a default value"); } + }; + pp.isSimpleAssignTarget = function(expr) { + if (expr.type === "ParenthesizedExpression") + { return this.isSimpleAssignTarget(expr.expression) } + return expr.type === "Identifier" || expr.type === "MemberExpression" + }; + var pp$1 = Parser.prototype; + pp$1.parseTopLevel = function(node) { + var this$1 = this; + var exports = {}; + if (!node.body) { node.body = []; } + while (this.type !== types.eof) { + var stmt = this$1.parseStatement(true, true, exports); + node.body.push(stmt); + } + this.adaptDirectivePrologue(node.body); + this.next(); + if (this.options.ecmaVersion >= 6) { + node.sourceType = this.options.sourceType; + } + return this.finishNode(node, "Program") + }; + var loopLabel = {kind: "loop"}; + var switchLabel = {kind: "switch"}; + pp$1.isLet = function() { + if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 91 || nextCh === 123) { return true } + if (isIdentifierStart(nextCh, true)) { + var pos = next + 1; + while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; } + var ident = this.input.slice(next, pos); + if (!keywordRelationalOperator.test(ident)) { return true } + } + return false + }; + pp$1.isAsyncFunction = function() { + if (this.options.ecmaVersion < 8 || !this.isContextual("async")) + { return false } + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length; + return !lineBreak.test(this.input.slice(this.pos, next)) && + this.input.slice(next, next + 8) === "function" && + (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8))) + }; + pp$1.parseStatement = function(declaration, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; + if (this.isLet()) { + starttype = types._var; + kind = "let"; + } + switch (starttype) { + case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword) + case types._debugger: return this.parseDebuggerStatement(node) + case types._do: return this.parseDoStatement(node) + case types._for: return this.parseForStatement(node) + case types._function: + if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false) + case types._class: + if (!declaration) { this.unexpected(); } + return this.parseClass(node, true) + case types._if: return this.parseIfStatement(node) + case types._return: return this.parseReturnStatement(node) + case types._switch: return this.parseSwitchStatement(node) + case types._throw: return this.parseThrowStatement(node) + case types._try: return this.parseTryStatement(node) + case types._const: case types._var: + kind = kind || this.value; + if (!declaration && kind !== "var") { this.unexpected(); } + return this.parseVarStatement(node, kind) + case types._while: return this.parseWhileStatement(node) + case types._with: return this.parseWithStatement(node) + case types.braceL: return this.parseBlock() + case types.semi: return this.parseEmptyStatement(node) + case types._export: + case types._import: + if (!this.options.allowImportExportEverywhere) { + if (!topLevel) + { this.raise(this.start, "'import' and 'export' may only appear at the top level"); } + if (!this.inModule) + { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); } + } + return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports) + default: + if (this.isAsyncFunction()) { + if (!declaration) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true) + } + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) + { return this.parseLabeledStatement(node, maybeName, expr) } + else { return this.parseExpressionStatement(node, expr) } + } + }; + pp$1.parseBreakContinueStatement = function(node, keyword) { + var this$1 = this; + var isBreak = keyword === "break"; + this.next(); + if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; } + else if (this.type !== types.name) { this.unexpected(); } + else { + node.label = this.parseIdent(); this.semicolon(); } - return this.finishNode(node, "ExportDefaultDeclaration") - } - if (this.shouldParseExportStatement()) { - node.declaration = this.parseStatement(true); - if (node.declaration.type === "VariableDeclaration") - { this.checkVariableExport(exports, node.declaration.declarations); } + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this$1.labels[i]; + if (node.label == null || lab.name === node.label.name) { + if (lab.kind != null && (isBreak || lab.kind === "loop")) { break } + if (node.label && isBreak) { break } + } + } + if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); } + return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement") + }; + pp$1.parseDebuggerStatement = function(node) { + this.next(); + this.semicolon(); + return this.finishNode(node, "DebuggerStatement") + }; + pp$1.parseDoStatement = function(node) { + this.next(); + this.labels.push(loopLabel); + node.body = this.parseStatement(false); + this.labels.pop(); + this.expect(types._while); + node.test = this.parseParenExpression(); + if (this.options.ecmaVersion >= 6) + { this.eat(types.semi); } else - { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } - node.specifiers = []; - node.source = null; - } else { - node.declaration = null; - node.specifiers = this.parseExportSpecifiers(exports); - if (this.eatContextual("from")) { - if (this.type !== types.string) { this.unexpected(); } - node.source = this.parseExprAtom(); + { this.semicolon(); } + return this.finishNode(node, "DoWhileStatement") + }; + pp$1.parseForStatement = function(node) { + this.next(); + var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1; + this.labels.push(loopLabel); + this.enterLexicalScope(); + this.expect(types.parenL); + if (this.type === types.semi) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, null) + } + var isLet = this.isLet(); + if (this.type === types._var || this.type === types._const || isLet) { + var init$1 = this.startNode(), kind = isLet ? "let" : this.value; + this.next(); + this.parseVar(init$1, true, kind); + this.finishNode(init$1, "VariableDeclaration"); + if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 && + !(kind !== "var" && init$1.declarations[0].init)) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + return this.parseForIn(node, init$1) + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init$1) + } + var refDestructuringErrors = new DestructuringErrors; + var init = this.parseExpression(true, refDestructuringErrors); + if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) { + if (this.options.ecmaVersion >= 9) { + if (this.type === types._in) { + if (awaitAt > -1) { this.unexpected(awaitAt); } + } else { node.await = awaitAt > -1; } + } + this.toAssignable(init, false, refDestructuringErrors); + this.checkLVal(init); + return this.parseForIn(node, init) } else { - for (var i = 0, list = node.specifiers; i < list.length; i += 1) { - var spec = list[i]; - - this$1.checkUnreserved(spec.local); + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + pp$1.parseFunctionStatement = function(node, isAsync) { + this.next(); + return this.parseFunction(node, true, false, isAsync) + }; + pp$1.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + node.consequent = this.parseStatement(!this.strict && this.type === types._function); + node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : null; + return this.finishNode(node, "IfStatement") + }; + pp$1.parseReturnStatement = function(node) { + if (!this.inFunction && !this.options.allowReturnOutsideFunction) + { this.raise(this.start, "'return' outside of function"); } + this.next(); + if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; } + else { node.argument = this.parseExpression(); this.semicolon(); } + return this.finishNode(node, "ReturnStatement") + }; + pp$1.parseSwitchStatement = function(node) { + var this$1 = this; + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types.braceL); + this.labels.push(switchLabel); + this.enterLexicalScope(); + var cur; + for (var sawDefault = false; this.type !== types.braceR;) { + if (this$1.type === types._case || this$1.type === types._default) { + var isCase = this$1.type === types._case; + if (cur) { this$1.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this$1.startNode()); + cur.consequent = []; + this$1.next(); + if (isCase) { + cur.test = this$1.parseExpression(); + } else { + if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this$1.expect(types.colon); + } else { + if (!cur) { this$1.unexpected(); } + cur.consequent.push(this$1.parseStatement(true)); } - - node.source = null; } + this.exitLexicalScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); + this.labels.pop(); + return this.finishNode(node, "SwitchStatement") + }; + pp$1.parseThrowStatement = function(node) { + this.next(); + if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) + { this.raise(this.lastTokEnd, "Illegal newline after throw"); } + node.argument = this.parseExpression(); this.semicolon(); - } - return this.finishNode(node, "ExportNamedDeclaration") -}; - -pp$1.checkExport = function(exports, name, pos) { - if (!exports) { return } - if (has(exports, name)) - { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } - exports[name] = true; -}; - -pp$1.checkPatternExport = function(exports, pat) { - var this$1 = this; - - var type = pat.type; - if (type === "Identifier") - { this.checkExport(exports, pat.name, pat.start); } - else if (type === "ObjectPattern") - { for (var i = 0, list = pat.properties; i < list.length; i += 1) + return this.finishNode(node, "ThrowStatement") + }; + var empty = []; + pp$1.parseTryStatement = function(node) { + this.next(); + node.block = this.parseBlock(); + node.handler = null; + if (this.type === types._catch) { + var clause = this.startNode(); + this.next(); + if (this.eat(types.parenL)) { + clause.param = this.parseBindingAtom(); + this.enterLexicalScope(); + this.checkLVal(clause.param, "let"); + this.expect(types.parenR); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterLexicalScope(); + } + clause.body = this.parseBlock(false); + this.exitLexicalScope(); + node.handler = this.finishNode(clause, "CatchClause"); + } + node.finalizer = this.eat(types._finally) ? this.parseBlock() : null; + if (!node.handler && !node.finalizer) + { this.raise(node.start, "Missing catch or finally clause"); } + return this.finishNode(node, "TryStatement") + }; + pp$1.parseVarStatement = function(node, kind) { + this.next(); + this.parseVar(node, false, kind); + this.semicolon(); + return this.finishNode(node, "VariableDeclaration") + }; + pp$1.parseWhileStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + this.labels.push(loopLabel); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, "WhileStatement") + }; + pp$1.parseWithStatement = function(node) { + if (this.strict) { this.raise(this.start, "'with' in strict mode"); } + this.next(); + node.object = this.parseParenExpression(); + node.body = this.parseStatement(false); + return this.finishNode(node, "WithStatement") + }; + pp$1.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") + }; + pp$1.parseLabeledStatement = function(node, maybeName, expr) { + var this$1 = this; + for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1) { - var prop = list[i]; - - this$1.checkPatternExport(exports, prop); - } } - else if (type === "ArrayPattern") - { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { - var elt = list$1[i$1]; - - if (elt) { this$1.checkPatternExport(exports, elt); } + var label = list[i$1]; + if (label.name === maybeName) + { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared"); } } - else if (type === "Property") - { this.checkPatternExport(exports, pat.value); } - else if (type === "AssignmentPattern") - { this.checkPatternExport(exports, pat.left); } - else if (type === "RestElement") - { this.checkPatternExport(exports, pat.argument); } - else if (type === "ParenthesizedExpression") - { this.checkPatternExport(exports, pat.expression); } -}; - -pp$1.checkVariableExport = function(exports, decls) { - var this$1 = this; - - if (!exports) { return } - for (var i = 0, list = decls; i < list.length; i += 1) - { - var decl = list[i]; - - this$1.checkPatternExport(exports, decl.id); - } -}; - -pp$1.shouldParseExportStatement = function() { - return this.type.keyword === "var" || - this.type.keyword === "const" || - this.type.keyword === "class" || - this.type.keyword === "function" || - this.isLet() || - this.isAsyncFunction() -}; - - -pp$1.parseExportSpecifiers = function(exports) { - var this$1 = this; - - var nodes = [], first = true; - this.expect(types.braceL); - while (!this.eat(types.braceR)) { - if (!first) { - this$1.expect(types.comma); - if (this$1.afterTrailingComma(types.braceR)) { break } - } else { first = false; } - - var node = this$1.startNode(); - node.local = this$1.parseIdent(true); - node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local; - this$1.checkExport(exports, node.exported.name, node.exported.start); - nodes.push(this$1.finishNode(node, "ExportSpecifier")); - } - return nodes -}; - - -pp$1.parseImport = function(node) { - this.next(); - if (this.type === types.string) { - node.specifiers = empty; - node.source = this.parseExprAtom(); - } else { - node.specifiers = this.parseImportSpecifiers(); - this.expectContextual("from"); - node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); - } - this.semicolon(); - return this.finishNode(node, "ImportDeclaration") -}; - - -pp$1.parseImportSpecifiers = function() { - var this$1 = this; - - var nodes = [], first = true; - if (this.type === types.name) { + var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null; + for (var i = this.labels.length - 1; i >= 0; i--) { + var label$1 = this$1.labels[i]; + if (label$1.statementStart === node.start) { + label$1.statementStart = this$1.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(true); + if (node.body.type === "ClassDeclaration" || + node.body.type === "VariableDeclaration" && node.body.kind !== "var" || + node.body.type === "FunctionDeclaration" && (this.strict || node.body.generator || node.body.async)) + { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); } + this.labels.pop(); + node.label = expr; + return this.finishNode(node, "LabeledStatement") + }; + pp$1.parseExpressionStatement = function(node, expr) { + node.expression = expr; + this.semicolon(); + return this.finishNode(node, "ExpressionStatement") + }; + pp$1.parseBlock = function(createNewLexicalScope) { + var this$1 = this; + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; var node = this.startNode(); - node.local = this.parseIdent(); - this.checkLVal(node.local, "let"); - nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); - if (!this.eat(types.comma)) { return nodes } - } - if (this.type === types.star) { - var node$1 = this.startNode(); + node.body = []; + this.expect(types.braceL); + if (createNewLexicalScope) { + this.enterLexicalScope(); + } + while (!this.eat(types.braceR)) { + var stmt = this$1.parseStatement(true); + node.body.push(stmt); + } + if (createNewLexicalScope) { + this.exitLexicalScope(); + } + return this.finishNode(node, "BlockStatement") + }; + pp$1.parseFor = function(node, init) { + node.init = init; + this.expect(types.semi); + node.test = this.type === types.semi ? null : this.parseExpression(); + this.expect(types.semi); + node.update = this.type === types.parenR ? null : this.parseExpression(); + this.expect(types.parenR); + this.exitLexicalScope(); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, "ForStatement") + }; + pp$1.parseForIn = function(node, init) { + var type = this.type === types._in ? "ForInStatement" : "ForOfStatement"; + this.next(); + if (type === "ForInStatement") { + if (init.type === "AssignmentPattern" || + (init.type === "VariableDeclaration" && init.declarations[0].init != null && + (this.strict || init.declarations[0].id.type !== "Identifier"))) + { this.raise(init.start, "Invalid assignment in for-in loop head"); } + } + node.left = init; + node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types.parenR); + this.exitLexicalScope(); + node.body = this.parseStatement(false); + this.labels.pop(); + return this.finishNode(node, type) + }; + pp$1.parseVar = function(node, isFor, kind) { + var this$1 = this; + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this$1.startNode(); + this$1.parseVarId(decl, kind); + if (this$1.eat(types.eq)) { + decl.init = this$1.parseMaybeAssign(isFor); + } else if (kind === "const" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) { + this$1.unexpected(); + } else if (decl.id.type !== "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) { + this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this$1.finishNode(decl, "VariableDeclarator")); + if (!this$1.eat(types.comma)) { break } + } + return node + }; + pp$1.parseVarId = function(decl, kind) { + decl.id = this.parseBindingAtom(kind); + this.checkLVal(decl.id, kind, false); + }; + pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) + { node.generator = this.eat(types.star); } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + if (isStatement) { + node.id = isStatement === "nullableID" && this.type !== types.name ? null : this.parseIdent(); + if (node.id) { + this.checkLVal(node.id, this.inModule && !this.inFunction ? "let" : "var"); + } + } + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; + this.inGenerator = node.generator; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; + this.enterFunctionScope(); + if (!isStatement) + { node.id = this.type === types.name ? this.parseIdent() : null; } + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody); + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression") + }; + pp$1.parseFunctionParams = function(node) { + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + }; + pp$1.parseClass = function(node, isStatement) { + var this$1 = this; + this.next(); + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + var member = this$1.parseClassMember(classBody); + if (member && member.type === "MethodDefinition" && member.kind === "constructor") { + if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } + } + node.body = this.finishNode(classBody, "ClassBody"); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; + pp$1.parseClassMember = function(classBody) { + var this$1 = this; + if (this.eat(types.semi)) { return null } + var method = this.startNode(); + var tryContextual = function (k, noLineBreak) { + if ( noLineBreak === void 0 ) noLineBreak = false; + var start = this$1.start, startLoc = this$1.startLoc; + if (!this$1.eatContextual(k)) { return false } + if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true } + if (method.key) { this$1.unexpected(); } + method.computed = false; + method.key = this$1.startNodeAt(start, startLoc); + method.key.name = k; + this$1.finishNode(method.key, "Identifier"); + return false + }; + method.kind = "method"; + method.static = tryContextual("static"); + var isGenerator = this.eat(types.star); + var isAsync = false; + if (!isGenerator) { + if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + } else if (tryContextual("get")) { + method.kind = "get"; + } else if (tryContextual("set")) { + method.kind = "set"; + } + } + if (!method.key) { this.parsePropertyName(method); } + var key = method.key; + if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" || + key.type === "Literal" && key.value === "constructor")) { + if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); } + if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); } + if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); } + method.kind = "constructor"; + } else if (method.static && key.type === "Identifier" && key.name === "prototype") { + this.raise(key.start, "Classes may not have a static property named prototype"); + } + this.parseClassMethod(classBody, method, isGenerator, isAsync); + if (method.kind === "get" && method.value.params.length !== 0) + { this.raiseRecoverable(method.value.start, "getter should have no params"); } + if (method.kind === "set" && method.value.params.length !== 1) + { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); } + if (method.kind === "set" && method.value.params[0].type === "RestElement") + { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); } + return method + }; + pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) { + method.value = this.parseMethod(isGenerator, isAsync); + classBody.body.push(this.finishNode(method, "MethodDefinition")); + }; + pp$1.parseClassId = function(node, isStatement) { + node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null; + }; + pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; + }; + pp$1.parseExport = function(node, exports) { + var this$1 = this; this.next(); - this.expectContextual("as"); - node$1.local = this.parseIdent(); - this.checkLVal(node$1.local, "let"); - nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + if (this.eat(types.star)) { + this.expectContextual("from"); + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + this.semicolon(); + return this.finishNode(node, "ExportAllDeclaration") + } + if (this.eat(types._default)) { + this.checkExport(exports, "default", this.lastTokStart); + var isAsync; + if (this.type === types._function || (isAsync = this.isAsyncFunction())) { + var fNode = this.startNode(); + this.next(); + if (isAsync) { this.next(); } + node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync); + } else if (this.type === types._class) { + var cNode = this.startNode(); + node.declaration = this.parseClass(cNode, "nullableID"); + } else { + node.declaration = this.parseMaybeAssign(); + this.semicolon(); + } + return this.finishNode(node, "ExportDefaultDeclaration") + } + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(true); + if (node.declaration.type === "VariableDeclaration") + { this.checkVariableExport(exports, node.declaration.declarations); } + else + { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); } + node.specifiers = []; + node.source = null; + } else { + node.declaration = null; + node.specifiers = this.parseExportSpecifiers(exports); + if (this.eatContextual("from")) { + if (this.type !== types.string) { this.unexpected(); } + node.source = this.parseExprAtom(); + } else { + for (var i = 0, list = node.specifiers; i < list.length; i += 1) { + var spec = list[i]; + this$1.checkUnreserved(spec.local); + } + node.source = null; + } + this.semicolon(); + } + return this.finishNode(node, "ExportNamedDeclaration") + }; + pp$1.checkExport = function(exports, name, pos) { + if (!exports) { return } + if (has(exports, name)) + { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); } + exports[name] = true; + }; + pp$1.checkPatternExport = function(exports, pat) { + var this$1 = this; + var type = pat.type; + if (type === "Identifier") + { this.checkExport(exports, pat.name, pat.start); } + else if (type === "ObjectPattern") + { for (var i = 0, list = pat.properties; i < list.length; i += 1) + { + var prop = list[i]; + this$1.checkPatternExport(exports, prop); + } } + else if (type === "ArrayPattern") + { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) { + var elt = list$1[i$1]; + if (elt) { this$1.checkPatternExport(exports, elt); } + } } + else if (type === "Property") + { this.checkPatternExport(exports, pat.value); } + else if (type === "AssignmentPattern") + { this.checkPatternExport(exports, pat.left); } + else if (type === "RestElement") + { this.checkPatternExport(exports, pat.argument); } + else if (type === "ParenthesizedExpression") + { this.checkPatternExport(exports, pat.expression); } + }; + pp$1.checkVariableExport = function(exports, decls) { + var this$1 = this; + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; + this$1.checkPatternExport(exports, decl.id); + } + }; + pp$1.shouldParseExportStatement = function() { + return this.type.keyword === "var" || + this.type.keyword === "const" || + this.type.keyword === "class" || + this.type.keyword === "function" || + this.isLet() || + this.isAsyncFunction() + }; + pp$1.parseExportSpecifiers = function(exports) { + var this$1 = this; + var nodes = [], first = true; + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + var node = this$1.startNode(); + node.local = this$1.parseIdent(true); + node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local; + this$1.checkExport(exports, node.exported.name, node.exported.start); + nodes.push(this$1.finishNode(node, "ExportSpecifier")); + } return nodes - } - this.expect(types.braceL); - while (!this.eat(types.braceR)) { - if (!first) { - this$1.expect(types.comma); - if (this$1.afterTrailingComma(types.braceR)) { break } - } else { first = false; } - - var node$2 = this$1.startNode(); - node$2.imported = this$1.parseIdent(true); - if (this$1.eatContextual("as")) { - node$2.local = this$1.parseIdent(); + }; + pp$1.parseImport = function(node) { + this.next(); + if (this.type === types.string) { + node.specifiers = empty; + node.source = this.parseExprAtom(); } else { - this$1.checkUnreserved(node$2.imported); - node$2.local = node$2.imported; + node.specifiers = this.parseImportSpecifiers(); + this.expectContextual("from"); + node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected(); } - this$1.checkLVal(node$2.local, "let"); - nodes.push(this$1.finishNode(node$2, "ImportSpecifier")); - } - return nodes -}; - -pp$1.adaptDirectivePrologue = function(statements) { - for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { - statements[i].directive = statements[i].expression.raw.slice(1, -1); - } -}; -pp$1.isDirectiveCandidate = function(statement) { - return ( - statement.type === "ExpressionStatement" && - statement.expression.type === "Literal" && - typeof statement.expression.value === "string" && - (this.input[statement.start] === "\"" || this.input[statement.start] === "'") - ) -}; - -var pp$2 = Parser.prototype; - - -pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { - var this$1 = this; - - if (this.options.ecmaVersion >= 6 && node) { - switch (node.type) { + this.semicolon(); + return this.finishNode(node, "ImportDeclaration") + }; + pp$1.parseImportSpecifiers = function() { + var this$1 = this; + var nodes = [], first = true; + if (this.type === types.name) { + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLVal(node.local, "let"); + nodes.push(this.finishNode(node, "ImportDefaultSpecifier")); + if (!this.eat(types.comma)) { return nodes } + } + if (this.type === types.star) { + var node$1 = this.startNode(); + this.next(); + this.expectContextual("as"); + node$1.local = this.parseIdent(); + this.checkLVal(node$1.local, "let"); + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + return nodes + } + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + var node$2 = this$1.startNode(); + node$2.imported = this$1.parseIdent(true); + if (this$1.eatContextual("as")) { + node$2.local = this$1.parseIdent(); + } else { + this$1.checkUnreserved(node$2.imported); + node$2.local = node$2.imported; + } + this$1.checkLVal(node$2.local, "let"); + nodes.push(this$1.finishNode(node$2, "ImportSpecifier")); + } + return nodes + }; + pp$1.adaptDirectivePrologue = function(statements) { + for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) { + statements[i].directive = statements[i].expression.raw.slice(1, -1); + } + }; + pp$1.isDirectiveCandidate = function(statement) { + return ( + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + typeof statement.expression.value === "string" && + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) + }; + var pp$2 = Parser.prototype; + pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { + var this$1 = this; + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); } + break + case "ObjectPattern": + case "ArrayPattern": + case "RestElement": + break + case "ObjectExpression": + node.type = "ObjectPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + for (var i = 0, list = node.properties; i < list.length; i += 1) { + var prop = list[i]; + this$1.toAssignable(prop, isBinding); + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this$1.raise(prop.argument.start, "Unexpected token"); + } + } + break + case "Property": + if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } + this.toAssignable(node.value, isBinding); + break + case "ArrayExpression": + node.type = "ArrayPattern"; + if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + this.toAssignableList(node.elements, isBinding); + break + case "SpreadElement": + node.type = "RestElement"; + this.toAssignable(node.argument, isBinding); + if (node.argument.type === "AssignmentPattern") + { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + break + case "AssignmentExpression": + if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } + node.type = "AssignmentPattern"; + delete node.operator; + this.toAssignable(node.left, isBinding); + case "AssignmentPattern": + break + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding); + break + case "MemberExpression": + if (!isBinding) { break } + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node + }; + pp$2.toAssignableList = function(exprList, isBinding) { + var this$1 = this; + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this$1.toAssignable(elt, isBinding); } + } + if (end) { + var last = exprList[end - 1]; + if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") + { this.unexpected(last.argument.start); } + } + return exprList + }; + pp$2.parseSpread = function(refDestructuringErrors) { + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeAssign(false, refDestructuringErrors); + return this.finishNode(node, "SpreadElement") + }; + pp$2.parseRestBinding = function() { + var node = this.startNode(); + this.next(); + if (this.options.ecmaVersion === 6 && this.type !== types.name) + { this.unexpected(); } + node.argument = this.parseBindingAtom(); + return this.finishNode(node, "RestElement") + }; + pp$2.parseBindingAtom = function() { + if (this.options.ecmaVersion >= 6) { + switch (this.type) { + case types.bracketL: + var node = this.startNode(); + this.next(); + node.elements = this.parseBindingList(types.bracketR, true, true); + return this.finishNode(node, "ArrayPattern") + case types.braceL: + return this.parseObj(true) + } + } + return this.parseIdent() + }; + pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) { + var this$1 = this; + var elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this$1.expect(types.comma); } + if (allowEmpty && this$1.type === types.comma) { + elts.push(null); + } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { + break + } else if (this$1.type === types.ellipsis) { + var rest = this$1.parseRestBinding(); + this$1.parseBindingListItem(rest); + elts.push(rest); + if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } + this$1.expect(close); + break + } else { + var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc); + this$1.parseBindingListItem(elem); + elts.push(elem); + } + } + return elts + }; + pp$2.parseBindingListItem = function(param) { + return param + }; + pp$2.parseMaybeDefault = function(startPos, startLoc, left) { + left = left || this.parseBindingAtom(); + if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left } + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.right = this.parseMaybeAssign(); + return this.finishNode(node, "AssignmentPattern") + }; + pp$2.checkLVal = function(expr, bindingType, checkClashes) { + var this$1 = this; + switch (expr.type) { case "Identifier": - if (this.inAsync && node.name === "await") - { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); } - break - - case "ObjectPattern": - case "ArrayPattern": - case "RestElement": - break - - case "ObjectExpression": - node.type = "ObjectPattern"; - if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - for (var i = 0, list = node.properties; i < list.length; i += 1) { - var prop = list[i]; - - this$1.toAssignable(prop, isBinding); + if (this.strict && this.reservedWordsStrictBind.test(expr.name)) + { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } + if (checkClashes) { + if (has(checkClashes, expr.name)) + { this.raiseRecoverable(expr.start, "Argument name clash"); } + checkClashes[expr.name] = true; + } + if (bindingType && bindingType !== "none") { if ( - prop.type === "RestElement" && - (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + bindingType === "var" && !this.canDeclareVarName(expr.name) || + bindingType !== "var" && !this.canDeclareLexicalName(expr.name) ) { - this$1.raise(prop.argument.start, "Unexpected token"); + this.raiseRecoverable(expr.start, ("Identifier '" + (expr.name) + "' has already been declared")); + } + if (bindingType === "var") { + this.declareVarName(expr.name); + } else { + this.declareLexicalName(expr.name); } } break - - case "Property": - if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); } - this.toAssignable(node.value, isBinding); + case "MemberExpression": + if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } break - - case "ArrayExpression": - node.type = "ArrayPattern"; - if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - this.toAssignableList(node.elements, isBinding); + case "ObjectPattern": + for (var i = 0, list = expr.properties; i < list.length; i += 1) + { + var prop = list[i]; + this$1.checkLVal(prop, bindingType, checkClashes); + } break - - case "SpreadElement": - node.type = "RestElement"; - this.toAssignable(node.argument, isBinding); - if (node.argument.type === "AssignmentPattern") - { this.raise(node.argument.start, "Rest elements cannot have a default value"); } + case "Property": + this.checkLVal(expr.value, bindingType, checkClashes); + break + case "ArrayPattern": + for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { + var elem = list$1[i$1]; + if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); } + } break - - case "AssignmentExpression": - if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); } - node.type = "AssignmentPattern"; - delete node.operator; - this.toAssignable(node.left, isBinding); - case "AssignmentPattern": + this.checkLVal(expr.left, bindingType, checkClashes); + break + case "RestElement": + this.checkLVal(expr.argument, bindingType, checkClashes); break - case "ParenthesizedExpression": - this.toAssignable(node.expression, isBinding); + this.checkLVal(expr.expression, bindingType, checkClashes); break - - case "MemberExpression": - if (!isBinding) { break } - default: - this.raise(node.start, "Assigning to rvalue"); - } - } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } - return node -}; - - -pp$2.toAssignableList = function(exprList, isBinding) { - var this$1 = this; - - var end = exprList.length; - for (var i = 0; i < end; i++) { - var elt = exprList[i]; - if (elt) { this$1.toAssignable(elt, isBinding); } - } - if (end) { - var last = exprList[end - 1]; - if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier") - { this.unexpected(last.argument.start); } - } - return exprList -}; - - -pp$2.parseSpread = function(refDestructuringErrors) { - var node = this.startNode(); - this.next(); - node.argument = this.parseMaybeAssign(false, refDestructuringErrors); - return this.finishNode(node, "SpreadElement") -}; - -pp$2.parseRestBinding = function() { - var node = this.startNode(); - this.next(); - - if (this.options.ecmaVersion === 6 && this.type !== types.name) - { this.unexpected(); } - - node.argument = this.parseBindingAtom(); - - return this.finishNode(node, "RestElement") -}; - - -pp$2.parseBindingAtom = function() { - if (this.options.ecmaVersion >= 6) { - switch (this.type) { - case types.bracketL: - var node = this.startNode(); - this.next(); - node.elements = this.parseBindingList(types.bracketR, true, true); - return this.finishNode(node, "ArrayPattern") - - case types.braceL: - return this.parseObj(true) - } - } - return this.parseIdent() -}; - -pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) { - var this$1 = this; - - var elts = [], first = true; - while (!this.eat(close)) { - if (first) { first = false; } - else { this$1.expect(types.comma); } - if (allowEmpty && this$1.type === types.comma) { - elts.push(null); - } else if (allowTrailingComma && this$1.afterTrailingComma(close)) { - break - } else if (this$1.type === types.ellipsis) { - var rest = this$1.parseRestBinding(); - this$1.parseBindingListItem(rest); - elts.push(rest); - if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } - this$1.expect(close); - break - } else { - var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc); - this$1.parseBindingListItem(elem); - elts.push(elem); + this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); } - } - return elts -}; - -pp$2.parseBindingListItem = function(param) { - return param -}; - - -pp$2.parseMaybeDefault = function(startPos, startLoc, left) { - left = left || this.parseBindingAtom(); - if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left } - var node = this.startNodeAt(startPos, startLoc); - node.left = left; - node.right = this.parseMaybeAssign(); - return this.finishNode(node, "AssignmentPattern") -}; - - -pp$2.checkLVal = function(expr, bindingType, checkClashes) { - var this$1 = this; - - switch (expr.type) { - case "Identifier": - if (this.strict && this.reservedWordsStrictBind.test(expr.name)) - { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); } - if (checkClashes) { - if (has(checkClashes, expr.name)) - { this.raiseRecoverable(expr.start, "Argument name clash"); } - checkClashes[expr.name] = true; - } - if (bindingType && bindingType !== "none") { - if ( - bindingType === "var" && !this.canDeclareVarName(expr.name) || - bindingType !== "var" && !this.canDeclareLexicalName(expr.name) - ) { - this.raiseRecoverable(expr.start, ("Identifier '" + (expr.name) + "' has already been declared")); + }; + var pp$3 = Parser.prototype; + pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) { + if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") + { return } + if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) + { return } + var key = prop.key; + var name; + switch (key.type) { + case "Identifier": name = key.name; break + case "Literal": name = String(key.value); break + default: return + } + var kind = prop.kind; + if (this.options.ecmaVersion >= 6) { + if (name === "__proto__" && kind === "init") { + if (propHash.proto) { + if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; } + else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } + } + propHash.proto = true; } - if (bindingType === "var") { - this.declareVarName(expr.name); + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; } else { - this.declareLexicalName(expr.name); + redefinition = other.init || other[kind]; } + if (redefinition) + { this.raiseRecoverable(key.start, "Redefinition of property"); } + } else { + other = propHash[name] = { + init: false, + get: false, + set: false + }; } - break - - case "MemberExpression": - if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); } - break - - case "ObjectPattern": - for (var i = 0, list = expr.properties; i < list.length; i += 1) - { - var prop = list[i]; - - this$1.checkLVal(prop, bindingType, checkClashes); - } - break - - case "Property": - this.checkLVal(expr.value, bindingType, checkClashes); - break - - case "ArrayPattern": - for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) { - var elem = list$1[i$1]; - - if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); } + other[kind] = true; + }; + pp$3.parseExpression = function(noIn, refDestructuringErrors) { + var this$1 = this; + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeAssign(noIn, refDestructuringErrors); + if (this.type === types.comma) { + var node = this.startNodeAt(startPos, startLoc); + node.expressions = [expr]; + while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") } - break - - case "AssignmentPattern": - this.checkLVal(expr.left, bindingType, checkClashes); - break - - case "RestElement": - this.checkLVal(expr.argument, bindingType, checkClashes); - break - - case "ParenthesizedExpression": - this.checkLVal(expr.expression, bindingType, checkClashes); - break - - default: - this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue"); - } -}; - - -var pp$3 = Parser.prototype; - - -pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) { - if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement") - { return } - if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand)) - { return } - var key = prop.key; - var name; - switch (key.type) { - case "Identifier": name = key.name; break - case "Literal": name = String(key.value); break - default: return - } - var kind = prop.kind; - if (this.options.ecmaVersion >= 6) { - if (name === "__proto__" && kind === "init") { - if (propHash.proto) { - if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; } - else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } - } - propHash.proto = true; + return expr + }; + pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.inGenerator && this.isContextual("yield")) { return this.parseYield() } + var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1; + if (refDestructuringErrors) { + oldParenAssign = refDestructuringErrors.parenthesizedAssign; + oldTrailingComma = refDestructuringErrors.trailingComma; + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; + } else { + refDestructuringErrors = new DestructuringErrors; + ownDestructuringErrors = true; + } + var startPos = this.start, startLoc = this.startLoc; + if (this.type === types.parenL || this.type === types.name) + { this.potentialArrowAt = this.start; } + var left = this.parseMaybeConditional(noIn, refDestructuringErrors); + if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } + if (this.type.isAssign) { + var node = this.startNodeAt(startPos, startLoc); + node.operator = this.value; + node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; + if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); } + refDestructuringErrors.shorthandAssign = -1; + this.checkLVal(left); + this.next(); + node.right = this.parseMaybeAssign(noIn); + return this.finishNode(node, "AssignmentExpression") + } else { + if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } } - return - } - name = "$" + name; - var other = propHash[name]; - if (other) { - var redefinition; - if (kind === "init") { - redefinition = this.strict && other.init || other.get || other.set; + if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } + if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } + return left + }; + pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprOps(noIn, refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + if (this.eat(types.question)) { + var node = this.startNodeAt(startPos, startLoc); + node.test = expr; + node.consequent = this.parseMaybeAssign(); + this.expect(types.colon); + node.alternate = this.parseMaybeAssign(noIn); + return this.finishNode(node, "ConditionalExpression") + } + return expr + }; + pp$3.parseExprOps = function(noIn, refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseMaybeUnary(refDestructuringErrors, false); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn) + }; + pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { + var prec = this.type.binop; + if (prec != null && (!noIn || this.type !== types._in)) { + if (prec > minPrec) { + var logical = this.type === types.logicalOR || this.type === types.logicalAND; + var op = this.value; + this.next(); + var startPos = this.start, startLoc = this.startLoc; + var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn); + var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical); + return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + } + } + return left + }; + pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { + var node = this.startNodeAt(startPos, startLoc); + node.left = left; + node.operator = op; + node.right = right; + return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") + }; + pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + var this$1 = this; + var startPos = this.start, startLoc = this.startLoc, expr; + if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) { + expr = this.parseAwait(); + sawUnary = true; + } else if (this.type.prefix) { + var node = this.startNode(), update = this.type === types.incDec; + node.operator = this.value; + node.prefix = true; + this.next(); + node.argument = this.parseMaybeUnary(null, true); + this.checkExpressionErrors(refDestructuringErrors, true); + if (update) { this.checkLVal(node.argument); } + else if (this.strict && node.operator === "delete" && + node.argument.type === "Identifier") + { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } + else { sawUnary = true; } + expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); } else { - redefinition = other.init || other[kind]; - } - if (redefinition) - { this.raiseRecoverable(key.start, "Redefinition of property"); } - } else { - other = propHash[name] = { - init: false, - get: false, - set: false - }; - } - other[kind] = true; -}; - - - - -pp$3.parseExpression = function(noIn, refDestructuringErrors) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseMaybeAssign(noIn, refDestructuringErrors); - if (this.type === types.comma) { - var node = this.startNodeAt(startPos, startLoc); - node.expressions = [expr]; - while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); } - return this.finishNode(node, "SequenceExpression") - } - return expr -}; - - -pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { - if (this.inGenerator && this.isContextual("yield")) { return this.parseYield() } - - var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1; - if (refDestructuringErrors) { - oldParenAssign = refDestructuringErrors.parenthesizedAssign; - oldTrailingComma = refDestructuringErrors.trailingComma; - refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1; - } else { - refDestructuringErrors = new DestructuringErrors; - ownDestructuringErrors = true; - } - - var startPos = this.start, startLoc = this.startLoc; - if (this.type === types.parenL || this.type === types.name) - { this.potentialArrowAt = this.start; } - var left = this.parseMaybeConditional(noIn, refDestructuringErrors); - if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); } - if (this.type.isAssign) { - var node = this.startNodeAt(startPos, startLoc); - node.operator = this.value; - node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left; - if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); } - refDestructuringErrors.shorthandAssign = -1; - this.checkLVal(left); - this.next(); - node.right = this.parseMaybeAssign(noIn); - return this.finishNode(node, "AssignmentExpression") - } else { - if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); } - } - if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; } - if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; } - return left -}; - - -pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseExprOps(noIn, refDestructuringErrors); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - if (this.eat(types.question)) { - var node = this.startNodeAt(startPos, startLoc); - node.test = expr; - node.consequent = this.parseMaybeAssign(); - this.expect(types.colon); - node.alternate = this.parseMaybeAssign(noIn); - return this.finishNode(node, "ConditionalExpression") - } - return expr -}; - - -pp$3.parseExprOps = function(noIn, refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseMaybeUnary(refDestructuringErrors, false); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn) -}; - - -pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) { - var prec = this.type.binop; - if (prec != null && (!noIn || this.type !== types._in)) { - if (prec > minPrec) { - var logical = this.type === types.logicalOR || this.type === types.logicalAND; - var op = this.value; + expr = this.parseExprSubscripts(refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this$1.startNodeAt(startPos, startLoc); + node$1.operator = this$1.value; + node$1.prefix = false; + node$1.argument = expr; + this$1.checkLVal(expr); + this$1.next(); + expr = this$1.finishNode(node$1, "UpdateExpression"); + } + } + if (!sawUnary && this.eat(types.starstar)) + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } + else + { return expr } + }; + pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors); + var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")"; + if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr } + var result = this.parseSubscripts(expr, startPos, startLoc); + if (refDestructuringErrors && result.type === "MemberExpression") { + if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } + if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } + } + return result + }; + pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { + var this$1 = this; + var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; + for (var computed = (void 0);;) { + if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) { + var node = this$1.startNodeAt(startPos, startLoc); + node.object = base; + node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true); + node.computed = !!computed; + if (computed) { this$1.expect(types.bracketR); } + base = this$1.finishNode(node, "MemberExpression"); + } else if (!noCalls && this$1.eat(types.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos; + this$1.yieldPos = 0; + this$1.awaitPos = 0; + var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) { + this$1.checkPatternErrors(refDestructuringErrors, false); + this$1.checkYieldAwaitInDefaultParams(); + this$1.yieldPos = oldYieldPos; + this$1.awaitPos = oldAwaitPos; + return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) + } + this$1.checkExpressionErrors(refDestructuringErrors, true); + this$1.yieldPos = oldYieldPos || this$1.yieldPos; + this$1.awaitPos = oldAwaitPos || this$1.awaitPos; + var node$1 = this$1.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + base = this$1.finishNode(node$1, "CallExpression"); + } else if (this$1.type === types.backQuote) { + var node$2 = this$1.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this$1.parseTemplate({isTagged: true}); + base = this$1.finishNode(node$2, "TaggedTemplateExpression"); + } else { + return base + } + } + }; + pp$3.parseExprAtom = function(refDestructuringErrors) { + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types._super: + if (!this.inFunction) + { this.raise(this.start, "'super' outside of function or class"); } + node = this.startNode(); + this.next(); + if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) + { this.unexpected(); } + return this.finishNode(node, "Super") + case types._this: + node = this.startNode(); this.next(); - var startPos = this.start, startLoc = this.startLoc; - var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn); - var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical); - return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn) + return this.finishNode(node, "ThisExpression") + case types.name: + var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; + var id = this.parseIdent(this.type !== types.name); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) + { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) } + if (canBeArrow && !this.canInsertSemicolon()) { + if (this.eat(types.arrow)) + { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) } + if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) { + id = this.parseIdent(); + if (this.canInsertSemicolon() || !this.eat(types.arrow)) + { this.unexpected(); } + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) + } + } + return id + case types.regexp: + var value = this.value; + node = this.parseLiteral(value.value); + node.regex = {pattern: value.pattern, flags: value.flags}; + return node + case types.num: case types.string: + return this.parseLiteral(this.value) + case types._null: case types._true: case types._false: + node = this.startNode(); + node.value = this.type === types._null ? null : this.type === types._true; + node.raw = this.type.keyword; + this.next(); + return this.finishNode(node, "Literal") + case types.parenL: + var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow); + if (refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) + { refDestructuringErrors.parenthesizedAssign = start; } + if (refDestructuringErrors.parenthesizedBind < 0) + { refDestructuringErrors.parenthesizedBind = start; } + } + return expr + case types.bracketL: + node = this.startNode(); + this.next(); + node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors); + return this.finishNode(node, "ArrayExpression") + case types.braceL: + return this.parseObj(false, refDestructuringErrors) + case types._function: + node = this.startNode(); + this.next(); + return this.parseFunction(node, false) + case types._class: + return this.parseClass(this.startNode(), false) + case types._new: + return this.parseNew() + case types.backQuote: + return this.parseTemplate() + default: + this.unexpected(); } - } - return left -}; - -pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) { - var node = this.startNodeAt(startPos, startLoc); - node.left = left; - node.operator = op; - node.right = right; - return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression") -}; - - -pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc, expr; - if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) { - expr = this.parseAwait(); - sawUnary = true; - } else if (this.type.prefix) { - var node = this.startNode(), update = this.type === types.incDec; - node.operator = this.value; - node.prefix = true; + }; + pp$3.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); this.next(); - node.argument = this.parseMaybeUnary(null, true); - this.checkExpressionErrors(refDestructuringErrors, true); - if (update) { this.checkLVal(node.argument); } - else if (this.strict && node.operator === "delete" && - node.argument.type === "Identifier") - { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); } - else { sawUnary = true; } - expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression"); - } else { - expr = this.parseExprSubscripts(refDestructuringErrors); - if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } - while (this.type.postfix && !this.canInsertSemicolon()) { - var node$1 = this$1.startNodeAt(startPos, startLoc); - node$1.operator = this$1.value; - node$1.prefix = false; - node$1.argument = expr; - this$1.checkLVal(expr); - this$1.next(); - expr = this$1.finishNode(node$1, "UpdateExpression"); + return this.finishNode(node, "Literal") + }; + pp$3.parseParenExpression = function() { + this.expect(types.parenL); + var val = this.parseExpression(); + this.expect(types.parenR); + return val + }; + pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { + var this$1 = this; + var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; + if (this.options.ecmaVersion >= 6) { + this.next(); + var innerStartPos = this.start, innerStartLoc = this.startLoc; + var exprList = [], first = true, lastIsComma = false; + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; + this.yieldPos = 0; + this.awaitPos = 0; + while (this.type !== types.parenR) { + first ? first = false : this$1.expect(types.comma); + if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) { + lastIsComma = true; + break + } else if (this$1.type === types.ellipsis) { + spreadStart = this$1.start; + exprList.push(this$1.parseParenItem(this$1.parseRestBinding())); + if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } + break + } else { + exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)); + } + } + var innerEndPos = this.start, innerEndLoc = this.startLoc; + this.expect(types.parenR); + if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + return this.parseParenArrowList(startPos, startLoc, exprList) + } + if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } + if (spreadStart) { this.unexpected(spreadStart); } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + if (exprList.length > 1) { + val = this.startNodeAt(innerStartPos, innerStartLoc); + val.expressions = exprList; + this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); + } else { + val = exprList[0]; + } + } else { + val = this.parseParenExpression(); } - } - - if (!sawUnary && this.eat(types.starstar)) - { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } - else - { return expr } -}; - - -pp$3.parseExprSubscripts = function(refDestructuringErrors) { - var startPos = this.start, startLoc = this.startLoc; - var expr = this.parseExprAtom(refDestructuringErrors); - var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")"; - if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr } - var result = this.parseSubscripts(expr, startPos, startLoc); - if (refDestructuringErrors && result.type === "MemberExpression") { - if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; } - if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; } - } - return result -}; - -pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) { - var this$1 = this; - - var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && - this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async"; - for (var computed = (void 0);;) { - if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) { - var node = this$1.startNodeAt(startPos, startLoc); - node.object = base; - node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true); - node.computed = !!computed; - if (computed) { this$1.expect(types.bracketR); } - base = this$1.finishNode(node, "MemberExpression"); - } else if (!noCalls && this$1.eat(types.parenL)) { - var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos; - this$1.yieldPos = 0; - this$1.awaitPos = 0; - var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors); - if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) { - this$1.checkPatternErrors(refDestructuringErrors, false); - this$1.checkYieldAwaitInDefaultParams(); - this$1.yieldPos = oldYieldPos; - this$1.awaitPos = oldAwaitPos; - return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true) - } - this$1.checkExpressionErrors(refDestructuringErrors, true); - this$1.yieldPos = oldYieldPos || this$1.yieldPos; - this$1.awaitPos = oldAwaitPos || this$1.awaitPos; - var node$1 = this$1.startNodeAt(startPos, startLoc); - node$1.callee = base; - node$1.arguments = exprList; - base = this$1.finishNode(node$1, "CallExpression"); - } else if (this$1.type === types.backQuote) { - var node$2 = this$1.startNodeAt(startPos, startLoc); - node$2.tag = base; - node$2.quasi = this$1.parseTemplate({isTagged: true}); - base = this$1.finishNode(node$2, "TaggedTemplateExpression"); + if (this.options.preserveParens) { + var par = this.startNodeAt(startPos, startLoc); + par.expression = val; + return this.finishNode(par, "ParenthesizedExpression") } else { - return base + return val + } + }; + pp$3.parseParenItem = function(item) { + return item + }; + pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) + }; + var empty$1 = []; + pp$3.parseNew = function() { + var node = this.startNode(); + var meta = this.parseIdent(true); + if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) { + node.meta = meta; + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + if (node.property.name !== "target" || containsEsc) + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); } + if (!this.inFunction) + { this.raiseRecoverable(node.start, "new.target can only be used in functions"); } + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc; + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); } + else { node.arguments = empty$1; } + return this.finishNode(node, "NewExpression") + }; + pp$3.parseTemplateElement = function(ref) { + var isTagged = ref.isTagged; + var elem = this.startNode(); + if (this.type === types.invalidTemplate) { + if (!isTagged) { + this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); + } + elem.value = { + raw: this.value, + cooked: null + }; + } else { + elem.value = { + raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), + cooked: this.value + }; } - } -}; - - -pp$3.parseExprAtom = function(refDestructuringErrors) { - var node, canBeArrow = this.potentialArrowAt === this.start; - switch (this.type) { - case types._super: - if (!this.inFunction) - { this.raise(this.start, "'super' outside of function or class"); } - node = this.startNode(); - this.next(); - if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL) - { this.unexpected(); } - return this.finishNode(node, "Super") - - case types._this: - node = this.startNode(); this.next(); - return this.finishNode(node, "ThisExpression") - - case types.name: - var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc; - var id = this.parseIdent(this.type !== types.name); - if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) - { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) } - if (canBeArrow && !this.canInsertSemicolon()) { - if (this.eat(types.arrow)) - { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) } - if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) { - id = this.parseIdent(); - if (this.canInsertSemicolon() || !this.eat(types.arrow)) - { this.unexpected(); } - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true) - } - } - return id - - case types.regexp: - var value = this.value; - node = this.parseLiteral(value.value); - node.regex = {pattern: value.pattern, flags: value.flags}; - return node - - case types.num: case types.string: - return this.parseLiteral(this.value) - - case types._null: case types._true: case types._false: - node = this.startNode(); - node.value = this.type === types._null ? null : this.type === types._true; - node.raw = this.type.keyword; + elem.tail = this.type === types.backQuote; + return this.finishNode(elem, "TemplateElement") + }; + pp$3.parseTemplate = function(ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; + var node = this.startNode(); this.next(); - return this.finishNode(node, "Literal") - - case types.parenL: - var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow); - if (refDestructuringErrors) { - if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr)) - { refDestructuringErrors.parenthesizedAssign = start; } - if (refDestructuringErrors.parenthesizedBind < 0) - { refDestructuringErrors.parenthesizedBind = start; } + node.expressions = []; + var curElt = this.parseTemplateElement({isTagged: isTagged}); + node.quasis = [curElt]; + while (!curElt.tail) { + if (this$1.type === types.eof) { this$1.raise(this$1.pos, "Unterminated template literal"); } + this$1.expect(types.dollarBraceL); + node.expressions.push(this$1.parseExpression()); + this$1.expect(types.braceR); + node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged})); } - return expr - - case types.bracketL: - node = this.startNode(); - this.next(); - node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors); - return this.finishNode(node, "ArrayExpression") - - case types.braceL: - return this.parseObj(false, refDestructuringErrors) - - case types._function: - node = this.startNode(); this.next(); - return this.parseFunction(node, false) - - case types._class: - return this.parseClass(this.startNode(), false) - - case types._new: - return this.parseNew() - - case types.backQuote: - return this.parseTemplate() - - default: - this.unexpected(); - } -}; - -pp$3.parseLiteral = function(value) { - var node = this.startNode(); - node.value = value; - node.raw = this.input.slice(this.start, this.end); - this.next(); - return this.finishNode(node, "Literal") -}; - -pp$3.parseParenExpression = function() { - this.expect(types.parenL); - var val = this.parseExpression(); - this.expect(types.parenR); - return val -}; - -pp$3.parseParenAndDistinguishExpression = function(canBeArrow) { - var this$1 = this; - - var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8; - if (this.options.ecmaVersion >= 6) { + return this.finishNode(node, "TemplateLiteral") + }; + pp$3.isAsyncProp = function(prop) { + return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && + (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) && + !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) + }; + pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var this$1 = this; + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; this.next(); - - var innerStartPos = this.start, innerStartLoc = this.startLoc; - var exprList = [], first = true, lastIsComma = false; - var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart; - this.yieldPos = 0; - this.awaitPos = 0; - while (this.type !== types.parenR) { - first ? first = false : this$1.expect(types.comma); - if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) { - lastIsComma = true; - break - } else if (this$1.type === types.ellipsis) { - spreadStart = this$1.start; - exprList.push(this$1.parseParenItem(this$1.parseRestBinding())); - if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); } - break - } else { - exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem)); + while (!this.eat(types.braceR)) { + if (!first) { + this$1.expect(types.comma); + if (this$1.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + var prop = this$1.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); } + node.properties.push(prop); + } + return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") + }; + pp$3.parseProperty = function(isPattern, refDestructuringErrors) { + var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; + if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { + if (isPattern) { + prop.argument = this.parseIdent(false); + if (this.type === types.comma) { + this.raise(this.start, "Comma is not permitted after the rest element"); + } + return this.finishNode(prop, "RestElement") } + if (this.type === types.parenL && refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0) { + refDestructuringErrors.parenthesizedAssign = this.start; + } + if (refDestructuringErrors.parenthesizedBind < 0) { + refDestructuringErrors.parenthesizedBind = this.start; + } + } + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + return this.finishNode(prop, "SpreadElement") } - var innerEndPos = this.start, innerEndLoc = this.startLoc; - this.expect(types.parenR); - - if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) { - this.checkPatternErrors(refDestructuringErrors, false); - this.checkYieldAwaitInDefaultParams(); - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - return this.parseParenArrowList(startPos, startLoc, exprList) - } - - if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); } - if (spreadStart) { this.unexpected(spreadStart); } - this.checkExpressionErrors(refDestructuringErrors, true); - this.yieldPos = oldYieldPos || this.yieldPos; - this.awaitPos = oldAwaitPos || this.awaitPos; - - if (exprList.length > 1) { - val = this.startNodeAt(innerStartPos, innerStartLoc); - val.expressions = exprList; - this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc); - } else { - val = exprList[0]; + if (this.options.ecmaVersion >= 6) { + prop.method = false; + prop.shorthand = false; + if (isPattern || refDestructuringErrors) { + startPos = this.start; + startLoc = this.startLoc; + } + if (!isPattern) + { isGenerator = this.eat(types.star); } } - } else { - val = this.parseParenExpression(); - } - - if (this.options.preserveParens) { - var par = this.startNodeAt(startPos, startLoc); - par.expression = val; - return this.finishNode(par, "ParenthesizedExpression") - } else { - return val - } -}; - -pp$3.parseParenItem = function(item) { - return item -}; - -pp$3.parseParenArrowList = function(startPos, startLoc, exprList) { - return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList) -}; - - -var empty$1 = []; - -pp$3.parseNew = function() { - var node = this.startNode(); - var meta = this.parseIdent(true); - if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) { - node.meta = meta; var containsEsc = this.containsEsc; - node.property = this.parseIdent(true); - if (node.property.name !== "target" || containsEsc) - { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); } - if (!this.inFunction) - { this.raiseRecoverable(node.start, "new.target can only be used in functions"); } - return this.finishNode(node, "MetaProperty") - } - var startPos = this.start, startLoc = this.startLoc; - node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); - if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); } - else { node.arguments = empty$1; } - return this.finishNode(node, "NewExpression") -}; - - -pp$3.parseTemplateElement = function(ref) { - var isTagged = ref.isTagged; - - var elem = this.startNode(); - if (this.type === types.invalidTemplate) { - if (!isTagged) { - this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal"); - } - elem.value = { - raw: this.value, - cooked: null - }; - } else { - elem.value = { - raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"), - cooked: this.value - }; - } - this.next(); - elem.tail = this.type === types.backQuote; - return this.finishNode(elem, "TemplateElement") -}; - -pp$3.parseTemplate = function(ref) { - var this$1 = this; - if ( ref === void 0 ) ref = {}; - var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false; - - var node = this.startNode(); - this.next(); - node.expressions = []; - var curElt = this.parseTemplateElement({isTagged: isTagged}); - node.quasis = [curElt]; - while (!curElt.tail) { - if (this$1.type === types.eof) { this$1.raise(this$1.pos, "Unterminated template literal"); } - this$1.expect(types.dollarBraceL); - node.expressions.push(this$1.parseExpression()); - this$1.expect(types.braceR); - node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged})); - } - this.next(); - return this.finishNode(node, "TemplateLiteral") -}; - -pp$3.isAsyncProp = function(prop) { - return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" && - (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) && - !lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) -}; - - -pp$3.parseObj = function(isPattern, refDestructuringErrors) { - var this$1 = this; - - var node = this.startNode(), first = true, propHash = {}; - node.properties = []; - this.next(); - while (!this.eat(types.braceR)) { - if (!first) { - this$1.expect(types.comma); - if (this$1.afterTrailingComma(types.braceR)) { break } - } else { first = false; } - - var prop = this$1.parseProperty(isPattern, refDestructuringErrors); - if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); } - node.properties.push(prop); - } - return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression") -}; - -pp$3.parseProperty = function(isPattern, refDestructuringErrors) { - var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc; - if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) { - if (isPattern) { - prop.argument = this.parseIdent(false); - if (this.type === types.comma) { - this.raise(this.start, "Comma is not permitted after the rest element"); - } - return this.finishNode(prop, "RestElement") + this.parsePropertyName(prop); + if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { + isAsync = true; + isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); + this.parsePropertyName(prop, refDestructuringErrors); + } else { + isAsync = false; } - if (this.type === types.parenL && refDestructuringErrors) { - if (refDestructuringErrors.parenthesizedAssign < 0) { - refDestructuringErrors.parenthesizedAssign = this.start; + this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); + return this.finishNode(prop, "Property") + }; + pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { + if ((isGenerator || isAsync) && this.type === types.colon) + { this.unexpected(); } + if (this.eat(types.colon)) { + prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); + prop.kind = "init"; + } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) { + if (isPattern) { this.unexpected(); } + prop.kind = "init"; + prop.method = true; + prop.value = this.parseMethod(isGenerator, isAsync); + } else if (!isPattern && !containsEsc && + this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && + (prop.key.name === "get" || prop.key.name === "set") && + (this.type !== types.comma && this.type !== types.braceR)) { + if (isGenerator || isAsync) { this.unexpected(); } + prop.kind = prop.key.name; + this.parsePropertyName(prop); + prop.value = this.parseMethod(false); + var paramCount = prop.kind === "get" ? 0 : 1; + if (prop.value.params.length !== paramCount) { + var start = prop.value.start; + if (prop.kind === "get") + { this.raiseRecoverable(start, "getter should have no params"); } + else + { this.raiseRecoverable(start, "setter should have exactly one param"); } + } else { + if (prop.kind === "set" && prop.value.params[0].type === "RestElement") + { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } + } + } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { + this.checkUnreserved(prop.key); + prop.kind = "init"; + if (isPattern) { + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + } else if (this.type === types.eq && refDestructuringErrors) { + if (refDestructuringErrors.shorthandAssign < 0) + { refDestructuringErrors.shorthandAssign = this.start; } + prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + } else { + prop.value = prop.key; } - if (refDestructuringErrors.parenthesizedBind < 0) { - refDestructuringErrors.parenthesizedBind = this.start; + prop.shorthand = true; + } else { this.unexpected(); } + }; + pp$3.parsePropertyName = function(prop) { + if (this.options.ecmaVersion >= 6) { + if (this.eat(types.bracketL)) { + prop.computed = true; + prop.key = this.parseMaybeAssign(); + this.expect(types.bracketR); + return prop.key + } else { + prop.computed = false; } } - prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); - if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { - refDestructuringErrors.trailingComma = this.start; + return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true) + }; + pp$3.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { + node.generator = false; + node.expression = false; } - return this.finishNode(prop, "SpreadElement") - } - if (this.options.ecmaVersion >= 6) { - prop.method = false; - prop.shorthand = false; - if (isPattern || refDestructuringErrors) { - startPos = this.start; - startLoc = this.startLoc; - } - if (!isPattern) - { isGenerator = this.eat(types.star); } - } - var containsEsc = this.containsEsc; - this.parsePropertyName(prop); - if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) { - isAsync = true; - isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star); - this.parsePropertyName(prop, refDestructuringErrors); - } else { - isAsync = false; - } - this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc); - return this.finishNode(prop, "Property") -}; - -pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) { - if ((isGenerator || isAsync) && this.type === types.colon) - { this.unexpected(); } - - if (this.eat(types.colon)) { - prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors); - prop.kind = "init"; - } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) { - if (isPattern) { this.unexpected(); } - prop.kind = "init"; - prop.method = true; - prop.value = this.parseMethod(isGenerator, isAsync); - } else if (!isPattern && !containsEsc && - this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && - (prop.key.name === "get" || prop.key.name === "set") && - (this.type !== types.comma && this.type !== types.braceR)) { - if (isGenerator || isAsync) { this.unexpected(); } - prop.kind = prop.key.name; - this.parsePropertyName(prop); - prop.value = this.parseMethod(false); - var paramCount = prop.kind === "get" ? 0 : 1; - if (prop.value.params.length !== paramCount) { - var start = prop.value.start; - if (prop.kind === "get") - { this.raiseRecoverable(start, "getter should have no params"); } - else - { this.raiseRecoverable(start, "setter should have exactly one param"); } - } else { - if (prop.kind === "set" && prop.value.params[0].type === "RestElement") - { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); } - } - } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") { - this.checkUnreserved(prop.key); - prop.kind = "init"; - if (isPattern) { - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); - } else if (this.type === types.eq && refDestructuringErrors) { - if (refDestructuringErrors.shorthandAssign < 0) - { refDestructuringErrors.shorthandAssign = this.start; } - prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key); + if (this.options.ecmaVersion >= 8) + { node.async = false; } + }; + pp$3.parseMethod = function(isGenerator, isAsync) { + var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + this.inGenerator = node.generator; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; + this.enterFunctionScope(); + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false); + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, "FunctionExpression") + }; + pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldInGen = this.inGenerator, oldInAsync = this.inAsync, + oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; + this.enterFunctionScope(); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + this.inGenerator = false; + this.inAsync = node.async; + this.yieldPos = 0; + this.awaitPos = 0; + this.inFunction = true; + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true); + this.inGenerator = oldInGen; + this.inAsync = oldInAsync; + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.inFunction = oldInFunc; + return this.finishNode(node, "ArrowFunctionExpression") + }; + pp$3.parseFunctionBody = function(node, isArrowFunction) { + var isExpression = isArrowFunction && this.type !== types.braceL; + var oldStrict = this.strict, useStrict = false; + if (isExpression) { + node.body = this.parseMaybeAssign(); + node.expression = true; + this.checkParams(node, false); } else { - prop.value = prop.key; + var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); + if (!oldStrict || nonSimple) { + useStrict = this.strictDirective(this.end); + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params)); + node.body = this.parseBlock(false); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitFunctionScope(); + if (this.strict && node.id) { + this.checkLVal(node.id, "none"); + } + this.strict = oldStrict; + }; + pp$3.isSimpleParamList = function(params) { + for (var i = 0, list = params; i < list.length; i += 1) + { + var param = list[i]; + if (param.type !== "Identifier") { return false + } } + return true + }; + pp$3.checkParams = function(node, allowDuplicates) { + var this$1 = this; + var nameHash = {}; + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + this$1.checkLVal(param, "var", allowDuplicates ? null : nameHash); } - prop.shorthand = true; - } else { this.unexpected(); } -}; - -pp$3.parsePropertyName = function(prop) { - if (this.options.ecmaVersion >= 6) { - if (this.eat(types.bracketL)) { - prop.computed = true; - prop.key = this.parseMaybeAssign(); - this.expect(types.bracketR); - return prop.key - } else { - prop.computed = false; + }; + pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var this$1 = this; + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this$1.expect(types.comma); + if (allowTrailingComma && this$1.afterTrailingComma(close)) { break } + } else { first = false; } + var elt = (void 0); + if (allowEmpty && this$1.type === types.comma) + { elt = null; } + else if (this$1.type === types.ellipsis) { + elt = this$1.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this$1.start; } + } else { + elt = this$1.parseMaybeAssign(false, refDestructuringErrors); + } + elts.push(elt); } - } - return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true) -}; - - -pp$3.initFunction = function(node) { - node.id = null; - if (this.options.ecmaVersion >= 6) { - node.generator = false; - node.expression = false; - } - if (this.options.ecmaVersion >= 8) - { node.async = false; } -}; - - -pp$3.parseMethod = function(isGenerator, isAsync) { - var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync, - oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; - - this.initFunction(node); - if (this.options.ecmaVersion >= 6) - { node.generator = isGenerator; } - if (this.options.ecmaVersion >= 8) - { node.async = !!isAsync; } - - this.inGenerator = node.generator; - this.inAsync = node.async; - this.yieldPos = 0; - this.awaitPos = 0; - this.inFunction = true; - this.enterFunctionScope(); - - this.expect(types.parenL); - node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); - this.checkYieldAwaitInDefaultParams(); - this.parseFunctionBody(node, false); - - this.inGenerator = oldInGen; - this.inAsync = oldInAsync; - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.inFunction = oldInFunc; - return this.finishNode(node, "FunctionExpression") -}; - - -pp$3.parseArrowExpression = function(node, params, isAsync) { - var oldInGen = this.inGenerator, oldInAsync = this.inAsync, - oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction; - - this.enterFunctionScope(); - this.initFunction(node); - if (this.options.ecmaVersion >= 8) - { node.async = !!isAsync; } - - this.inGenerator = false; - this.inAsync = node.async; - this.yieldPos = 0; - this.awaitPos = 0; - this.inFunction = true; - - node.params = this.toAssignableList(params, true); - this.parseFunctionBody(node, true); - - this.inGenerator = oldInGen; - this.inAsync = oldInAsync; - this.yieldPos = oldYieldPos; - this.awaitPos = oldAwaitPos; - this.inFunction = oldInFunc; - return this.finishNode(node, "ArrowFunctionExpression") -}; - - -pp$3.parseFunctionBody = function(node, isArrowFunction) { - var isExpression = isArrowFunction && this.type !== types.braceL; - var oldStrict = this.strict, useStrict = false; - - if (isExpression) { - node.body = this.parseMaybeAssign(); - node.expression = true; - this.checkParams(node, false); - } else { - var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params); - if (!oldStrict || nonSimple) { - useStrict = this.strictDirective(this.end); - if (useStrict && nonSimple) - { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } - } - var oldLabels = this.labels; - this.labels = []; - if (useStrict) { this.strict = true; } - - this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params)); - node.body = this.parseBlock(false); - node.expression = false; - this.adaptDirectivePrologue(node.body.body); - this.labels = oldLabels; - } - this.exitFunctionScope(); - - if (this.strict && node.id) { - this.checkLVal(node.id, "none"); - } - this.strict = oldStrict; -}; - -pp$3.isSimpleParamList = function(params) { - for (var i = 0, list = params; i < list.length; i += 1) - { - var param = list[i]; - - if (param.type !== "Identifier") { return false - } } - return true -}; - - -pp$3.checkParams = function(node, allowDuplicates) { - var this$1 = this; - - var nameHash = {}; - for (var i = 0, list = node.params; i < list.length; i += 1) - { - var param = list[i]; - - this$1.checkLVal(param, "var", allowDuplicates ? null : nameHash); - } -}; - - -pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { - var this$1 = this; - - var elts = [], first = true; - while (!this.eat(close)) { - if (!first) { - this$1.expect(types.comma); - if (allowTrailingComma && this$1.afterTrailingComma(close)) { break } - } else { first = false; } - - var elt = (void 0); - if (allowEmpty && this$1.type === types.comma) - { elt = null; } - else if (this$1.type === types.ellipsis) { - elt = this$1.parseSpread(refDestructuringErrors); - if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0) - { refDestructuringErrors.trailingComma = this$1.start; } + return elts + }; + pp$3.checkUnreserved = function(ref) { + var start = ref.start; + var end = ref.end; + var name = ref.name; + if (this.inGenerator && name === "yield") + { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); } + if (this.isKeyword(name)) + { this.raise(start, ("Unexpected keyword '" + name + "'")); } + if (this.options.ecmaVersion < 6 && + this.input.slice(start, end).indexOf("\\") !== -1) { return } + var re = this.strict ? this.reservedWordsStrict : this.reservedWords; + if (re.test(name)) { + if (!this.inAsync && name === "await") + { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } + }; + pp$3.parseIdent = function(liberal, isBinding) { + var node = this.startNode(); + if (liberal && this.options.allowReserved === "never") { liberal = false; } + if (this.type === types.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } } else { - elt = this$1.parseMaybeAssign(false, refDestructuringErrors); + this.unexpected(); } - elts.push(elt); - } - return elts -}; - -pp$3.checkUnreserved = function(ref) { - var start = ref.start; - var end = ref.end; - var name = ref.name; - - if (this.inGenerator && name === "yield") - { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); } - if (this.inAsync && name === "await") - { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); } - if (this.isKeyword(name)) - { this.raise(start, ("Unexpected keyword '" + name + "'")); } - if (this.options.ecmaVersion < 6 && - this.input.slice(start, end).indexOf("\\") !== -1) { return } - var re = this.strict ? this.reservedWordsStrict : this.reservedWords; - if (re.test(name)) { - if (!this.inAsync && name === "await") - { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); } - this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); - } -}; - - -pp$3.parseIdent = function(liberal, isBinding) { - var node = this.startNode(); - if (liberal && this.options.allowReserved === "never") { liberal = false; } - if (this.type === types.name) { - node.name = this.value; - } else if (this.type.keyword) { - node.name = this.type.keyword; - - if ((node.name === "class" || node.name === "function") && - (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { - this.context.pop(); + this.next(); + this.finishNode(node, "Identifier"); + if (!liberal) { this.checkUnreserved(node); } + return node + }; + pp$3.parseYield = function() { + if (!this.yieldPos) { this.yieldPos = this.start; } + var node = this.startNode(); + this.next(); + if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) { + node.delegate = false; + node.argument = null; + } else { + node.delegate = this.eat(types.star); + node.argument = this.parseMaybeAssign(); } - } else { - this.unexpected(); - } - this.next(); - this.finishNode(node, "Identifier"); - if (!liberal) { this.checkUnreserved(node); } - return node -}; - - -pp$3.parseYield = function() { - if (!this.yieldPos) { this.yieldPos = this.start; } - - var node = this.startNode(); - this.next(); - if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) { - node.delegate = false; - node.argument = null; - } else { - node.delegate = this.eat(types.star); - node.argument = this.parseMaybeAssign(); - } - return this.finishNode(node, "YieldExpression") -}; - -pp$3.parseAwait = function() { - if (!this.awaitPos) { this.awaitPos = this.start; } - - var node = this.startNode(); - this.next(); - node.argument = this.parseMaybeUnary(null, true); - return this.finishNode(node, "AwaitExpression") -}; - -var pp$4 = Parser.prototype; - - -pp$4.raise = function(pos, message) { - var loc = getLineInfo(this.input, pos); - message += " (" + loc.line + ":" + loc.column + ")"; - var err = new SyntaxError(message); - err.pos = pos; err.loc = loc; err.raisedAt = this.pos; - throw err -}; - -pp$4.raiseRecoverable = pp$4.raise; - -pp$4.curPosition = function() { - if (this.options.locations) { - return new Position(this.curLine, this.pos - this.lineStart) - } -}; - -var pp$5 = Parser.prototype; - -var assign = Object.assign || function(target) { - var sources = [], len = arguments.length - 1; - while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; - - for (var i = 0, list = sources; i < list.length; i += 1) { - var source = list[i]; - - for (var key in source) { - if (has(source, key)) { - target[key] = source[key]; + return this.finishNode(node, "YieldExpression") + }; + pp$3.parseAwait = function() { + if (!this.awaitPos) { this.awaitPos = this.start; } + var node = this.startNode(); + this.next(); + node.argument = this.parseMaybeUnary(null, true); + return this.finishNode(node, "AwaitExpression") + }; + var pp$4 = Parser.prototype; + pp$4.raise = function(pos, message) { + var loc = getLineInfo(this.input, pos); + message += " (" + loc.line + ":" + loc.column + ")"; + var err = new SyntaxError(message); + err.pos = pos; err.loc = loc; err.raisedAt = this.pos; + throw err + }; + pp$4.raiseRecoverable = pp$4.raise; + pp$4.curPosition = function() { + if (this.options.locations) { + return new Position(this.curLine, this.pos - this.lineStart) + } + }; + var pp$5 = Parser.prototype; + var assign = Object.assign || function(target) { + var sources = [], len = arguments.length - 1; + while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ]; + for (var i = 0, list = sources; i < list.length; i += 1) { + var source = list[i]; + for (var key in source) { + if (has(source, key)) { + target[key] = source[key]; + } } } + return target + }; + pp$5.enterFunctionScope = function() { + this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}}); + }; + pp$5.exitFunctionScope = function() { + this.scopeStack.pop(); + }; + pp$5.enterLexicalScope = function() { + var parentScope = this.scopeStack[this.scopeStack.length - 1]; + var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}}; + this.scopeStack.push(childScope); + assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical); + }; + pp$5.exitLexicalScope = function() { + var childScope = this.scopeStack.pop(); + var parentScope = this.scopeStack[this.scopeStack.length - 1]; + assign(parentScope.childVar, childScope.var, childScope.childVar); + }; + pp$5.canDeclareVarName = function(name) { + var currentScope = this.scopeStack[this.scopeStack.length - 1]; + return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name) + }; + pp$5.canDeclareLexicalName = function(name) { + var currentScope = this.scopeStack[this.scopeStack.length - 1]; + return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name) + }; + pp$5.declareVarName = function(name) { + this.scopeStack[this.scopeStack.length - 1].var[name] = true; + }; + pp$5.declareLexicalName = function(name) { + this.scopeStack[this.scopeStack.length - 1].lexical[name] = true; + }; + var Node = function Node(parser, pos, loc) { + this.type = ""; + this.start = pos; + this.end = 0; + if (parser.options.locations) + { this.loc = new SourceLocation(parser, loc); } + if (parser.options.directSourceFile) + { this.sourceFile = parser.options.directSourceFile; } + if (parser.options.ranges) + { this.range = [pos, 0]; } + }; + var pp$6 = Parser.prototype; + pp$6.startNode = function() { + return new Node(this, this.start, this.startLoc) + }; + pp$6.startNodeAt = function(pos, loc) { + return new Node(this, pos, loc) + }; + function finishNodeAt(node, type, pos, loc) { + node.type = type; + node.end = pos; + if (this.options.locations) + { node.loc.end = loc; } + if (this.options.ranges) + { node.range[1] = pos; } + return node } - return target -}; - - -pp$5.enterFunctionScope = function() { - this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}}); -}; - -pp$5.exitFunctionScope = function() { - this.scopeStack.pop(); -}; - -pp$5.enterLexicalScope = function() { - var parentScope = this.scopeStack[this.scopeStack.length - 1]; - var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}}; - - this.scopeStack.push(childScope); - assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical); -}; - -pp$5.exitLexicalScope = function() { - var childScope = this.scopeStack.pop(); - var parentScope = this.scopeStack[this.scopeStack.length - 1]; - - assign(parentScope.childVar, childScope.var, childScope.childVar); -}; - -pp$5.canDeclareVarName = function(name) { - var currentScope = this.scopeStack[this.scopeStack.length - 1]; - - return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name) -}; - -pp$5.canDeclareLexicalName = function(name) { - var currentScope = this.scopeStack[this.scopeStack.length - 1]; - - return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name) -}; - -pp$5.declareVarName = function(name) { - this.scopeStack[this.scopeStack.length - 1].var[name] = true; -}; - -pp$5.declareLexicalName = function(name) { - this.scopeStack[this.scopeStack.length - 1].lexical[name] = true; -}; - -var Node = function Node(parser, pos, loc) { - this.type = ""; - this.start = pos; - this.end = 0; - if (parser.options.locations) - { this.loc = new SourceLocation(parser, loc); } - if (parser.options.directSourceFile) - { this.sourceFile = parser.options.directSourceFile; } - if (parser.options.ranges) - { this.range = [pos, 0]; } -}; - - -var pp$6 = Parser.prototype; - -pp$6.startNode = function() { - return new Node(this, this.start, this.startLoc) -}; - -pp$6.startNodeAt = function(pos, loc) { - return new Node(this, pos, loc) -}; - - -function finishNodeAt(node, type, pos, loc) { - node.type = type; - node.end = pos; - if (this.options.locations) - { node.loc.end = loc; } - if (this.options.ranges) - { node.range[1] = pos; } - return node -} - -pp$6.finishNode = function(node, type) { - return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) -}; - - -pp$6.finishNodeAt = function(node, type, pos, loc) { - return finishNodeAt.call(this, node, type, pos, loc) -}; - - -var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { - this.token = token; - this.isExpr = !!isExpr; - this.preserveSpace = !!preserveSpace; - this.override = override; - this.generator = !!generator; -}; - -var types$1 = { - b_stat: new TokContext("{", false), - b_expr: new TokContext("{", true), - b_tmpl: new TokContext("${", false), - p_stat: new TokContext("(", false), - p_expr: new TokContext("(", true), - q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), - f_stat: new TokContext("function", false), - f_expr: new TokContext("function", true), - f_expr_gen: new TokContext("function", true, false, null, true), - f_gen: new TokContext("function", false, false, null, true) -}; - -var pp$7 = Parser.prototype; - -pp$7.initialContext = function() { - return [types$1.b_stat] -}; - -pp$7.braceIsBlock = function(prevType) { - var parent = this.curContext(); - if (parent === types$1.f_expr || parent === types$1.f_stat) - { return true } - if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr)) - { return !parent.isExpr } - - if (prevType === types._return || prevType === types.name && this.exprAllowed) - { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } - if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow) - { return true } - if (prevType === types.braceL) - { return parent === types$1.b_stat } - if (prevType === types._var || prevType === types.name) - { return false } - return !this.exprAllowed -}; - -pp$7.inGeneratorContext = function() { - var this$1 = this; - - for (var i = this.context.length - 1; i >= 1; i--) { - var context = this$1.context[i]; - if (context.token === "function") - { return context.generator } - } - return false -}; - -pp$7.updateContext = function(prevType) { - var update, type = this.type; - if (type.keyword && prevType === types.dot) - { this.exprAllowed = false; } - else if (update = type.updateContext) - { update.call(this, prevType); } - else - { this.exprAllowed = type.beforeExpr; } -}; - - -types.parenR.updateContext = types.braceR.updateContext = function() { - if (this.context.length === 1) { + pp$6.finishNode = function(node, type) { + return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc) + }; + pp$6.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) + }; + var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) { + this.token = token; + this.isExpr = !!isExpr; + this.preserveSpace = !!preserveSpace; + this.override = override; + this.generator = !!generator; + }; + var types$1 = { + b_stat: new TokContext("{", false), + b_expr: new TokContext("{", true), + b_tmpl: new TokContext("${", false), + p_stat: new TokContext("(", false), + p_expr: new TokContext("(", true), + q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }), + f_stat: new TokContext("function", false), + f_expr: new TokContext("function", true), + f_expr_gen: new TokContext("function", true, false, null, true), + f_gen: new TokContext("function", false, false, null, true) + }; + var pp$7 = Parser.prototype; + pp$7.initialContext = function() { + return [types$1.b_stat] + }; + pp$7.braceIsBlock = function(prevType) { + var parent = this.curContext(); + if (parent === types$1.f_expr || parent === types$1.f_stat) + { return true } + if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr)) + { return !parent.isExpr } + if (prevType === types._return || prevType === types.name && this.exprAllowed) + { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) } + if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow) + { return true } + if (prevType === types.braceL) + { return parent === types$1.b_stat } + if (prevType === types._var || prevType === types.name) + { return false } + return !this.exprAllowed + }; + pp$7.inGeneratorContext = function() { + var this$1 = this; + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this$1.context[i]; + if (context.token === "function") + { return context.generator } + } + return false + }; + pp$7.updateContext = function(prevType) { + var update, type = this.type; + if (type.keyword && prevType === types.dot) + { this.exprAllowed = false; } + else if (update = type.updateContext) + { update.call(this, prevType); } + else + { this.exprAllowed = type.beforeExpr; } + }; + types.parenR.updateContext = types.braceR.updateContext = function() { + if (this.context.length === 1) { + this.exprAllowed = true; + return + } + var out = this.context.pop(); + if (out === types$1.b_stat && this.curContext().token === "function") { + out = this.context.pop(); + } + this.exprAllowed = !out.isExpr; + }; + types.braceL.updateContext = function(prevType) { + this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr); this.exprAllowed = true; - return - } - var out = this.context.pop(); - if (out === types$1.b_stat && this.curContext().token === "function") { - out = this.context.pop(); - } - this.exprAllowed = !out.isExpr; -}; - -types.braceL.updateContext = function(prevType) { - this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr); - this.exprAllowed = true; -}; - -types.dollarBraceL.updateContext = function() { - this.context.push(types$1.b_tmpl); - this.exprAllowed = true; -}; - -types.parenL.updateContext = function(prevType) { - var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; - this.context.push(statementParens ? types$1.p_stat : types$1.p_expr); - this.exprAllowed = true; -}; - -types.incDec.updateContext = function() { -}; - -types._function.updateContext = types._class.updateContext = function(prevType) { - if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && - !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) - { this.context.push(types$1.f_expr); } - else - { this.context.push(types$1.f_stat); } - this.exprAllowed = false; -}; - -types.backQuote.updateContext = function() { - if (this.curContext() === types$1.q_tmpl) - { this.context.pop(); } - else - { this.context.push(types$1.q_tmpl); } - this.exprAllowed = false; -}; - -types.star.updateContext = function(prevType) { - if (prevType === types._function) { - var index = this.context.length - 1; - if (this.context[index] === types$1.f_expr) - { this.context[index] = types$1.f_expr_gen; } + }; + types.dollarBraceL.updateContext = function() { + this.context.push(types$1.b_tmpl); + this.exprAllowed = true; + }; + types.parenL.updateContext = function(prevType) { + var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while; + this.context.push(statementParens ? types$1.p_stat : types$1.p_expr); + this.exprAllowed = true; + }; + types.incDec.updateContext = function() { + }; + types._function.updateContext = types._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && + !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat)) + { this.context.push(types$1.f_expr); } else - { this.context[index] = types$1.f_gen; } - } - this.exprAllowed = true; -}; - -types.name.updateContext = function(prevType) { - var allowed = false; - if (this.options.ecmaVersion >= 6 && prevType !== types.dot) { - if (this.value === "of" && !this.exprAllowed || - this.value === "yield" && this.inGeneratorContext()) - { allowed = true; } - } - this.exprAllowed = allowed; -}; - -var data = { - "$LONE": [ - "ASCII", - "ASCII_Hex_Digit", - "AHex", - "Alphabetic", - "Alpha", - "Any", - "Assigned", - "Bidi_Control", - "Bidi_C", - "Bidi_Mirrored", - "Bidi_M", - "Case_Ignorable", - "CI", - "Cased", - "Changes_When_Casefolded", - "CWCF", - "Changes_When_Casemapped", - "CWCM", - "Changes_When_Lowercased", - "CWL", - "Changes_When_NFKC_Casefolded", - "CWKCF", - "Changes_When_Titlecased", - "CWT", - "Changes_When_Uppercased", - "CWU", - "Dash", - "Default_Ignorable_Code_Point", - "DI", - "Deprecated", - "Dep", - "Diacritic", - "Dia", - "Emoji", - "Emoji_Component", - "Emoji_Modifier", - "Emoji_Modifier_Base", - "Emoji_Presentation", - "Extender", - "Ext", - "Grapheme_Base", - "Gr_Base", - "Grapheme_Extend", - "Gr_Ext", - "Hex_Digit", - "Hex", - "IDS_Binary_Operator", - "IDSB", - "IDS_Trinary_Operator", - "IDST", - "ID_Continue", - "IDC", - "ID_Start", - "IDS", - "Ideographic", - "Ideo", - "Join_Control", - "Join_C", - "Logical_Order_Exception", - "LOE", - "Lowercase", - "Lower", - "Math", - "Noncharacter_Code_Point", - "NChar", - "Pattern_Syntax", - "Pat_Syn", - "Pattern_White_Space", - "Pat_WS", - "Quotation_Mark", - "QMark", - "Radical", - "Regional_Indicator", - "RI", - "Sentence_Terminal", - "STerm", - "Soft_Dotted", - "SD", - "Terminal_Punctuation", - "Term", - "Unified_Ideograph", - "UIdeo", - "Uppercase", - "Upper", - "Variation_Selector", - "VS", - "White_Space", - "space", - "XID_Continue", - "XIDC", - "XID_Start", - "XIDS" - ], - "General_Category": [ - "Cased_Letter", - "LC", - "Close_Punctuation", - "Pe", - "Connector_Punctuation", - "Pc", - "Control", - "Cc", - "cntrl", - "Currency_Symbol", - "Sc", - "Dash_Punctuation", - "Pd", - "Decimal_Number", - "Nd", - "digit", - "Enclosing_Mark", - "Me", - "Final_Punctuation", - "Pf", - "Format", - "Cf", - "Initial_Punctuation", - "Pi", - "Letter", - "L", - "Letter_Number", - "Nl", - "Line_Separator", - "Zl", - "Lowercase_Letter", - "Ll", - "Mark", - "M", - "Combining_Mark", - "Math_Symbol", - "Sm", - "Modifier_Letter", - "Lm", - "Modifier_Symbol", - "Sk", - "Nonspacing_Mark", - "Mn", - "Number", - "N", - "Open_Punctuation", - "Ps", - "Other", - "C", - "Other_Letter", - "Lo", - "Other_Number", - "No", - "Other_Punctuation", - "Po", - "Other_Symbol", - "So", - "Paragraph_Separator", - "Zp", - "Private_Use", - "Co", - "Punctuation", - "P", - "punct", - "Separator", - "Z", - "Space_Separator", - "Zs", - "Spacing_Mark", - "Mc", - "Surrogate", - "Cs", - "Symbol", - "S", - "Titlecase_Letter", - "Lt", - "Unassigned", - "Cn", - "Uppercase_Letter", - "Lu" - ], - "Script": [ - "Adlam", - "Adlm", - "Ahom", - "Anatolian_Hieroglyphs", - "Hluw", - "Arabic", - "Arab", - "Armenian", - "Armn", - "Avestan", - "Avst", - "Balinese", - "Bali", - "Bamum", - "Bamu", - "Bassa_Vah", - "Bass", - "Batak", - "Batk", - "Bengali", - "Beng", - "Bhaiksuki", - "Bhks", - "Bopomofo", - "Bopo", - "Brahmi", - "Brah", - "Braille", - "Brai", - "Buginese", - "Bugi", - "Buhid", - "Buhd", - "Canadian_Aboriginal", - "Cans", - "Carian", - "Cari", - "Caucasian_Albanian", - "Aghb", - "Chakma", - "Cakm", - "Cham", - "Cherokee", - "Cher", - "Common", - "Zyyy", - "Coptic", - "Copt", - "Qaac", - "Cuneiform", - "Xsux", - "Cypriot", - "Cprt", - "Cyrillic", - "Cyrl", - "Deseret", - "Dsrt", - "Devanagari", - "Deva", - "Duployan", - "Dupl", - "Egyptian_Hieroglyphs", - "Egyp", - "Elbasan", - "Elba", - "Ethiopic", - "Ethi", - "Georgian", - "Geor", - "Glagolitic", - "Glag", - "Gothic", - "Goth", - "Grantha", - "Gran", - "Greek", - "Grek", - "Gujarati", - "Gujr", - "Gurmukhi", - "Guru", - "Han", - "Hani", - "Hangul", - "Hang", - "Hanunoo", - "Hano", - "Hatran", - "Hatr", - "Hebrew", - "Hebr", - "Hiragana", - "Hira", - "Imperial_Aramaic", - "Armi", - "Inherited", - "Zinh", - "Qaai", - "Inscriptional_Pahlavi", - "Phli", - "Inscriptional_Parthian", - "Prti", - "Javanese", - "Java", - "Kaithi", - "Kthi", - "Kannada", - "Knda", - "Katakana", - "Kana", - "Kayah_Li", - "Kali", - "Kharoshthi", - "Khar", - "Khmer", - "Khmr", - "Khojki", - "Khoj", - "Khudawadi", - "Sind", - "Lao", - "Laoo", - "Latin", - "Latn", - "Lepcha", - "Lepc", - "Limbu", - "Limb", - "Linear_A", - "Lina", - "Linear_B", - "Linb", - "Lisu", - "Lycian", - "Lyci", - "Lydian", - "Lydi", - "Mahajani", - "Mahj", - "Malayalam", - "Mlym", - "Mandaic", - "Mand", - "Manichaean", - "Mani", - "Marchen", - "Marc", - "Masaram_Gondi", - "Gonm", - "Meetei_Mayek", - "Mtei", - "Mende_Kikakui", - "Mend", - "Meroitic_Cursive", - "Merc", - "Meroitic_Hieroglyphs", - "Mero", - "Miao", - "Plrd", - "Modi", - "Mongolian", - "Mong", - "Mro", - "Mroo", - "Multani", - "Mult", - "Myanmar", - "Mymr", - "Nabataean", - "Nbat", - "New_Tai_Lue", - "Talu", - "Newa", - "Nko", - "Nkoo", - "Nushu", - "Nshu", - "Ogham", - "Ogam", - "Ol_Chiki", - "Olck", - "Old_Hungarian", - "Hung", - "Old_Italic", - "Ital", - "Old_North_Arabian", - "Narb", - "Old_Permic", - "Perm", - "Old_Persian", - "Xpeo", - "Old_South_Arabian", - "Sarb", - "Old_Turkic", - "Orkh", - "Oriya", - "Orya", - "Osage", - "Osge", - "Osmanya", - "Osma", - "Pahawh_Hmong", - "Hmng", - "Palmyrene", - "Palm", - "Pau_Cin_Hau", - "Pauc", - "Phags_Pa", - "Phag", - "Phoenician", - "Phnx", - "Psalter_Pahlavi", - "Phlp", - "Rejang", - "Rjng", - "Runic", - "Runr", - "Samaritan", - "Samr", - "Saurashtra", - "Saur", - "Sharada", - "Shrd", - "Shavian", - "Shaw", - "Siddham", - "Sidd", - "SignWriting", - "Sgnw", - "Sinhala", - "Sinh", - "Sora_Sompeng", - "Sora", - "Soyombo", - "Soyo", - "Sundanese", - "Sund", - "Syloti_Nagri", - "Sylo", - "Syriac", - "Syrc", - "Tagalog", - "Tglg", - "Tagbanwa", - "Tagb", - "Tai_Le", - "Tale", - "Tai_Tham", - "Lana", - "Tai_Viet", - "Tavt", - "Takri", - "Takr", - "Tamil", - "Taml", - "Tangut", - "Tang", - "Telugu", - "Telu", - "Thaana", - "Thaa", - "Thai", - "Tibetan", - "Tibt", - "Tifinagh", - "Tfng", - "Tirhuta", - "Tirh", - "Ugaritic", - "Ugar", - "Vai", - "Vaii", - "Warang_Citi", - "Wara", - "Yi", - "Yiii", - "Zanabazar_Square", - "Zanb" - ] -}; -Array.prototype.push.apply(data.$LONE, data.General_Category); -data.gc = data.General_Category; -data.sc = data.Script_Extensions = data.scx = data.Script; - -var pp$9 = Parser.prototype; - -var RegExpValidationState = function RegExpValidationState(parser) { - this.parser = parser; - this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); - this.source = ""; - this.flags = ""; - this.start = 0; - this.switchU = false; - this.switchN = false; - this.pos = 0; - this.lastIntValue = 0; - this.lastStringValue = ""; - this.lastAssertionIsQuantifiable = false; - this.numCapturingParens = 0; - this.maxBackReference = 0; - this.groupNames = []; - this.backReferenceNames = []; -}; - -RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { - var unicode = flags.indexOf("u") !== -1; - this.start = start | 0; - this.source = pattern + ""; - this.flags = flags; - this.switchU = unicode && this.parser.options.ecmaVersion >= 6; - this.switchN = unicode && this.parser.options.ecmaVersion >= 9; -}; - -RegExpValidationState.prototype.raise = function raise (message) { - this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); -}; - -RegExpValidationState.prototype.at = function at (i) { - var s = this.source; - var l = s.length; - if (i >= l) { - return -1 - } - var c = s.charCodeAt(i); - if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { - return c - } - return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00 -}; - -RegExpValidationState.prototype.nextIndex = function nextIndex (i) { - var s = this.source; - var l = s.length; - if (i >= l) { - return l - } - var c = s.charCodeAt(i); - if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { - return i + 1 - } - return i + 2 -}; - -RegExpValidationState.prototype.current = function current () { - return this.at(this.pos) -}; - -RegExpValidationState.prototype.lookahead = function lookahead () { - return this.at(this.nextIndex(this.pos)) -}; - -RegExpValidationState.prototype.advance = function advance () { - this.pos = this.nextIndex(this.pos); -}; - -RegExpValidationState.prototype.eat = function eat (ch) { - if (this.current() === ch) { - this.advance(); - return true - } - return false -}; - -function codePointToString$1(ch) { - if (ch <= 0xFFFF) { return String.fromCharCode(ch) } - ch -= 0x10000; - return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) -} - -pp$9.validateRegExpFlags = function(state) { - var this$1 = this; - - var validFlags = state.validFlags; - var flags = state.flags; - - for (var i = 0; i < flags.length; i++) { - var flag = flags.charAt(i); - if (validFlags.indexOf(flag) === -1) { - this$1.raise(state.start, "Invalid regular expression flag"); + { this.context.push(types$1.f_stat); } + this.exprAllowed = false; + }; + types.backQuote.updateContext = function() { + if (this.curContext() === types$1.q_tmpl) + { this.context.pop(); } + else + { this.context.push(types$1.q_tmpl); } + this.exprAllowed = false; + }; + types.star.updateContext = function(prevType) { + if (prevType === types._function) { + var index = this.context.length - 1; + if (this.context[index] === types$1.f_expr) + { this.context[index] = types$1.f_expr_gen; } + else + { this.context[index] = types$1.f_gen; } } - if (flags.indexOf(flag, i + 1) > -1) { - this$1.raise(state.start, "Duplicate regular expression flag"); + this.exprAllowed = true; + }; + types.name.updateContext = function(prevType) { + var allowed = false; + if (this.options.ecmaVersion >= 6 && prevType !== types.dot) { + if (this.value === "of" && !this.exprAllowed || + this.value === "yield" && this.inGeneratorContext()) + { allowed = true; } + } + this.exprAllowed = allowed; + }; + var data = { + "$LONE": [ + "ASCII", + "ASCII_Hex_Digit", + "AHex", + "Alphabetic", + "Alpha", + "Any", + "Assigned", + "Bidi_Control", + "Bidi_C", + "Bidi_Mirrored", + "Bidi_M", + "Case_Ignorable", + "CI", + "Cased", + "Changes_When_Casefolded", + "CWCF", + "Changes_When_Casemapped", + "CWCM", + "Changes_When_Lowercased", + "CWL", + "Changes_When_NFKC_Casefolded", + "CWKCF", + "Changes_When_Titlecased", + "CWT", + "Changes_When_Uppercased", + "CWU", + "Dash", + "Default_Ignorable_Code_Point", + "DI", + "Deprecated", + "Dep", + "Diacritic", + "Dia", + "Emoji", + "Emoji_Component", + "Emoji_Modifier", + "Emoji_Modifier_Base", + "Emoji_Presentation", + "Extender", + "Ext", + "Grapheme_Base", + "Gr_Base", + "Grapheme_Extend", + "Gr_Ext", + "Hex_Digit", + "Hex", + "IDS_Binary_Operator", + "IDSB", + "IDS_Trinary_Operator", + "IDST", + "ID_Continue", + "IDC", + "ID_Start", + "IDS", + "Ideographic", + "Ideo", + "Join_Control", + "Join_C", + "Logical_Order_Exception", + "LOE", + "Lowercase", + "Lower", + "Math", + "Noncharacter_Code_Point", + "NChar", + "Pattern_Syntax", + "Pat_Syn", + "Pattern_White_Space", + "Pat_WS", + "Quotation_Mark", + "QMark", + "Radical", + "Regional_Indicator", + "RI", + "Sentence_Terminal", + "STerm", + "Soft_Dotted", + "SD", + "Terminal_Punctuation", + "Term", + "Unified_Ideograph", + "UIdeo", + "Uppercase", + "Upper", + "Variation_Selector", + "VS", + "White_Space", + "space", + "XID_Continue", + "XIDC", + "XID_Start", + "XIDS" + ], + "General_Category": [ + "Cased_Letter", + "LC", + "Close_Punctuation", + "Pe", + "Connector_Punctuation", + "Pc", + "Control", + "Cc", + "cntrl", + "Currency_Symbol", + "Sc", + "Dash_Punctuation", + "Pd", + "Decimal_Number", + "Nd", + "digit", + "Enclosing_Mark", + "Me", + "Final_Punctuation", + "Pf", + "Format", + "Cf", + "Initial_Punctuation", + "Pi", + "Letter", + "L", + "Letter_Number", + "Nl", + "Line_Separator", + "Zl", + "Lowercase_Letter", + "Ll", + "Mark", + "M", + "Combining_Mark", + "Math_Symbol", + "Sm", + "Modifier_Letter", + "Lm", + "Modifier_Symbol", + "Sk", + "Nonspacing_Mark", + "Mn", + "Number", + "N", + "Open_Punctuation", + "Ps", + "Other", + "C", + "Other_Letter", + "Lo", + "Other_Number", + "No", + "Other_Punctuation", + "Po", + "Other_Symbol", + "So", + "Paragraph_Separator", + "Zp", + "Private_Use", + "Co", + "Punctuation", + "P", + "punct", + "Separator", + "Z", + "Space_Separator", + "Zs", + "Spacing_Mark", + "Mc", + "Surrogate", + "Cs", + "Symbol", + "S", + "Titlecase_Letter", + "Lt", + "Unassigned", + "Cn", + "Uppercase_Letter", + "Lu" + ], + "Script": [ + "Adlam", + "Adlm", + "Ahom", + "Anatolian_Hieroglyphs", + "Hluw", + "Arabic", + "Arab", + "Armenian", + "Armn", + "Avestan", + "Avst", + "Balinese", + "Bali", + "Bamum", + "Bamu", + "Bassa_Vah", + "Bass", + "Batak", + "Batk", + "Bengali", + "Beng", + "Bhaiksuki", + "Bhks", + "Bopomofo", + "Bopo", + "Brahmi", + "Brah", + "Braille", + "Brai", + "Buginese", + "Bugi", + "Buhid", + "Buhd", + "Canadian_Aboriginal", + "Cans", + "Carian", + "Cari", + "Caucasian_Albanian", + "Aghb", + "Chakma", + "Cakm", + "Cham", + "Cherokee", + "Cher", + "Common", + "Zyyy", + "Coptic", + "Copt", + "Qaac", + "Cuneiform", + "Xsux", + "Cypriot", + "Cprt", + "Cyrillic", + "Cyrl", + "Deseret", + "Dsrt", + "Devanagari", + "Deva", + "Duployan", + "Dupl", + "Egyptian_Hieroglyphs", + "Egyp", + "Elbasan", + "Elba", + "Ethiopic", + "Ethi", + "Georgian", + "Geor", + "Glagolitic", + "Glag", + "Gothic", + "Goth", + "Grantha", + "Gran", + "Greek", + "Grek", + "Gujarati", + "Gujr", + "Gurmukhi", + "Guru", + "Han", + "Hani", + "Hangul", + "Hang", + "Hanunoo", + "Hano", + "Hatran", + "Hatr", + "Hebrew", + "Hebr", + "Hiragana", + "Hira", + "Imperial_Aramaic", + "Armi", + "Inherited", + "Zinh", + "Qaai", + "Inscriptional_Pahlavi", + "Phli", + "Inscriptional_Parthian", + "Prti", + "Javanese", + "Java", + "Kaithi", + "Kthi", + "Kannada", + "Knda", + "Katakana", + "Kana", + "Kayah_Li", + "Kali", + "Kharoshthi", + "Khar", + "Khmer", + "Khmr", + "Khojki", + "Khoj", + "Khudawadi", + "Sind", + "Lao", + "Laoo", + "Latin", + "Latn", + "Lepcha", + "Lepc", + "Limbu", + "Limb", + "Linear_A", + "Lina", + "Linear_B", + "Linb", + "Lisu", + "Lycian", + "Lyci", + "Lydian", + "Lydi", + "Mahajani", + "Mahj", + "Malayalam", + "Mlym", + "Mandaic", + "Mand", + "Manichaean", + "Mani", + "Marchen", + "Marc", + "Masaram_Gondi", + "Gonm", + "Meetei_Mayek", + "Mtei", + "Mende_Kikakui", + "Mend", + "Meroitic_Cursive", + "Merc", + "Meroitic_Hieroglyphs", + "Mero", + "Miao", + "Plrd", + "Modi", + "Mongolian", + "Mong", + "Mro", + "Mroo", + "Multani", + "Mult", + "Myanmar", + "Mymr", + "Nabataean", + "Nbat", + "New_Tai_Lue", + "Talu", + "Newa", + "Nko", + "Nkoo", + "Nushu", + "Nshu", + "Ogham", + "Ogam", + "Ol_Chiki", + "Olck", + "Old_Hungarian", + "Hung", + "Old_Italic", + "Ital", + "Old_North_Arabian", + "Narb", + "Old_Permic", + "Perm", + "Old_Persian", + "Xpeo", + "Old_South_Arabian", + "Sarb", + "Old_Turkic", + "Orkh", + "Oriya", + "Orya", + "Osage", + "Osge", + "Osmanya", + "Osma", + "Pahawh_Hmong", + "Hmng", + "Palmyrene", + "Palm", + "Pau_Cin_Hau", + "Pauc", + "Phags_Pa", + "Phag", + "Phoenician", + "Phnx", + "Psalter_Pahlavi", + "Phlp", + "Rejang", + "Rjng", + "Runic", + "Runr", + "Samaritan", + "Samr", + "Saurashtra", + "Saur", + "Sharada", + "Shrd", + "Shavian", + "Shaw", + "Siddham", + "Sidd", + "SignWriting", + "Sgnw", + "Sinhala", + "Sinh", + "Sora_Sompeng", + "Sora", + "Soyombo", + "Soyo", + "Sundanese", + "Sund", + "Syloti_Nagri", + "Sylo", + "Syriac", + "Syrc", + "Tagalog", + "Tglg", + "Tagbanwa", + "Tagb", + "Tai_Le", + "Tale", + "Tai_Tham", + "Lana", + "Tai_Viet", + "Tavt", + "Takri", + "Takr", + "Tamil", + "Taml", + "Tangut", + "Tang", + "Telugu", + "Telu", + "Thaana", + "Thaa", + "Thai", + "Tibetan", + "Tibt", + "Tifinagh", + "Tfng", + "Tirhuta", + "Tirh", + "Ugaritic", + "Ugar", + "Vai", + "Vaii", + "Warang_Citi", + "Wara", + "Yi", + "Yiii", + "Zanabazar_Square", + "Zanb" + ] + }; + Array.prototype.push.apply(data.$LONE, data.General_Category); + data.gc = data.General_Category; + data.sc = data.Script_Extensions = data.scx = data.Script; + var pp$9 = Parser.prototype; + var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); + this.source = ""; + this.flags = ""; + this.start = 0; + this.switchU = false; + this.switchN = false; + this.pos = 0; + this.lastIntValue = 0; + this.lastStringValue = ""; + this.lastAssertionIsQuantifiable = false; + this.numCapturingParens = 0; + this.maxBackReference = 0; + this.groupNames = []; + this.backReferenceNames = []; + }; + RegExpValidationState.prototype.reset = function reset (start, pattern, flags) { + var unicode = flags.indexOf("u") !== -1; + this.start = start | 0; + this.source = pattern + ""; + this.flags = flags; + this.switchU = unicode && this.parser.options.ecmaVersion >= 6; + this.switchN = unicode && this.parser.options.ecmaVersion >= 9; + }; + RegExpValidationState.prototype.raise = function raise (message) { + this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message)); + }; + RegExpValidationState.prototype.at = function at (i) { + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 } - } -}; - -pp$9.validateRegExpPattern = function(state) { - this.regexp_pattern(state); - - if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { - state.switchN = true; - this.regexp_pattern(state); - } -}; - -pp$9.regexp_pattern = function(state) { - state.pos = 0; - state.lastIntValue = 0; - state.lastStringValue = ""; - state.lastAssertionIsQuantifiable = false; - state.numCapturingParens = 0; - state.maxBackReference = 0; - state.groupNames.length = 0; - state.backReferenceNames.length = 0; - - this.regexp_disjunction(state); - - if (state.pos !== state.source.length) { - if (state.eat(0x29 )) { - state.raise("Unmatched ')'"); + var c = s.charCodeAt(i); + if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c } - if (state.eat(0x5D ) || state.eat(0x7D )) { - state.raise("Lone quantifier brackets"); + return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00 + }; + RegExpValidationState.prototype.nextIndex = function nextIndex (i) { + var s = this.source; + var l = s.length; + if (i >= l) { + return l } - } - if (state.maxBackReference > state.numCapturingParens) { - state.raise("Invalid escape"); - } - for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { - var name = list[i]; - - if (state.groupNames.indexOf(name) === -1) { - state.raise("Invalid named capture referenced"); + var c = s.charCodeAt(i); + if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return i + 1 } + return i + 2 + }; + RegExpValidationState.prototype.current = function current () { + return this.at(this.pos) + }; + RegExpValidationState.prototype.lookahead = function lookahead () { + return this.at(this.nextIndex(this.pos)) + }; + RegExpValidationState.prototype.advance = function advance () { + this.pos = this.nextIndex(this.pos); + }; + RegExpValidationState.prototype.eat = function eat (ch) { + if (this.current() === ch) { + this.advance(); + return true + } + return false + }; + function codePointToString$1(ch) { + if (ch <= 0xFFFF) { return String.fromCharCode(ch) } + ch -= 0x10000; + return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) } -}; - -pp$9.regexp_disjunction = function(state) { - var this$1 = this; - - this.regexp_alternative(state); - while (state.eat(0x7C )) { - this$1.regexp_alternative(state); - } - - if (this.regexp_eatQuantifier(state, true)) { - state.raise("Nothing to repeat"); - } - if (state.eat(0x7B )) { - state.raise("Lone quantifier brackets"); - } -}; - -pp$9.regexp_alternative = function(state) { - while (state.pos < state.source.length && this.regexp_eatTerm(state)) - { } -}; - -pp$9.regexp_eatTerm = function(state) { - if (this.regexp_eatAssertion(state)) { - if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { - if (state.switchU) { - state.raise("Invalid quantifier"); + pp$9.validateRegExpFlags = function(state) { + var this$1 = this; + var validFlags = state.validFlags; + var flags = state.flags; + for (var i = 0; i < flags.length; i++) { + var flag = flags.charAt(i); + if (validFlags.indexOf(flag) === -1) { + this$1.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this$1.raise(state.start, "Duplicate regular expression flag"); } } - return true - } - - if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { - this.regexp_eatQuantifier(state); - return true - } - - return false -}; - -pp$9.regexp_eatAssertion = function(state) { - var start = state.pos; - state.lastAssertionIsQuantifiable = false; - - if (state.eat(0x5E ) || state.eat(0x24 )) { - return true - } - - if (state.eat(0x5C )) { - if (state.eat(0x42 ) || state.eat(0x62 )) { - return true + }; + pp$9.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + state.switchN = true; + this.regexp_pattern(state); } - state.pos = start; - } - - if (state.eat(0x28 ) && state.eat(0x3F )) { - var lookbehind = false; - if (this.options.ecmaVersion >= 9) { - lookbehind = state.eat(0x3C ); + }; + pp$9.regexp_pattern = function(state) { + state.pos = 0; + state.lastIntValue = 0; + state.lastStringValue = ""; + state.lastAssertionIsQuantifiable = false; + state.numCapturingParens = 0; + state.maxBackReference = 0; + state.groupNames.length = 0; + state.backReferenceNames.length = 0; + this.regexp_disjunction(state); + if (state.pos !== state.source.length) { + if (state.eat(0x29 )) { + state.raise("Unmatched ')'"); + } + if (state.eat(0x5D ) || state.eat(0x7D )) { + state.raise("Lone quantifier brackets"); + } } - if (state.eat(0x3D ) || state.eat(0x21 )) { - this.regexp_disjunction(state); - if (!state.eat(0x29 )) { - state.raise("Unterminated group"); + if (state.maxBackReference > state.numCapturingParens) { + state.raise("Invalid escape"); + } + for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) { + var name = list[i]; + if (state.groupNames.indexOf(name) === -1) { + state.raise("Invalid named capture referenced"); } - state.lastAssertionIsQuantifiable = !lookbehind; - return true } - } - - state.pos = start; - return false -}; - -pp$9.regexp_eatQuantifier = function(state, noError) { - if ( noError === void 0 ) noError = false; - - if (this.regexp_eatQuantifierPrefix(state, noError)) { - state.eat(0x3F ); - return true - } - return false -}; - -pp$9.regexp_eatQuantifierPrefix = function(state, noError) { - return ( - state.eat(0x2A ) || - state.eat(0x2B ) || - state.eat(0x3F ) || - this.regexp_eatBracedQuantifier(state, noError) - ) -}; -pp$9.regexp_eatBracedQuantifier = function(state, noError) { - var start = state.pos; - if (state.eat(0x7B )) { - var min = 0, max = -1; - if (this.regexp_eatDecimalDigits(state)) { - min = state.lastIntValue; - if (state.eat(0x2C ) && this.regexp_eatDecimalDigits(state)) { - max = state.lastIntValue; - } - if (state.eat(0x7D )) { - if (max !== -1 && max < min && !noError) { - state.raise("numbers out of order in {} quantifier"); + }; + pp$9.regexp_disjunction = function(state) { + var this$1 = this; + this.regexp_alternative(state); + while (state.eat(0x7C )) { + this$1.regexp_alternative(state); + } + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B )) { + state.raise("Lone quantifier brackets"); + } + }; + pp$9.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) + { } + }; + pp$9.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + if (state.switchU) { + state.raise("Invalid quantifier"); } - return true } + return true } - if (state.switchU && !noError) { - state.raise("Incomplete quantifier"); + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true } - state.pos = start; - } - return false -}; - -pp$9.regexp_eatAtom = function(state) { - return ( - this.regexp_eatPatternCharacters(state) || - state.eat(0x2E ) || - this.regexp_eatReverseSolidusAtomEscape(state) || - this.regexp_eatCharacterClass(state) || - this.regexp_eatUncapturingGroup(state) || - this.regexp_eatCapturingGroup(state) - ) -}; -pp$9.regexp_eatReverseSolidusAtomEscape = function(state) { - var start = state.pos; - if (state.eat(0x5C )) { - if (this.regexp_eatAtomEscape(state)) { + return false + }; + pp$9.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + if (state.eat(0x5E ) || state.eat(0x24 )) { return true } - state.pos = start; - } - return false -}; -pp$9.regexp_eatUncapturingGroup = function(state) { - var start = state.pos; - if (state.eat(0x28 )) { - if (state.eat(0x3F ) && state.eat(0x3A )) { - this.regexp_disjunction(state); - if (state.eat(0x29 )) { + if (state.eat(0x5C )) { + if (state.eat(0x42 ) || state.eat(0x62 )) { return true } - state.raise("Unterminated group"); + state.pos = start; } - state.pos = start; - } - return false -}; -pp$9.regexp_eatCapturingGroup = function(state) { - if (state.eat(0x28 )) { - if (this.options.ecmaVersion >= 9) { - this.regexp_groupSpecifier(state); - } else if (state.current() === 0x3F ) { - state.raise("Invalid group"); + if (state.eat(0x28 ) && state.eat(0x3F )) { + var lookbehind = false; + if (this.options.ecmaVersion >= 9) { + lookbehind = state.eat(0x3C ); + } + if (state.eat(0x3D ) || state.eat(0x21 )) { + this.regexp_disjunction(state); + if (!state.eat(0x29 )) { + state.raise("Unterminated group"); + } + state.lastAssertionIsQuantifiable = !lookbehind; + return true + } } - this.regexp_disjunction(state); - if (state.eat(0x29 )) { - state.numCapturingParens += 1; + state.pos = start; + return false + }; + pp$9.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F ); return true } - state.raise("Unterminated group"); - } - return false -}; - -pp$9.regexp_eatExtendedAtom = function(state) { - return ( - state.eat(0x2E ) || - this.regexp_eatReverseSolidusAtomEscape(state) || - this.regexp_eatCharacterClass(state) || - this.regexp_eatUncapturingGroup(state) || - this.regexp_eatCapturingGroup(state) || - this.regexp_eatInvalidBracedQuantifier(state) || - this.regexp_eatExtendedPatternCharacter(state) - ) -}; - -pp$9.regexp_eatInvalidBracedQuantifier = function(state) { - if (this.regexp_eatBracedQuantifier(state, true)) { - state.raise("Nothing to repeat"); - } - return false -}; - -pp$9.regexp_eatSyntaxCharacter = function(state) { - var ch = state.current(); - if (isSyntaxCharacter(ch)) { - state.lastIntValue = ch; - state.advance(); - return true - } - return false -}; -function isSyntaxCharacter(ch) { - return ( - ch === 0x24 || - ch >= 0x28 && ch <= 0x2B || - ch === 0x2E || - ch === 0x3F || - ch >= 0x5B && ch <= 0x5E || - ch >= 0x7B && ch <= 0x7D - ) -} - -pp$9.regexp_eatPatternCharacters = function(state) { - var start = state.pos; - var ch = 0; - while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { - state.advance(); - } - return state.pos !== start -}; - -pp$9.regexp_eatExtendedPatternCharacter = function(state) { - var ch = state.current(); - if ( - ch !== -1 && - ch !== 0x24 && - !(ch >= 0x28 && ch <= 0x2B ) && - ch !== 0x2E && - ch !== 0x3F && - ch !== 0x5B && - ch !== 0x5E && - ch !== 0x7C - ) { - state.advance(); - return true - } - return false -}; - -pp$9.regexp_groupSpecifier = function(state) { - if (state.eat(0x3F )) { - if (this.regexp_eatGroupName(state)) { - if (state.groupNames.indexOf(state.lastStringValue) !== -1) { - state.raise("Duplicate capture group name"); + return false + }; + pp$9.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A ) || + state.eat(0x2B ) || + state.eat(0x3F ) || + this.regexp_eatBracedQuantifier(state, noError) + ) + }; + pp$9.regexp_eatBracedQuantifier = function(state, noError) { + var start = state.pos; + if (state.eat(0x7B )) { + var min = 0, max = -1; + if (this.regexp_eatDecimalDigits(state)) { + min = state.lastIntValue; + if (state.eat(0x2C ) && this.regexp_eatDecimalDigits(state)) { + max = state.lastIntValue; + } + if (state.eat(0x7D )) { + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true + } } - state.groupNames.push(state.lastStringValue); - return - } - state.raise("Invalid group"); - } -}; - -pp$9.regexp_eatGroupName = function(state) { - state.lastStringValue = ""; - if (state.eat(0x3C )) { - if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E )) { - return true + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; } - state.raise("Invalid capture group name"); - } - return false -}; - -pp$9.regexp_eatRegExpIdentifierName = function(state) { - state.lastStringValue = ""; - if (this.regexp_eatRegExpIdentifierStart(state)) { - state.lastStringValue += codePointToString$1(state.lastIntValue); - while (this.regexp_eatRegExpIdentifierPart(state)) { - state.lastStringValue += codePointToString$1(state.lastIntValue); + return false + }; + pp$9.regexp_eatAtom = function(state) { + return ( + this.regexp_eatPatternCharacters(state) || + state.eat(0x2E ) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) + ) + }; + pp$9.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C )) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; } - return true - } - return false -}; - -pp$9.regexp_eatRegExpIdentifierStart = function(state) { - var start = state.pos; - var ch = state.current(); - state.advance(); - - if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { - ch = state.lastIntValue; - } - if (isRegExpIdentifierStart(ch)) { - state.lastIntValue = ch; - return true - } - - state.pos = start; - return false -}; -function isRegExpIdentifierStart(ch) { - return isIdentifierStart(ch, true) || ch === 0x24 || ch === 0x5F -} - -pp$9.regexp_eatRegExpIdentifierPart = function(state) { - var start = state.pos; - var ch = state.current(); - state.advance(); - - if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { - ch = state.lastIntValue; - } - if (isRegExpIdentifierPart(ch)) { - state.lastIntValue = ch; - return true - } - - state.pos = start; - return false -}; -function isRegExpIdentifierPart(ch) { - return isIdentifierChar(ch, true) || ch === 0x24 || ch === 0x5F || ch === 0x200C || ch === 0x200D -} - -pp$9.regexp_eatAtomEscape = function(state) { - if ( - this.regexp_eatBackReference(state) || - this.regexp_eatCharacterClassEscape(state) || - this.regexp_eatCharacterEscape(state) || - (state.switchN && this.regexp_eatKGroupName(state)) - ) { - return true - } - if (state.switchU) { - if (state.current() === 0x63 ) { - state.raise("Invalid unicode escape"); + return false + }; + pp$9.regexp_eatUncapturingGroup = function(state) { + var start = state.pos; + if (state.eat(0x28 )) { + if (state.eat(0x3F ) && state.eat(0x3A )) { + this.regexp_disjunction(state); + if (state.eat(0x29 )) { + return true + } + state.raise("Unterminated group"); + } + state.pos = start; } - state.raise("Invalid escape"); - } - return false -}; -pp$9.regexp_eatBackReference = function(state) { - var start = state.pos; - if (this.regexp_eatDecimalEscape(state)) { - var n = state.lastIntValue; - if (state.switchU) { - if (n > state.maxBackReference) { - state.maxBackReference = n; + return false + }; + pp$9.regexp_eatCapturingGroup = function(state) { + if (state.eat(0x28 )) { + if (this.options.ecmaVersion >= 9) { + this.regexp_groupSpecifier(state); + } else if (state.current() === 0x3F ) { + state.raise("Invalid group"); + } + this.regexp_disjunction(state); + if (state.eat(0x29 )) { + state.numCapturingParens += 1; + return true } + state.raise("Unterminated group"); + } + return false + }; + pp$9.regexp_eatExtendedAtom = function(state) { + return ( + state.eat(0x2E ) || + this.regexp_eatReverseSolidusAtomEscape(state) || + this.regexp_eatCharacterClass(state) || + this.regexp_eatUncapturingGroup(state) || + this.regexp_eatCapturingGroup(state) || + this.regexp_eatInvalidBracedQuantifier(state) || + this.regexp_eatExtendedPatternCharacter(state) + ) + }; + pp$9.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false + }; + pp$9.regexp_eatSyntaxCharacter = function(state) { + var ch = state.current(); + if (isSyntaxCharacter(ch)) { + state.lastIntValue = ch; + state.advance(); return true } - if (n <= state.numCapturingParens) { + return false + }; + function isSyntaxCharacter(ch) { + return ( + ch === 0x24 || + ch >= 0x28 && ch <= 0x2B || + ch === 0x2E || + ch === 0x3F || + ch >= 0x5B && ch <= 0x5E || + ch >= 0x7B && ch <= 0x7D + ) + } + pp$9.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); + } + return state.pos !== start + }; + pp$9.regexp_eatExtendedPatternCharacter = function(state) { + var ch = state.current(); + if ( + ch !== -1 && + ch !== 0x24 && + !(ch >= 0x28 && ch <= 0x2B ) && + ch !== 0x2E && + ch !== 0x3F && + ch !== 0x5B && + ch !== 0x5E && + ch !== 0x7C + ) { + state.advance(); return true } - state.pos = start; - } - return false -}; -pp$9.regexp_eatKGroupName = function(state) { - if (state.eat(0x6B )) { - if (this.regexp_eatGroupName(state)) { - state.backReferenceNames.push(state.lastStringValue); + return false + }; + pp$9.regexp_groupSpecifier = function(state) { + if (state.eat(0x3F )) { + if (this.regexp_eatGroupName(state)) { + if (state.groupNames.indexOf(state.lastStringValue) !== -1) { + state.raise("Duplicate capture group name"); + } + state.groupNames.push(state.lastStringValue); + return + } + state.raise("Invalid group"); + } + }; + pp$9.regexp_eatGroupName = function(state) { + state.lastStringValue = ""; + if (state.eat(0x3C )) { + if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E )) { + return true + } + state.raise("Invalid capture group name"); + } + return false + }; + pp$9.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString$1(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString$1(state.lastIntValue); + } return true } - state.raise("Invalid named reference"); - } - return false -}; - -pp$9.regexp_eatCharacterEscape = function(state) { - return ( - this.regexp_eatControlEscape(state) || - this.regexp_eatCControlLetter(state) || - this.regexp_eatZero(state) || - this.regexp_eatHexEscapeSequence(state) || - this.regexp_eatRegExpUnicodeEscapeSequence(state) || - (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || - this.regexp_eatIdentityEscape(state) - ) -}; -pp$9.regexp_eatCControlLetter = function(state) { - var start = state.pos; - if (state.eat(0x63 )) { - if (this.regexp_eatControlLetter(state)) { + return false + }; + pp$9.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var ch = state.current(); + state.advance(); + if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierStart(ch)) { + state.lastIntValue = ch; return true } state.pos = start; + return false + }; + function isRegExpIdentifierStart(ch) { + return isIdentifierStart(ch, true) || ch === 0x24 || ch === 0x5F } - return false -}; -pp$9.regexp_eatZero = function(state) { - if (state.current() === 0x30 && !isDecimalDigit(state.lookahead())) { - state.lastIntValue = 0; - state.advance(); - return true - } - return false -}; - -pp$9.regexp_eatControlEscape = function(state) { - var ch = state.current(); - if (ch === 0x74 ) { - state.lastIntValue = 0x09; - state.advance(); - return true - } - if (ch === 0x6E ) { - state.lastIntValue = 0x0A; - state.advance(); - return true - } - if (ch === 0x76 ) { - state.lastIntValue = 0x0B; - state.advance(); - return true - } - if (ch === 0x66 ) { - state.lastIntValue = 0x0C; - state.advance(); - return true - } - if (ch === 0x72 ) { - state.lastIntValue = 0x0D; - state.advance(); - return true - } - return false -}; - -pp$9.regexp_eatControlLetter = function(state) { - var ch = state.current(); - if (isControlLetter(ch)) { - state.lastIntValue = ch % 0x20; + pp$9.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var ch = state.current(); state.advance(); - return true - } - return false -}; -function isControlLetter(ch) { - return ( - (ch >= 0x41 && ch <= 0x5A ) || - (ch >= 0x61 && ch <= 0x7A ) - ) -} - -pp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) { - var start = state.pos; - - if (state.eat(0x75 )) { - if (this.regexp_eatFixedHexDigits(state, 4)) { - var lead = state.lastIntValue; - if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) { - var leadSurrogateEnd = state.pos; - if (state.eat(0x5C ) && state.eat(0x75 ) && this.regexp_eatFixedHexDigits(state, 4)) { - var trail = state.lastIntValue; - if (trail >= 0xDC00 && trail <= 0xDFFF) { - state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; - return true - } - } - state.pos = leadSurrogateEnd; - state.lastIntValue = lead; - } + if (ch === 0x5C && this.regexp_eatRegExpUnicodeEscapeSequence(state)) { + ch = state.lastIntValue; + } + if (isRegExpIdentifierPart(ch)) { + state.lastIntValue = ch; return true } + state.pos = start; + return false + }; + function isRegExpIdentifierPart(ch) { + return isIdentifierChar(ch, true) || ch === 0x24 || ch === 0x5F || ch === 0x200C || ch === 0x200D + } + pp$9.regexp_eatAtomEscape = function(state) { if ( - state.switchU && - state.eat(0x7B ) && - this.regexp_eatHexDigits(state) && - state.eat(0x7D ) && - isValidUnicode(state.lastIntValue) + this.regexp_eatBackReference(state) || + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) || + (state.switchN && this.regexp_eatKGroupName(state)) ) { return true } if (state.switchU) { - state.raise("Invalid unicode escape"); + if (state.current() === 0x63 ) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); } - state.pos = start; - } - - return false -}; -function isValidUnicode(ch) { - return ch >= 0 && ch <= 0x10FFFF -} - -pp$9.regexp_eatIdentityEscape = function(state) { - if (state.switchU) { - if (this.regexp_eatSyntaxCharacter(state)) { - return true + return false + }; + pp$9.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + if (n > state.maxBackReference) { + state.maxBackReference = n; + } + return true + } + if (n <= state.numCapturingParens) { + return true + } + state.pos = start; + } + return false + }; + pp$9.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B )) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true + } + state.raise("Invalid named reference"); + } + return false + }; + pp$9.regexp_eatCharacterEscape = function(state) { + return ( + this.regexp_eatControlEscape(state) || + this.regexp_eatCControlLetter(state) || + this.regexp_eatZero(state) || + this.regexp_eatHexEscapeSequence(state) || + this.regexp_eatRegExpUnicodeEscapeSequence(state) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) + }; + pp$9.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 )) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; } - if (state.eat(0x2F )) { - state.lastIntValue = 0x2F; + return false + }; + pp$9.regexp_eatZero = function(state) { + if (state.current() === 0x30 && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); return true } return false - } - - var ch = state.current(); - if (ch !== 0x63 && (!state.switchN || ch !== 0x6B )) { - state.lastIntValue = ch; - state.advance(); - return true - } - - return false -}; - -pp$9.regexp_eatDecimalEscape = function(state) { - state.lastIntValue = 0; - var ch = state.current(); - if (ch >= 0x31 && ch <= 0x39 ) { - do { - state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 ); + }; + pp$9.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 ) { + state.lastIntValue = 0x09; state.advance(); - } while ((ch = state.current()) >= 0x30 && ch <= 0x39 ) - return true - } - return false -}; - -pp$9.regexp_eatCharacterClassEscape = function(state) { - var ch = state.current(); - - if (isCharacterClassEscape(ch)) { - state.lastIntValue = -1; - state.advance(); - return true - } - - if ( - state.switchU && - this.options.ecmaVersion >= 9 && - (ch === 0x50 || ch === 0x70 ) - ) { - state.lastIntValue = -1; - state.advance(); - if ( - state.eat(0x7B ) && - this.regexp_eatUnicodePropertyValueExpression(state) && - state.eat(0x7D ) - ) { return true } - state.raise("Invalid property name"); - } - - return false -}; -function isCharacterClassEscape(ch) { - return ( - ch === 0x64 || - ch === 0x44 || - ch === 0x73 || - ch === 0x53 || - ch === 0x77 || - ch === 0x57 - ) -} - -pp$9.regexp_eatUnicodePropertyValueExpression = function(state) { - var start = state.pos; - - if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D )) { - var name = state.lastStringValue; - if (this.regexp_eatUnicodePropertyValue(state)) { - var value = state.lastStringValue; - this.regexp_validateUnicodePropertyNameAndValue(state, name, value); + if (ch === 0x6E ) { + state.lastIntValue = 0x0A; + state.advance(); return true } - } - state.pos = start; - - if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { - var nameOrValue = state.lastStringValue; - this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); - return true - } - return false -}; -pp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { - if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) { - state.raise("Invalid property name"); - } -}; -pp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { - if (data.$LONE.indexOf(nameOrValue) === -1) { - state.raise("Invalid property name"); - } -}; - -pp$9.regexp_eatUnicodePropertyName = function(state) { - var ch = 0; - state.lastStringValue = ""; - while (isUnicodePropertyNameCharacter(ch = state.current())) { - state.lastStringValue += codePointToString$1(ch); - state.advance(); - } - return state.lastStringValue !== "" -}; -function isUnicodePropertyNameCharacter(ch) { - return isControlLetter(ch) || ch === 0x5F -} - -pp$9.regexp_eatUnicodePropertyValue = function(state) { - var ch = 0; - state.lastStringValue = ""; - while (isUnicodePropertyValueCharacter(ch = state.current())) { - state.lastStringValue += codePointToString$1(ch); - state.advance(); - } - return state.lastStringValue !== "" -}; -function isUnicodePropertyValueCharacter(ch) { - return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) -} - -pp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { - return this.regexp_eatUnicodePropertyValue(state) -}; - -pp$9.regexp_eatCharacterClass = function(state) { - if (state.eat(0x5B )) { - state.eat(0x5E ); - this.regexp_classRanges(state); - if (state.eat(0x5D )) { + if (ch === 0x76 ) { + state.lastIntValue = 0x0B; + state.advance(); return true } - state.raise("Unterminated character class"); - } - return false -}; - -pp$9.regexp_classRanges = function(state) { - var this$1 = this; - - while (this.regexp_eatClassAtom(state)) { - var left = state.lastIntValue; - if (state.eat(0x2D ) && this$1.regexp_eatClassAtom(state)) { - var right = state.lastIntValue; - if (state.switchU && (left === -1 || right === -1)) { - state.raise("Invalid character class"); + if (ch === 0x66 ) { + state.lastIntValue = 0x0C; + state.advance(); + return true + } + if (ch === 0x72 ) { + state.lastIntValue = 0x0D; + state.advance(); + return true + } + return false + }; + pp$9.regexp_eatControlLetter = function(state) { + var ch = state.current(); + if (isControlLetter(ch)) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + function isControlLetter(ch) { + return ( + (ch >= 0x41 && ch <= 0x5A ) || + (ch >= 0x61 && ch <= 0x7A ) + ) + } + pp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x75 )) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C ) && state.eat(0x75 ) && this.regexp_eatFixedHexDigits(state, 4)) { + var trail = state.lastIntValue; + if (trail >= 0xDC00 && trail <= 0xDFFF) { + state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000; + return true + } + } + state.pos = leadSurrogateEnd; + state.lastIntValue = lead; + } + return true } - if (left !== -1 && right !== -1 && left > right) { - state.raise("Range out of order in character class"); + if ( + state.switchU && + state.eat(0x7B ) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D ) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (state.switchU) { + state.raise("Invalid unicode escape"); } + state.pos = start; } + return false + }; + function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF } -}; - -pp$9.regexp_eatClassAtom = function(state) { - var start = state.pos; - - if (state.eat(0x5C )) { - if (this.regexp_eatClassEscape(state)) { - return true - } + pp$9.regexp_eatIdentityEscape = function(state) { if (state.switchU) { - var ch$1 = state.current(); - if (ch$1 === 0x63 || isOctalDigit(ch$1)) { - state.raise("Invalid class escape"); + if (this.regexp_eatSyntaxCharacter(state)) { + return true } - state.raise("Invalid escape"); + if (state.eat(0x2F )) { + state.lastIntValue = 0x2F; + return true + } + return false } - state.pos = start; - } - - var ch = state.current(); - if (ch !== 0x5D ) { - state.lastIntValue = ch; - state.advance(); - return true - } - - return false -}; - -pp$9.regexp_eatClassEscape = function(state) { - var start = state.pos; - - if (state.eat(0x62 )) { - state.lastIntValue = 0x08; - return true - } - - if (state.switchU && state.eat(0x2D )) { - state.lastIntValue = 0x2D; - return true - } - - if (!state.switchU && state.eat(0x63 )) { - if (this.regexp_eatClassControlLetter(state)) { + var ch = state.current(); + if (ch !== 0x63 && (!state.switchN || ch !== 0x6B )) { + state.lastIntValue = ch; + state.advance(); return true } - state.pos = start; - } - - return ( - this.regexp_eatCharacterClassEscape(state) || - this.regexp_eatCharacterEscape(state) - ) -}; - -pp$9.regexp_eatClassControlLetter = function(state) { - var ch = state.current(); - if (isDecimalDigit(ch) || ch === 0x5F ) { - state.lastIntValue = ch % 0x20; - state.advance(); - return true - } - return false -}; - -pp$9.regexp_eatHexEscapeSequence = function(state) { - var start = state.pos; - if (state.eat(0x78 )) { - if (this.regexp_eatFixedHexDigits(state, 2)) { + return false + }; + pp$9.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 && ch <= 0x39 ) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 ); + state.advance(); + } while ((ch = state.current()) >= 0x30 && ch <= 0x39 ) return true } - if (state.switchU) { - state.raise("Invalid escape"); + return false + }; + pp$9.regexp_eatCharacterClassEscape = function(state) { + var ch = state.current(); + if (isCharacterClassEscape(ch)) { + state.lastIntValue = -1; + state.advance(); + return true + } + if ( + state.switchU && + this.options.ecmaVersion >= 9 && + (ch === 0x50 || ch === 0x70 ) + ) { + state.lastIntValue = -1; + state.advance(); + if ( + state.eat(0x7B ) && + this.regexp_eatUnicodePropertyValueExpression(state) && + state.eat(0x7D ) + ) { + return true + } + state.raise("Invalid property name"); + } + return false + }; + function isCharacterClassEscape(ch) { + return ( + ch === 0x64 || + ch === 0x44 || + ch === 0x73 || + ch === 0x53 || + ch === 0x77 || + ch === 0x57 + ) + } + pp$9.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; + if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D )) { + var name = state.lastStringValue; + if (this.regexp_eatUnicodePropertyValue(state)) { + var value = state.lastStringValue; + this.regexp_validateUnicodePropertyNameAndValue(state, name, value); + return true + } } state.pos = start; + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); + return true + } + return false + }; + pp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) { + state.raise("Invalid property name"); + } + }; + pp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (data.$LONE.indexOf(nameOrValue) === -1) { + state.raise("Invalid property name"); + } + }; + pp$9.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString$1(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F + } + pp$9.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString$1(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) } - return false -}; - -pp$9.regexp_eatDecimalDigits = function(state) { - var start = state.pos; - var ch = 0; - state.lastIntValue = 0; - while (isDecimalDigit(ch = state.current())) { - state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 ); - state.advance(); - } - return state.pos !== start -}; -function isDecimalDigit(ch) { - return ch >= 0x30 && ch <= 0x39 -} - -pp$9.regexp_eatHexDigits = function(state) { - var start = state.pos; - var ch = 0; - state.lastIntValue = 0; - while (isHexDigit(ch = state.current())) { - state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); - state.advance(); + pp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) + }; + pp$9.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B )) { + state.eat(0x5E ); + this.regexp_classRanges(state); + if (state.eat(0x5D )) { + return true + } + state.raise("Unterminated character class"); + } + return false + }; + pp$9.regexp_classRanges = function(state) { + var this$1 = this; + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D ) && this$1.regexp_eatClassAtom(state)) { + var right = state.lastIntValue; + if (state.switchU && (left === -1 || right === -1)) { + state.raise("Invalid character class"); + } + if (left !== -1 && right !== -1 && left > right) { + state.raise("Range out of order in character class"); + } + } + } + }; + pp$9.regexp_eatClassAtom = function(state) { + var start = state.pos; + if (state.eat(0x5C )) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + var ch$1 = state.current(); + if (ch$1 === 0x63 || isOctalDigit(ch$1)) { + state.raise("Invalid class escape"); + } + state.raise("Invalid escape"); + } + state.pos = start; + } + var ch = state.current(); + if (ch !== 0x5D ) { + state.lastIntValue = ch; + state.advance(); + return true + } + return false + }; + pp$9.regexp_eatClassEscape = function(state) { + var start = state.pos; + if (state.eat(0x62 )) { + state.lastIntValue = 0x08; + return true + } + if (state.switchU && state.eat(0x2D )) { + state.lastIntValue = 0x2D; + return true + } + if (!state.switchU && state.eat(0x63 )) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) + }; + pp$9.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F ) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + pp$9.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 )) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true + } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; + } + return false + }; + pp$9.regexp_eatDecimalDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isDecimalDigit(ch = state.current())) { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 ); + state.advance(); + } + return state.pos !== start + }; + function isDecimalDigit(ch) { + return ch >= 0x30 && ch <= 0x39 } - return state.pos !== start -}; -function isHexDigit(ch) { - return ( - (ch >= 0x30 && ch <= 0x39 ) || - (ch >= 0x41 && ch <= 0x46 ) || - (ch >= 0x61 && ch <= 0x66 ) - ) -} -function hexToInt(ch) { - if (ch >= 0x41 && ch <= 0x46 ) { - return 10 + (ch - 0x41 ) + pp$9.regexp_eatHexDigits = function(state) { + var start = state.pos; + var ch = 0; + state.lastIntValue = 0; + while (isHexDigit(ch = state.current())) { + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); + } + return state.pos !== start + }; + function isHexDigit(ch) { + return ( + (ch >= 0x30 && ch <= 0x39 ) || + (ch >= 0x41 && ch <= 0x46 ) || + (ch >= 0x61 && ch <= 0x66 ) + ) } - if (ch >= 0x61 && ch <= 0x66 ) { - return 10 + (ch - 0x61 ) + function hexToInt(ch) { + if (ch >= 0x41 && ch <= 0x46 ) { + return 10 + (ch - 0x41 ) + } + if (ch >= 0x61 && ch <= 0x66 ) { + return 10 + (ch - 0x61 ) + } + return ch - 0x30 } - return ch - 0x30 -} - -pp$9.regexp_eatLegacyOctalEscapeSequence = function(state) { - if (this.regexp_eatOctalDigit(state)) { - var n1 = state.lastIntValue; + pp$9.regexp_eatLegacyOctalEscapeSequence = function(state) { if (this.regexp_eatOctalDigit(state)) { - var n2 = state.lastIntValue; - if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { - state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + var n1 = state.lastIntValue; + if (this.regexp_eatOctalDigit(state)) { + var n2 = state.lastIntValue; + if (n1 <= 3 && this.regexp_eatOctalDigit(state)) { + state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue; + } else { + state.lastIntValue = n1 * 8 + n2; + } } else { - state.lastIntValue = n1 * 8 + n2; + state.lastIntValue = n1; } - } else { - state.lastIntValue = n1; + return true } - return true - } - return false -}; - -pp$9.regexp_eatOctalDigit = function(state) { - var ch = state.current(); - if (isOctalDigit(ch)) { - state.lastIntValue = ch - 0x30; - state.advance(); - return true - } - state.lastIntValue = 0; - return false -}; -function isOctalDigit(ch) { - return ch >= 0x30 && ch <= 0x37 -} - -pp$9.regexp_eatFixedHexDigits = function(state, length) { - var start = state.pos; - state.lastIntValue = 0; - for (var i = 0; i < length; ++i) { + return false + }; + pp$9.regexp_eatOctalDigit = function(state) { var ch = state.current(); - if (!isHexDigit(ch)) { - state.pos = start; - return false + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; + state.advance(); + return true } - state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); - state.advance(); + state.lastIntValue = 0; + return false + }; + function isOctalDigit(ch) { + return ch >= 0x30 && ch <= 0x37 } - return true -}; - - -var Token = function Token(p) { - this.type = p.type; - this.value = p.value; - this.start = p.start; - this.end = p.end; - if (p.options.locations) - { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } - if (p.options.ranges) - { this.range = [p.start, p.end]; } -}; - - -var pp$8 = Parser.prototype; - - -pp$8.next = function() { - if (this.options.onToken) - { this.options.onToken(new Token(this)); } - - this.lastTokEnd = this.end; - this.lastTokStart = this.start; - this.lastTokEndLoc = this.endLoc; - this.lastTokStartLoc = this.startLoc; - this.nextToken(); -}; - -pp$8.getToken = function() { - this.next(); - return new Token(this) -}; - -if (typeof Symbol !== "undefined") - { pp$8[Symbol.iterator] = function() { - var this$1 = this; - - return { - next: function () { - var token = this$1.getToken(); - return { - done: token.type === types.eof, - value: token - } + pp$9.regexp_eatFixedHexDigits = function(state, length) { + var start = state.pos; + state.lastIntValue = 0; + for (var i = 0; i < length; ++i) { + var ch = state.current(); + if (!isHexDigit(ch)) { + state.pos = start; + return false } + state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch); + state.advance(); } - }; } - - -pp$8.curContext = function() { - return this.context[this.context.length - 1] -}; - - -pp$8.nextToken = function() { - var curContext = this.curContext(); - if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } - - this.start = this.pos; - if (this.options.locations) { this.startLoc = this.curPosition(); } - if (this.pos >= this.input.length) { return this.finishToken(types.eof) } - - if (curContext.override) { return curContext.override(this) } - else { this.readToken(this.fullCharCodeAtPos()); } -}; - -pp$8.readToken = function(code) { - if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 ) - { return this.readWord() } - - return this.getTokenFromCode(code) -}; - -pp$8.fullCharCodeAtPos = function() { - var code = this.input.charCodeAt(this.pos); - if (code <= 0xd7ff || code >= 0xe000) { return code } - var next = this.input.charCodeAt(this.pos + 1); - return (code << 10) + next - 0x35fdc00 -}; - -pp$8.skipBlockComment = function() { - var this$1 = this; - - var startLoc = this.options.onComment && this.curPosition(); - var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); - if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } - this.pos = end + 2; - if (this.options.locations) { - lineBreakG.lastIndex = start; - var match; - while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { - ++this$1.curLine; - this$1.lineStart = match.index + match[0].length; - } - } - if (this.options.onComment) - { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, - startLoc, this.curPosition()); } -}; - -pp$8.skipLineComment = function(startSkip) { - var this$1 = this; - - var start = this.pos; - var startLoc = this.options.onComment && this.curPosition(); - var ch = this.input.charCodeAt(this.pos += startSkip); - while (this.pos < this.input.length && !isNewLine(ch)) { - ch = this$1.input.charCodeAt(++this$1.pos); - } - if (this.options.onComment) - { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, - startLoc, this.curPosition()); } -}; - - -pp$8.skipSpace = function() { - var this$1 = this; - - loop: while (this.pos < this.input.length) { - var ch = this$1.input.charCodeAt(this$1.pos); - switch (ch) { - case 32: case 160: - ++this$1.pos; - break - case 13: - if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { - ++this$1.pos; + return true + }; + var Token = function Token(p) { + this.type = p.type; + this.value = p.value; + this.start = p.start; + this.end = p.end; + if (p.options.locations) + { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); } + if (p.options.ranges) + { this.range = [p.start, p.end]; } + }; + var pp$8 = Parser.prototype; + pp$8.next = function() { + if (this.options.onToken) + { this.options.onToken(new Token(this)); } + this.lastTokEnd = this.end; + this.lastTokStart = this.start; + this.lastTokEndLoc = this.endLoc; + this.lastTokStartLoc = this.startLoc; + this.nextToken(); + }; + pp$8.getToken = function() { + this.next(); + return new Token(this) + }; + if (typeof Symbol !== "undefined") + { pp$8[Symbol.iterator] = function() { + var this$1 = this; + return { + next: function () { + var token = this$1.getToken(); + return { + done: token.type === types.eof, + value: token + } + } } - case 10: case 8232: case 8233: - ++this$1.pos; - if (this$1.options.locations) { + }; } + pp$8.curContext = function() { + return this.context[this.context.length - 1] + }; + pp$8.nextToken = function() { + var curContext = this.curContext(); + if (!curContext || !curContext.preserveSpace) { this.skipSpace(); } + this.start = this.pos; + if (this.options.locations) { this.startLoc = this.curPosition(); } + if (this.pos >= this.input.length) { return this.finishToken(types.eof) } + if (curContext.override) { return curContext.override(this) } + else { this.readToken(this.fullCharCodeAtPos()); } + }; + pp$8.readToken = function(code) { + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 ) + { return this.readWord() } + return this.getTokenFromCode(code) + }; + pp$8.fullCharCodeAtPos = function() { + var code = this.input.charCodeAt(this.pos); + if (code <= 0xd7ff || code >= 0xe000) { return code } + var next = this.input.charCodeAt(this.pos + 1); + return (code << 10) + next - 0x35fdc00 + }; + pp$8.skipBlockComment = function() { + var this$1 = this; + var startLoc = this.options.onComment && this.curPosition(); + var start = this.pos, end = this.input.indexOf("*/", this.pos += 2); + if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); } + this.pos = end + 2; + if (this.options.locations) { + lineBreakG.lastIndex = start; + var match; + while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) { ++this$1.curLine; - this$1.lineStart = this$1.pos; + this$1.lineStart = match.index + match[0].length; } - break - case 47: - switch (this$1.input.charCodeAt(this$1.pos + 1)) { - case 42: - this$1.skipBlockComment(); + } + if (this.options.onComment) + { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos, + startLoc, this.curPosition()); } + }; + pp$8.skipLineComment = function(startSkip) { + var this$1 = this; + var start = this.pos; + var startLoc = this.options.onComment && this.curPosition(); + var ch = this.input.charCodeAt(this.pos += startSkip); + while (this.pos < this.input.length && !isNewLine(ch)) { + ch = this$1.input.charCodeAt(++this$1.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } + }; + pp$8.skipSpace = function() { + var this$1 = this; + loop: while (this.pos < this.input.length) { + var ch = this$1.input.charCodeAt(this$1.pos); + switch (ch) { + case 32: case 160: + ++this$1.pos; + break + case 13: + if (this$1.input.charCodeAt(this$1.pos + 1) === 10) { + ++this$1.pos; + } + case 10: case 8232: case 8233: + ++this$1.pos; + if (this$1.options.locations) { + ++this$1.curLine; + this$1.lineStart = this$1.pos; + } break case 47: - this$1.skipLineComment(2); + switch (this$1.input.charCodeAt(this$1.pos + 1)) { + case 42: + this$1.skipBlockComment(); + break + case 47: + this$1.skipLineComment(2); + break + default: + break loop + } break default: - break loop - } - break - default: - if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { - ++this$1.pos; - } else { - break loop + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this$1.pos; + } else { + break loop + } } } - } -}; - - -pp$8.finishToken = function(type, val) { - this.end = this.pos; - if (this.options.locations) { this.endLoc = this.curPosition(); } - var prevType = this.type; - this.type = type; - this.value = val; - - this.updateContext(prevType); -}; - - -pp$8.readToken_dot = function() { - var next = this.input.charCodeAt(this.pos + 1); - if (next >= 48 && next <= 57) { return this.readNumber(true) } - var next2 = this.input.charCodeAt(this.pos + 2); - if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { - this.pos += 3; - return this.finishToken(types.ellipsis) - } else { - ++this.pos; - return this.finishToken(types.dot) - } -}; - -pp$8.readToken_slash = function() { - var next = this.input.charCodeAt(this.pos + 1); - if (this.exprAllowed) { ++this.pos; return this.readRegexp() } - if (next === 61) { return this.finishOp(types.assign, 2) } - return this.finishOp(types.slash, 1) -}; - -pp$8.readToken_mult_modulo_exp = function(code) { - var next = this.input.charCodeAt(this.pos + 1); - var size = 1; - var tokentype = code === 42 ? types.star : types.modulo; - - if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { - ++size; - tokentype = types.starstar; - next = this.input.charCodeAt(this.pos + 2); - } - - if (next === 61) { return this.finishOp(types.assign, size + 1) } - return this.finishOp(tokentype, size) -}; - -pp$8.readToken_pipe_amp = function(code) { - var next = this.input.charCodeAt(this.pos + 1); - if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) } - if (next === 61) { return this.finishOp(types.assign, 2) } - return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1) -}; - -pp$8.readToken_caret = function() { - var next = this.input.charCodeAt(this.pos + 1); - if (next === 61) { return this.finishOp(types.assign, 2) } - return this.finishOp(types.bitwiseXOR, 1) -}; - -pp$8.readToken_plus_min = function(code) { - var next = this.input.charCodeAt(this.pos + 1); - if (next === code) { - if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && - (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { - this.skipLineComment(3); - this.skipSpace(); - return this.nextToken() + }; + pp$8.finishToken = function(type, val) { + this.end = this.pos; + if (this.options.locations) { this.endLoc = this.curPosition(); } + var prevType = this.type; + this.type = type; + this.value = val; + this.updateContext(prevType); + }; + pp$8.readToken_dot = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next >= 48 && next <= 57) { return this.readNumber(true) } + var next2 = this.input.charCodeAt(this.pos + 2); + if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { + this.pos += 3; + return this.finishToken(types.ellipsis) + } else { + ++this.pos; + return this.finishToken(types.dot) } - return this.finishOp(types.incDec, 2) - } - if (next === 61) { return this.finishOp(types.assign, 2) } - return this.finishOp(types.plusMin, 1) -}; - -pp$8.readToken_lt_gt = function(code) { - var next = this.input.charCodeAt(this.pos + 1); - var size = 1; - if (next === code) { - size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; - if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) } - return this.finishOp(types.bitShift, size) - } - if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && - this.input.charCodeAt(this.pos + 3) === 45) { - this.skipLineComment(4); - this.skipSpace(); - return this.nextToken() - } - if (next === 61) { size = 2; } - return this.finishOp(types.relational, size) -}; - -pp$8.readToken_eq_excl = function(code) { - var next = this.input.charCodeAt(this.pos + 1); - if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) } - if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { - this.pos += 2; - return this.finishToken(types.arrow) - } - return this.finishOp(code === 61 ? types.eq : types.prefix, 1) -}; - -pp$8.getTokenFromCode = function(code) { - switch (code) { - case 46: - return this.readToken_dot() - - case 40: ++this.pos; return this.finishToken(types.parenL) - case 41: ++this.pos; return this.finishToken(types.parenR) - case 59: ++this.pos; return this.finishToken(types.semi) - case 44: ++this.pos; return this.finishToken(types.comma) - case 91: ++this.pos; return this.finishToken(types.bracketL) - case 93: ++this.pos; return this.finishToken(types.bracketR) - case 123: ++this.pos; return this.finishToken(types.braceL) - case 125: ++this.pos; return this.finishToken(types.braceR) - case 58: ++this.pos; return this.finishToken(types.colon) - case 63: ++this.pos; return this.finishToken(types.question) - - case 96: - if (this.options.ecmaVersion < 6) { break } - ++this.pos; - return this.finishToken(types.backQuote) - - case 48: + }; + pp$8.readToken_slash = function() { var next = this.input.charCodeAt(this.pos + 1); - if (next === 120 || next === 88) { return this.readRadixNumber(16) } - if (this.options.ecmaVersion >= 6) { - if (next === 111 || next === 79) { return this.readRadixNumber(8) } - if (next === 98 || next === 66) { return this.readRadixNumber(2) } + if (this.exprAllowed) { ++this.pos; return this.readRegexp() } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.slash, 1) + }; + pp$8.readToken_mult_modulo_exp = function(code) { + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + var tokentype = code === 42 ? types.star : types.modulo; + if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) { + ++size; + tokentype = types.starstar; + next = this.input.charCodeAt(this.pos + 2); + } + if (next === 61) { return this.finishOp(types.assign, size + 1) } + return this.finishOp(tokentype, size) + }; + pp$8.readToken_pipe_amp = function(code) { + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1) + }; + pp$8.readToken_caret = function() { + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.bitwiseXOR, 1) + }; + pp$8.readToken_plus_min = function(code) { + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 && + (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) { + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types.incDec, 2) } - - case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: - return this.readNumber(false) - - case 34: case 39: - return this.readString(code) - - - case 47: - return this.readToken_slash() - - case 37: case 42: - return this.readToken_mult_modulo_exp(code) - - case 124: case 38: - return this.readToken_pipe_amp(code) - - case 94: - return this.readToken_caret() - - case 43: case 45: - return this.readToken_plus_min(code) - - case 60: case 62: - return this.readToken_lt_gt(code) - - case 61: case 33: - return this.readToken_eq_excl(code) - - case 126: - return this.finishOp(types.prefix, 1) - } - - this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'"); -}; - -pp$8.finishOp = function(type, size) { - var str = this.input.slice(this.pos, this.pos + size); - this.pos += size; - return this.finishToken(type, str) -}; - -pp$8.readRegexp = function() { - var this$1 = this; - - var escaped, inClass, start = this.pos; - for (;;) { - if (this$1.pos >= this$1.input.length) { this$1.raise(start, "Unterminated regular expression"); } - var ch = this$1.input.charAt(this$1.pos); - if (lineBreak.test(ch)) { this$1.raise(start, "Unterminated regular expression"); } - if (!escaped) { - if (ch === "[") { inClass = true; } - else if (ch === "]" && inClass) { inClass = false; } - else if (ch === "/" && !inClass) { break } - escaped = ch === "\\"; - } else { escaped = false; } - ++this$1.pos; - } - var pattern = this.input.slice(start, this.pos); - ++this.pos; - var flagsStart = this.pos; - var flags = this.readWord1(); - if (this.containsEsc) { this.unexpected(flagsStart); } - - var state = this.regexpState || (this.regexpState = new RegExpValidationState(this)); - state.reset(start, pattern, flags); - this.validateRegExpFlags(state); - this.validateRegExpPattern(state); - - var value = null; - try { - value = new RegExp(pattern, flags); - } catch (e) { - } - - return this.finishToken(types.regexp, {pattern: pattern, flags: flags, value: value}) -}; - - -pp$8.readInt = function(radix, len) { - var this$1 = this; - - var start = this.pos, total = 0; - for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { - var code = this$1.input.charCodeAt(this$1.pos), val = (void 0); - if (code >= 97) { val = code - 97 + 10; } - else if (code >= 65) { val = code - 65 + 10; } - else if (code >= 48 && code <= 57) { val = code - 48; } - else { val = Infinity; } - if (val >= radix) { break } - ++this$1.pos; - total = total * radix + val; - } - if (this.pos === start || len != null && this.pos - start !== len) { return null } - - return total -}; - -pp$8.readRadixNumber = function(radix) { - this.pos += 2; - var val = this.readInt(radix); - if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); } - if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } - return this.finishToken(types.num, val) -}; - - -pp$8.readNumber = function(startsWithDot) { - var start = this.pos; - if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); } - var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48; - if (octal && this.strict) { this.raise(start, "Invalid number"); } - if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; } - var next = this.input.charCodeAt(this.pos); - if (next === 46 && !octal) { - ++this.pos; - this.readInt(10); - next = this.input.charCodeAt(this.pos); - } - if ((next === 69 || next === 101) && !octal) { - next = this.input.charCodeAt(++this.pos); - if (next === 43 || next === 45) { ++this.pos; } - if (this.readInt(10) === null) { this.raise(start, "Invalid number"); } - } - if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } - - var str = this.input.slice(start, this.pos); - var val = octal ? parseInt(str, 8) : parseFloat(str); - return this.finishToken(types.num, val) -}; - - -pp$8.readCodePoint = function() { - var ch = this.input.charCodeAt(this.pos), code; - - if (ch === 123) { - if (this.options.ecmaVersion < 6) { this.unexpected(); } - var codePos = ++this.pos; - code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos); - ++this.pos; - if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); } - } else { - code = this.readHexChar(4); - } - return code -}; - -function codePointToString(code) { - if (code <= 0xFFFF) { return String.fromCharCode(code) } - code -= 0x10000; - return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) -} - -pp$8.readString = function(quote) { - var this$1 = this; - - var out = "", chunkStart = ++this.pos; - for (;;) { - if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated string constant"); } - var ch = this$1.input.charCodeAt(this$1.pos); - if (ch === quote) { break } - if (ch === 92) { - out += this$1.input.slice(chunkStart, this$1.pos); - out += this$1.readEscapedChar(false); - chunkStart = this$1.pos; - } else { - if (isNewLine(ch, this$1.options.ecmaVersion >= 10)) { this$1.raise(this$1.start, "Unterminated string constant"); } - ++this$1.pos; + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.plusMin, 1) + }; + pp$8.readToken_lt_gt = function(code) { + var next = this.input.charCodeAt(this.pos + 1); + var size = 1; + if (next === code) { + size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2; + if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) } + return this.finishOp(types.bitShift, size) + } + if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 && + this.input.charCodeAt(this.pos + 3) === 45) { + this.skipLineComment(4); + this.skipSpace(); + return this.nextToken() } - } - out += this.input.slice(chunkStart, this.pos++); - return this.finishToken(types.string, out) -}; - - -var INVALID_TEMPLATE_ESCAPE_ERROR = {}; - -pp$8.tryReadTemplateToken = function() { - this.inTemplateElement = true; - try { - this.readTmplToken(); - } catch (err) { - if (err === INVALID_TEMPLATE_ESCAPE_ERROR) { - this.readInvalidTemplateToken(); - } else { - throw err + if (next === 61) { size = 2; } + return this.finishOp(types.relational, size) + }; + pp$8.readToken_eq_excl = function(code) { + var next = this.input.charCodeAt(this.pos + 1); + if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) } + if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { + this.pos += 2; + return this.finishToken(types.arrow) } - } - - this.inTemplateElement = false; -}; - -pp$8.invalidStringToken = function(position, message) { - if (this.inTemplateElement && this.options.ecmaVersion >= 9) { - throw INVALID_TEMPLATE_ESCAPE_ERROR - } else { - this.raise(position, message); - } -}; - -pp$8.readTmplToken = function() { - var this$1 = this; - - var out = "", chunkStart = this.pos; - for (;;) { - if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated template"); } - var ch = this$1.input.charCodeAt(this$1.pos); - if (ch === 96 || ch === 36 && this$1.input.charCodeAt(this$1.pos + 1) === 123) { - if (this$1.pos === this$1.start && (this$1.type === types.template || this$1.type === types.invalidTemplate)) { - if (ch === 36) { - this$1.pos += 2; - return this$1.finishToken(types.dollarBraceL) - } else { - ++this$1.pos; - return this$1.finishToken(types.backQuote) - } - } - out += this$1.input.slice(chunkStart, this$1.pos); - return this$1.finishToken(types.template, out) + return this.finishOp(code === 61 ? types.eq : types.prefix, 1) + }; + pp$8.getTokenFromCode = function(code) { + switch (code) { + case 46: + return this.readToken_dot() + case 40: ++this.pos; return this.finishToken(types.parenL) + case 41: ++this.pos; return this.finishToken(types.parenR) + case 59: ++this.pos; return this.finishToken(types.semi) + case 44: ++this.pos; return this.finishToken(types.comma) + case 91: ++this.pos; return this.finishToken(types.bracketL) + case 93: ++this.pos; return this.finishToken(types.bracketR) + case 123: ++this.pos; return this.finishToken(types.braceL) + case 125: ++this.pos; return this.finishToken(types.braceR) + case 58: ++this.pos; return this.finishToken(types.colon) + case 63: ++this.pos; return this.finishToken(types.question) + case 96: + if (this.options.ecmaVersion < 6) { break } + ++this.pos; + return this.finishToken(types.backQuote) + case 48: + var next = this.input.charCodeAt(this.pos + 1); + if (next === 120 || next === 88) { return this.readRadixNumber(16) } + if (this.options.ecmaVersion >= 6) { + if (next === 111 || next === 79) { return this.readRadixNumber(8) } + if (next === 98 || next === 66) { return this.readRadixNumber(2) } + } + case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: + return this.readNumber(false) + case 34: case 39: + return this.readString(code) + case 47: + return this.readToken_slash() + case 37: case 42: + return this.readToken_mult_modulo_exp(code) + case 124: case 38: + return this.readToken_pipe_amp(code) + case 94: + return this.readToken_caret() + case 43: case 45: + return this.readToken_plus_min(code) + case 60: case 62: + return this.readToken_lt_gt(code) + case 61: case 33: + return this.readToken_eq_excl(code) + case 126: + return this.finishOp(types.prefix, 1) + } + this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'"); + }; + pp$8.finishOp = function(type, size) { + var str = this.input.slice(this.pos, this.pos + size); + this.pos += size; + return this.finishToken(type, str) + }; + pp$8.readRegexp = function() { + var this$1 = this; + var escaped, inClass, start = this.pos; + for (;;) { + if (this$1.pos >= this$1.input.length) { this$1.raise(start, "Unterminated regular expression"); } + var ch = this$1.input.charAt(this$1.pos); + if (lineBreak.test(ch)) { this$1.raise(start, "Unterminated regular expression"); } + if (!escaped) { + if (ch === "[") { inClass = true; } + else if (ch === "]" && inClass) { inClass = false; } + else if (ch === "/" && !inClass) { break } + escaped = ch === "\\"; + } else { escaped = false; } + ++this$1.pos; + } + var pattern = this.input.slice(start, this.pos); + ++this.pos; + var flagsStart = this.pos; + var flags = this.readWord1(); + if (this.containsEsc) { this.unexpected(flagsStart); } + var state = this.regexpState || (this.regexpState = new RegExpValidationState(this)); + state.reset(start, pattern, flags); + this.validateRegExpFlags(state); + this.validateRegExpPattern(state); + var value = null; + try { + value = new RegExp(pattern, flags); + } catch (e) { } - if (ch === 92) { - out += this$1.input.slice(chunkStart, this$1.pos); - out += this$1.readEscapedChar(true); - chunkStart = this$1.pos; - } else if (isNewLine(ch)) { - out += this$1.input.slice(chunkStart, this$1.pos); + return this.finishToken(types.regexp, {pattern: pattern, flags: flags, value: value}) + }; + pp$8.readInt = function(radix, len) { + var this$1 = this; + var start = this.pos, total = 0; + for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) { + var code = this$1.input.charCodeAt(this$1.pos), val = (void 0); + if (code >= 97) { val = code - 97 + 10; } + else if (code >= 65) { val = code - 65 + 10; } + else if (code >= 48 && code <= 57) { val = code - 48; } + else { val = Infinity; } + if (val >= radix) { break } ++this$1.pos; - switch (ch) { - case 13: - if (this$1.input.charCodeAt(this$1.pos) === 10) { ++this$1.pos; } - case 10: - out += "\n"; - break - default: - out += String.fromCharCode(ch); - break - } - if (this$1.options.locations) { - ++this$1.curLine; - this$1.lineStart = this$1.pos; - } - chunkStart = this$1.pos; + total = total * radix + val; + } + if (this.pos === start || len != null && this.pos - start !== len) { return null } + return total + }; + pp$8.readRadixNumber = function(radix) { + this.pos += 2; + var val = this.readInt(radix); + if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); } + if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } + return this.finishToken(types.num, val) + }; + pp$8.readNumber = function(startsWithDot) { + var start = this.pos; + if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); } + var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48; + if (octal && this.strict) { this.raise(start, "Invalid number"); } + if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; } + var next = this.input.charCodeAt(this.pos); + if (next === 46 && !octal) { + ++this.pos; + this.readInt(10); + next = this.input.charCodeAt(this.pos); + } + if ((next === 69 || next === 101) && !octal) { + next = this.input.charCodeAt(++this.pos); + if (next === 43 || next === 45) { ++this.pos; } + if (this.readInt(10) === null) { this.raise(start, "Invalid number"); } + } + if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); } + var str = this.input.slice(start, this.pos); + var val = octal ? parseInt(str, 8) : parseFloat(str); + return this.finishToken(types.num, val) + }; + pp$8.readCodePoint = function() { + var ch = this.input.charCodeAt(this.pos), code; + if (ch === 123) { + if (this.options.ecmaVersion < 6) { this.unexpected(); } + var codePos = ++this.pos; + code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos); + ++this.pos; + if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); } } else { - ++this$1.pos; + code = this.readHexChar(4); } + return code + }; + function codePointToString(code) { + if (code <= 0xFFFF) { return String.fromCharCode(code) } + code -= 0x10000; + return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00) } -}; - -pp$8.readInvalidTemplateToken = function() { - var this$1 = this; - - for (; this.pos < this.input.length; this.pos++) { - switch (this$1.input[this$1.pos]) { - case "\\": - ++this$1.pos; - break - - case "$": - if (this$1.input[this$1.pos + 1] !== "{") { - break + pp$8.readString = function(quote) { + var this$1 = this; + var out = "", chunkStart = ++this.pos; + for (;;) { + if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated string constant"); } + var ch = this$1.input.charCodeAt(this$1.pos); + if (ch === quote) { break } + if (ch === 92) { + out += this$1.input.slice(chunkStart, this$1.pos); + out += this$1.readEscapedChar(false); + chunkStart = this$1.pos; + } else { + if (isNewLine(ch, this$1.options.ecmaVersion >= 10)) { this$1.raise(this$1.start, "Unterminated string constant"); } + ++this$1.pos; } - - case "`": - return this$1.finishToken(types.invalidTemplate, this$1.input.slice(this$1.start, this$1.pos)) - } - } - this.raise(this.start, "Unterminated template"); -}; - - -pp$8.readEscapedChar = function(inTemplate) { - var ch = this.input.charCodeAt(++this.pos); - ++this.pos; - switch (ch) { - case 110: return "\n" - case 114: return "\r" - case 120: return String.fromCharCode(this.readHexChar(2)) - case 117: return codePointToString(this.readCodePoint()) - case 116: return "\t" - case 98: return "\b" - case 118: return "\u000b" - case 102: return "\f" - case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } - case 10: - if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; } - return "" - default: - if (ch >= 48 && ch <= 55) { - var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0]; - var octal = parseInt(octalStr, 8); - if (octal > 255) { - octalStr = octalStr.slice(0, -1); - octal = parseInt(octalStr, 8); - } - this.pos += octalStr.length - 1; - ch = this.input.charCodeAt(this.pos); - if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) { - this.invalidStringToken( - this.pos - 1 - octalStr.length, - inTemplate - ? "Octal literal in template string" - : "Octal literal in strict mode" - ); + out += this.input.slice(chunkStart, this.pos++); + return this.finishToken(types.string, out) + }; + var INVALID_TEMPLATE_ESCAPE_ERROR = {}; + pp$8.tryReadTemplateToken = function() { + this.inTemplateElement = true; + try { + this.readTmplToken(); + } catch (err) { + if (err === INVALID_TEMPLATE_ESCAPE_ERROR) { + this.readInvalidTemplateToken(); + } else { + throw err } - return String.fromCharCode(octal) } - return String.fromCharCode(ch) - } -}; - - -pp$8.readHexChar = function(len) { - var codePos = this.pos; - var n = this.readInt(16, len); - if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); } - return n -}; - - -pp$8.readWord1 = function() { - var this$1 = this; - - this.containsEsc = false; - var word = "", first = true, chunkStart = this.pos; - var astral = this.options.ecmaVersion >= 6; - while (this.pos < this.input.length) { - var ch = this$1.fullCharCodeAtPos(); - if (isIdentifierChar(ch, astral)) { - this$1.pos += ch <= 0xffff ? 1 : 2; - } else if (ch === 92) { - this$1.containsEsc = true; - word += this$1.input.slice(chunkStart, this$1.pos); - var escStart = this$1.pos; - if (this$1.input.charCodeAt(++this$1.pos) !== 117) - { this$1.invalidStringToken(this$1.pos, "Expecting Unicode escape sequence \\uXXXX"); } - ++this$1.pos; - var esc = this$1.readCodePoint(); - if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) - { this$1.invalidStringToken(escStart, "Invalid Unicode escape"); } - word += codePointToString(esc); - chunkStart = this$1.pos; + this.inTemplateElement = false; + }; + pp$8.invalidStringToken = function(position, message) { + if (this.inTemplateElement && this.options.ecmaVersion >= 9) { + throw INVALID_TEMPLATE_ESCAPE_ERROR } else { - break + this.raise(position, message); } - first = false; - } - return word + this.input.slice(chunkStart, this.pos) -}; - - -pp$8.readWord = function() { - var word = this.readWord1(); - var type = types.name; - if (this.keywords.test(word)) { - if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword " + word); } - type = keywords$1[word]; - } - return this.finishToken(type, word) -}; - - -var version = "5.7.3"; - - -function parse(input, options) { - return new Parser(options, input).parse() -} - - -function parseExpressionAt(input, pos, options) { - var p = new Parser(options, input, pos); - p.nextToken(); - return p.parseExpression() -} - - -function tokenizer(input, options) { - return new Parser(options, input) -} - -function addLooseExports(parse, Parser$$1, plugins$$1) { - exports.parse_dammit = parse; - exports.LooseParser = Parser$$1; - exports.pluginsLoose = plugins$$1; -} - -exports.version = version; -exports.parse = parse; -exports.parseExpressionAt = parseExpressionAt; -exports.tokenizer = tokenizer; -exports.addLooseExports = addLooseExports; -exports.Parser = Parser; -exports.plugins = plugins; -exports.defaultOptions = defaultOptions; -exports.Position = Position; -exports.SourceLocation = SourceLocation; -exports.getLineInfo = getLineInfo; -exports.Node = Node; -exports.TokenType = TokenType; -exports.tokTypes = types; -exports.keywordTypes = keywords$1; -exports.TokContext = TokContext; -exports.tokContexts = types$1; -exports.isIdentifierChar = isIdentifierChar; -exports.isIdentifierStart = isIdentifierStart; -exports.Token = Token; -exports.isNewLine = isNewLine; -exports.lineBreak = lineBreak; -exports.lineBreakG = lineBreakG; -exports.nonASCIIwhitespace = nonASCIIwhitespace; - -Object.defineProperty(exports, '__esModule', { value: true }); - -}))); - -},{}],2:[function(require,module,exports){ - -},{}],3:[function(require,module,exports){ -function glWiretap(gl, options = {}) { - const { - contextName = 'gl', - throwGetError, - useTrackablePrimitives, - readPixelsFile, - recording = [], - variables = {}, - onReadPixels, - onUnrecognizedArgumentLookup, - } = options; - const proxy = new Proxy(gl, { get: listen }); - const contextVariables = []; - const entityNames = {}; - let imageCount = 0; - let indent = ''; - let readPixelsVariableName; - return proxy; - function listen(obj, property) { - switch (property) { - case 'addComment': return addComment; - case 'checkThrowError': return checkThrowError; - case 'getReadPixelsVariableName': return readPixelsVariableName; - case 'insertVariable': return insertVariable; - case 'reset': return reset; - case 'setIndent': return setIndent; - case 'toString': return toString; - case 'getContextVariableName': return getContextVariableName; - } - if (typeof gl[property] === 'function') { - return function() { - switch (property) { - case 'getError': - if (throwGetError) { - recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`); - } else { - recording.push(`${indent}${contextName}.getError();`); - } - return gl.getError(); - case 'getExtension': { - const variableName = `${contextName}Variables${contextVariables.length}`; - recording.push(`${indent}const ${variableName} = ${contextName}.getExtension('${arguments[0]}');`); - const extension = gl.getExtension(arguments[0]); - if (extension && typeof extension === 'object') { - const tappedExtension = glExtensionWiretap(extension, { - getEntity, - useTrackablePrimitives, - recording, - contextName: variableName, - contextVariables, - variables, - indent, - onUnrecognizedArgumentLookup, - }); - contextVariables.push(tappedExtension); - return tappedExtension; - } else { - contextVariables.push(null); - } - return extension; + }; + pp$8.readTmplToken = function() { + var this$1 = this; + var out = "", chunkStart = this.pos; + for (;;) { + if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated template"); } + var ch = this$1.input.charCodeAt(this$1.pos); + if (ch === 96 || ch === 36 && this$1.input.charCodeAt(this$1.pos + 1) === 123) { + if (this$1.pos === this$1.start && (this$1.type === types.template || this$1.type === types.invalidTemplate)) { + if (ch === 36) { + this$1.pos += 2; + return this$1.finishToken(types.dollarBraceL) + } else { + ++this$1.pos; + return this$1.finishToken(types.backQuote) } - case 'readPixels': - const i = contextVariables.indexOf(arguments[6]); - let targetVariableName; - if (i === -1) { - const variableName = getVariableName(arguments[6]); - if (variableName) { - targetVariableName = variableName; - recording.push(`${indent}${variableName}`); - } else { - targetVariableName = `${contextName}Variable${contextVariables.length}`; - contextVariables.push(arguments[6]); - recording.push(`${indent}const ${targetVariableName} = new ${arguments[6].constructor.name}(${arguments[6].length});`); - } - } else { - targetVariableName = `${contextName}Variable${i}`; - } - readPixelsVariableName = targetVariableName; - const argumentAsStrings = [ - arguments[0], - arguments[1], - arguments[2], - arguments[3], - getEntity(arguments[4]), - getEntity(arguments[5]), - targetVariableName - ]; - recording.push(`${indent}${contextName}.readPixels(${argumentAsStrings.join(', ')});`); - if (readPixelsFile) { - writePPM(arguments[2], arguments[3]); - } - if (onReadPixels) { - onReadPixels(targetVariableName, argumentAsStrings); - } - return gl.readPixels.apply(gl, arguments); - case 'drawBuffers': - recording.push(`${indent}${contextName}.drawBuffers([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup } )}]);`); - return gl.drawBuffers(arguments[0]); - } - let result = gl[property].apply(gl, arguments); - switch (typeof result) { - case 'undefined': - recording.push(`${indent}${methodCallToString(property, arguments)};`); - return; - case 'number': - case 'boolean': - if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) { - recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); - contextVariables.push(result = trackablePrimitive(result)); - break; - } - default: - if (result === null) { - recording.push(`${methodCallToString(property, arguments)};`); - } else { - recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); - } - - contextVariables.push(result); } - return result; + out += this$1.input.slice(chunkStart, this$1.pos); + return this$1.finishToken(types.template, out) } - } - entityNames[gl[property]] = property; - return gl[property]; - } - function toString() { - return recording.join('\n'); - } - function reset() { - while (recording.length > 0) { - recording.pop(); - } - } - function insertVariable(name, value) { - variables[name] = value; - } - function getEntity(value) { - const name = entityNames[value]; - if (name) { - return contextName + '.' + name; - } - return value; - } - function setIndent(spaces) { - indent = ' '.repeat(spaces); - } - function addVariable(value, source) { - const variableName = `${contextName}Variable${contextVariables.length}`; - recording.push(`${indent}const ${variableName} = ${source};`); - contextVariables.push(value); - return variableName; - } - function writePPM(width, height) { - const sourceVariable = `${contextName}Variable${contextVariables.length}`; - const imageVariable = `imageDatum${imageCount}`; - recording.push(`${indent}let ${imageVariable} = ["P3\\n# ${readPixelsFile}.ppm\\n", ${width}, ' ', ${height}, "\\n255\\n"].join("");`); - recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`); - recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`); - recording.push(`${indent}}`); - recording.push(`${indent}if (typeof require !== "undefined") {`); - recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`); - recording.push(`${indent}}`); - imageCount++; - } - function addComment(value) { - recording.push(`${indent}// ${value}`); - } - function checkThrowError() { - recording.push(`${indent}(() => { -${indent}const error = ${contextName}.getError(); -${indent}if (error !== ${contextName}.NONE) { -${indent} const names = Object.getOwnPropertyNames(gl); -${indent} for (let i = 0; i < names.length; i++) { -${indent} const name = names[i]; -${indent} if (${contextName}[name] === error) { -${indent} throw new Error('${contextName} threw ' + name); -${indent} } -${indent} } -${indent}} -${indent}})();`); - } - function methodCallToString(method, args) { - return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; - } - - function getVariableName(value) { - if (variables) { - for (const name in variables) { - if (variables[name] === value) { - return name; + if (ch === 92) { + out += this$1.input.slice(chunkStart, this$1.pos); + out += this$1.readEscapedChar(true); + chunkStart = this$1.pos; + } else if (isNewLine(ch)) { + out += this$1.input.slice(chunkStart, this$1.pos); + ++this$1.pos; + switch (ch) { + case 13: + if (this$1.input.charCodeAt(this$1.pos) === 10) { ++this$1.pos; } + case 10: + out += "\n"; + break + default: + out += String.fromCharCode(ch); + break + } + if (this$1.options.locations) { + ++this$1.curLine; + this$1.lineStart = this$1.pos; } + chunkStart = this$1.pos; + } else { + ++this$1.pos; } } - return null; - } - - function getContextVariableName(value) { - const i = contextVariables.indexOf(value); - if (i !== -1) { - return `${contextName}Variable${i}`; + }; + pp$8.readInvalidTemplateToken = function() { + var this$1 = this; + for (; this.pos < this.input.length; this.pos++) { + switch (this$1.input[this$1.pos]) { + case "\\": + ++this$1.pos; + break + case "$": + if (this$1.input[this$1.pos + 1] !== "{") { + break + } + case "`": + return this$1.finishToken(types.invalidTemplate, this$1.input.slice(this$1.start, this$1.pos)) + } } - return null; - } -} - -function glExtensionWiretap(extension, options) { - const proxy = new Proxy(extension, { get: listen }); - const extensionEntityNames = {}; - const { - contextName, - contextVariables, - getEntity, - useTrackablePrimitives, - recording, - variables, - indent, - onUnrecognizedArgumentLookup, - } = options; - return proxy; - function listen(obj, property) { - if (typeof obj[property] === 'function') { - return function() { - switch (property) { - case 'drawBuffersWEBGL': - recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`); - return extension.drawBuffersWEBGL(arguments[0]); - } - let result = extension[property].apply(extension, arguments); - switch (typeof result) { - case 'undefined': - recording.push(`${indent}${methodCallToString(property, arguments)};`); - return; - case 'number': - case 'boolean': - if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) { - recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); - contextVariables.push(result = trackablePrimitive(result)); - } else { - recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); - contextVariables.push(result); - } - break; - default: - if (result === null) { - recording.push(`${methodCallToString(property, arguments)};`); - } else { - recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); - } - contextVariables.push(result); + this.raise(this.start, "Unterminated template"); + }; + pp$8.readEscapedChar = function(inTemplate) { + var ch = this.input.charCodeAt(++this.pos); + ++this.pos; + switch (ch) { + case 110: return "\n" + case 114: return "\r" + case 120: return String.fromCharCode(this.readHexChar(2)) + case 117: return codePointToString(this.readCodePoint()) + case 116: return "\t" + case 98: return "\b" + case 118: return "\u000b" + case 102: return "\f" + case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } + case 10: + if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; } + return "" + default: + if (ch >= 48 && ch <= 55) { + var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0]; + var octal = parseInt(octalStr, 8); + if (octal > 255) { + octalStr = octalStr.slice(0, -1); + octal = parseInt(octalStr, 8); + } + this.pos += octalStr.length - 1; + ch = this.input.charCodeAt(this.pos); + if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) { + this.invalidStringToken( + this.pos - 1 - octalStr.length, + inTemplate + ? "Octal literal in template string" + : "Octal literal in strict mode" + ); } - return result; - }; + return String.fromCharCode(octal) + } + return String.fromCharCode(ch) } - extensionEntityNames[extension[property]] = property; - return extension[property]; - } - - function getExtensionEntity(value) { - if (extensionEntityNames.hasOwnProperty(value)) { - return `${contextName}.${extensionEntityNames[value]}`; + }; + pp$8.readHexChar = function(len) { + var codePos = this.pos; + var n = this.readInt(16, len); + if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); } + return n + }; + pp$8.readWord1 = function() { + var this$1 = this; + this.containsEsc = false; + var word = "", first = true, chunkStart = this.pos; + var astral = this.options.ecmaVersion >= 6; + while (this.pos < this.input.length) { + var ch = this$1.fullCharCodeAtPos(); + if (isIdentifierChar(ch, astral)) { + this$1.pos += ch <= 0xffff ? 1 : 2; + } else if (ch === 92) { + this$1.containsEsc = true; + word += this$1.input.slice(chunkStart, this$1.pos); + var escStart = this$1.pos; + if (this$1.input.charCodeAt(++this$1.pos) !== 117) + { this$1.invalidStringToken(this$1.pos, "Expecting Unicode escape sequence \\uXXXX"); } + ++this$1.pos; + var esc = this$1.readCodePoint(); + if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) + { this$1.invalidStringToken(escStart, "Invalid Unicode escape"); } + word += codePointToString(esc); + chunkStart = this$1.pos; + } else { + break + } + first = false; } - return getEntity(value); - } - - function methodCallToString(method, args) { - return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; - } - - function addVariable(value, source) { - const variableName = `${contextName}Variable${contextVariables.length}`; - contextVariables.push(value); - recording.push(`${indent}const ${variableName} = ${source};`); - return variableName; + return word + this.input.slice(chunkStart, this.pos) + }; + pp$8.readWord = function() { + var word = this.readWord1(); + var type = types.name; + if (this.keywords.test(word)) { + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword " + word); } + type = keywords$1[word]; + } + return this.finishToken(type, word) + }; + function parse(input, options) { + return new Parser(options, input).parse() } -} -function argumentsToString(args, options) { - const { variables, onUnrecognizedArgumentLookup } = options; - return (Array.from(args).map((arg) => { - const variableName = getVariableName(arg); - if (variableName) { - return variableName; + class Texture { + constructor(settings) { + const { + texture, + size, + dimensions, + output, + context, + type = 'NumberTexture', + } = settings; + if (!output) throw new Error('settings property "output" required.'); + if (!context) throw new Error('settings property "context" required.'); + this.texture = texture; + this.size = size; + this.dimensions = dimensions; + this.output = output; + this.context = context; + this.kernel = null; + this.type = type; } - return argumentToString(arg, options); - }).join(', ')); - - function getVariableName(value) { - if (variables) { - for (const name in variables) { - if (!variables.hasOwnProperty(name)) continue; - if (variables[name] === value) { - return name; - } - } + toArray() { + throw new Error(`Not implemented on ${this.constructor.name}`); } - if (onUnrecognizedArgumentLookup) { - return onUnrecognizedArgumentLookup(value); + delete() { + return this.context.deleteTexture(this.texture); } - return null; } -} -function argumentToString(arg, options) { - const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options; - if (typeof arg === 'undefined') { - return 'undefined'; - } - if (arg === null) { - return 'null'; - } - const i = contextVariables.indexOf(arg); - if (i > -1) { - return `${contextName}Variable${i}`; - } - switch (arg.constructor.name) { - case 'String': - const hasLines = /\n/.test(arg); - const hasSingleQuotes = /'/.test(arg); - const hasDoubleQuotes = /"/.test(arg); - if (hasLines) { - return '`' + arg + '`'; - } else if (hasSingleQuotes && !hasDoubleQuotes) { - return '"' + arg + '"'; - } else if (!hasSingleQuotes && hasDoubleQuotes) { - return "'" + arg + "'"; - } else { - return '\'' + arg + '\''; - } - case 'Number': return getEntity(arg); - case 'Boolean': return getEntity(arg); - case 'Array': - return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`); - case 'Float32Array': - case 'Uint8Array': - case 'Uint16Array': - case 'Int32Array': - return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`); - default: - if (onUnrecognizedArgumentLookup) { - const instantiationString = onUnrecognizedArgumentLookup(arg); - if (instantiationString) { - return instantiationString; - } + function getSystemEndianness() { + const b = new ArrayBuffer(4); + const a = new Uint32Array(b); + const c = new Uint8Array(b); + a[0] = 0xdeadbeef; + if (c[0] === 0xef) return 'LE'; + if (c[0] === 0xde) return 'BE'; + throw new Error('unknown endianness'); + }const _systemEndianness = getSystemEndianness(); + function systemEndianness() { + return _systemEndianness; + }function getVariableType(value, strictIntegers) { + if (isArray(value)) { + if (value[0].nodeName === 'IMG') { + return 'HTMLImageArray'; } - throw new Error(`unrecognized argument type ${arg.constructor.name}`); - } -} - -function trackablePrimitive(value) { - return new value.constructor(value); -} - -if (typeof module !== 'undefined') { - module.exports = { glWiretap, glExtensionWiretap }; -} - -if (typeof window !== 'undefined') { - glWiretap.glExtensionWiretap = glExtensionWiretap; - window.glWiretap = glWiretap; -} - -},{}],4:[function(require,module,exports){ -function setupArguments(args) { - const newArguments = new Array(args.length); - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - if (arg.toArray) { - newArguments[i] = arg.toArray(); - } else { - newArguments[i] = arg; + return 'Array'; } - } - return newArguments; -} - -function mock1D() { - const args = setupArguments(arguments); - const row = new Float32Array(this.output.x); - for (let x = 0; x < this.output.x; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - row[x] = this._fn.apply(this, args); - } - return row; -} - -function mock2D() { - const args = setupArguments(arguments); - const matrix = new Array(this.output.y); - for (let y = 0; y < this.output.y; y++) { - const row = new Float32Array(this.output.x); - for (let x = 0; x < this.output.x; x++) { - this.thread.x = x; - this.thread.y = y; - this.thread.z = 0; - row[x] = this._fn.apply(this, args); + switch (value.constructor) { + case Boolean: + return 'Boolean'; + case Number: + return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float'; + case Texture: + return value.type; + case Input: + return 'Input'; } - matrix[y] = row; - } - return matrix; -} - -function mock2DGraphical() { - const args = setupArguments(arguments); - for (let y = 0; y < this.output.y; y++) { - for (let x = 0; x < this.output.x; x++) { - this.thread.x = x; - this.thread.y = y; - this.thread.z = 0; - this._fn.apply(this, args); + switch (value.nodeName) { + case 'IMG': + return 'HTMLImage'; + case 'VIDEO': + return 'HTMLVideo'; } - } -} - -function mock3D() { - const args = setupArguments(arguments); - const cube = new Array(this.output.z); - for (let z = 0; z < this.output.z; z++) { - const matrix = new Array(this.output.y); - for (let y = 0; y < this.output.y; y++) { - const row = new Float32Array(this.output.x); - for (let x = 0; x < this.output.x; x++) { - this.thread.x = x; - this.thread.y = y; - this.thread.z = z; - row[x] = this._fn.apply(this, args); + return value.hasOwnProperty('type') ? value.type : 'Unknown'; + }const utils$1 = { + systemEndianness, + getSystemEndianness, + isFunction, + isFunctionString, + getFunctionNameFromString, + getFunctionBodyFromString(funcStr) { + return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); + }, + getArgumentNamesFromString, + clone(obj) { + if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj; + const temp = obj.constructor(); + for (let key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + obj.isActiveClone = null; + temp[key] = utils$1.clone(obj[key]); + delete obj.isActiveClone; + } + } + return temp; + }, + isArray, + getVariableType, + getKernelTextureSize(settings, dimensions) { + let [w, h, d] = dimensions; + let texelCount = (w || 1) * (h || 1) * (d || 1); + if (settings.optimizeFloatMemory && settings.precision === 'single') { + w = texelCount = Math.ceil(texelCount / 4); + } + if (h > 1 && w * h === texelCount) { + return new Int32Array([w, h]); + } + return utils$1.closestSquareDimensions(texelCount); + }, + closestSquareDimensions(length) { + const sqrt = Math.sqrt(length); + let high = Math.ceil(sqrt); + let low = Math.floor(sqrt); + while (high * low < length) { + high--; + low = Math.ceil(length / high); + } + return new Int32Array([low, Math.ceil(length / low)]); + }, + getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) { + const totalArea = utils$1.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4); + const texelCount = totalArea / bitRatio; + return utils$1.closestSquareDimensions(texelCount); + }, + getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) { + const [w, h, d] = dimensions; + const totalArea = utils$1.roundTo((w || 1) * (h || 1) * (d || 1), 4); + const texelCount = totalArea / (4 / bitRatio); + return utils$1.closestSquareDimensions(texelCount); + }, + roundTo(n, d) { + return Math.floor((n + d - 1) / d) * d; + }, + getDimensions(x, pad) { + let ret; + if (isArray(x)) { + const dim = []; + let temp = x; + while (isArray(temp)) { + dim.push(temp.length); + temp = temp[0]; + } + ret = dim.reverse(); + } else if (x instanceof Texture) { + ret = x.output; + } else if (x instanceof Input) { + ret = x.size; + } else { + throw new Error(`Unknown dimensions of ${x}`); } - matrix[y] = row; - } - cube[z] = matrix; - } - return cube; -} - -function apiDecorate(kernel) { - kernel.setOutput = (output) => { - kernel.output = setupOutput(output); - if (kernel.graphical) { - setupGraphical(kernel); - } - }; - kernel.toJSON = () => { - throw new Error('Not usable with gpuMock'); - }; - kernel.setConstants = (flag) => { - kernel.constants = flag; - return kernel; - }; - kernel.setGraphical = (flag) => { - kernel.graphical = flag; - return kernel; - }; - kernel.setCanvas = (flag) => { - kernel.canvas = flag; - return kernel; - }; - kernel.setContext = (flag) => { - kernel.context = flag; - return kernel; - }; - kernel.exec = function() { - return new Promise((resolve, reject) => { - try { - resolve(kernel.apply(kernel, arguments)); - } catch(e) { - reject(e); + if (pad) { + ret = Array.from(ret); + while (ret.length < 3) { + ret.push(1); + } } - }); - }; - kernel.getPixels = (flip) => { - const {x, y} = kernel.output; - return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0); - }; - kernel.color = function(r, g, b, a) { - if (typeof a === 'undefined') { - a = 1; - } - - r = Math.floor(r * 255); - g = Math.floor(g * 255); - b = Math.floor(b * 255); - a = Math.floor(a * 255); - - const width = kernel.output.x; - const height = kernel.output.y; - - const x = kernel.thread.x; - const y = height - kernel.thread.y - 1; - - const index = x + y * width; - - kernel._colorData[index * 4 + 0] = r; - kernel._colorData[index * 4 + 1] = g; - kernel._colorData[index * 4 + 2] = b; - kernel._colorData[index * 4 + 3] = a; - }; - - kernel.setWarnVarUsage = () => { - return kernel; - }; - kernel.setOptimizeFloatMemory = () => { - return kernel; - }; - kernel.setArgumentTypes = () => { - return kernel; - }; - kernel.setDebug = () => { - return kernel; - }; - kernel.setLoopMaxIterations = () => { - return kernel; - }; - kernel.setPipeline = () => { - return kernel; - }; - kernel.setPrecision = () => { - return kernel; - }; - kernel.setImmutable = () => { - return kernel; - }; - kernel.setFunctions = () => { - return kernel; - }; - kernel.addSubKernel = () => { - return kernel; - }; - kernel.destroy = () => {}; - kernel.validateSettings = () => {}; - if (kernel.graphical && kernel.output) { - setupGraphical(kernel); - } - return kernel; -} - -function setupGraphical(kernel) { - const {x, y} = kernel.output; - if (kernel.context && kernel.context.createImageData) { - const data = new Uint8ClampedArray(x * y * 4); - kernel._imageData = kernel.context.createImageData(x, y); - kernel._colorData = data; - } else { - const data = new Uint8ClampedArray(x * y * 4); - kernel._imageData = { data }; - kernel._colorData = data; - } -} - -function setupOutput(output) { - let result = null; - if (output.length) { - if (output.length === 3) { - const [x,y,z] = output; - result = { x, y, z }; - } else if (output.length === 2) { - const [x,y] = output; - result = { x, y }; - } else { - const [x] = output; - result = { x }; - } - } else { - result = output; - } - return result; -} - -function gpuMock(fn, settings = {}) { - const output = settings.output ? setupOutput(settings.output) : null; - function kernel() { - if (kernel.output.z) { - return mock3D.apply(kernel, arguments); - } else if (kernel.output.y) { - if (kernel.graphical) { - return mock2DGraphical.apply(kernel, arguments); + return new Int32Array(ret); + }, + flatten2dArrayTo(array, target) { + let offset = 0; + for (let y = 0; y < array.length; y++) { + target.set(array[y], offset); + offset += array[y].length; } - return mock2D.apply(kernel, arguments); - } else { - return mock1D.apply(kernel, arguments); - } - } - kernel._fn = fn; - kernel.constants = settings.constants || null; - kernel.context = settings.context || null; - kernel.canvas = settings.canvas || null; - kernel.graphical = settings.graphical || false; - kernel._imageData = null; - kernel._colorData = null; - kernel.output = output; - kernel.thread = { - x: 0, - y: 0, - z: 0 - }; - return apiDecorate(kernel); -} - -function flipPixels(pixels, width, height) { - const halfHeight = height / 2 | 0; - const bytesPerRow = width * 4; - const temp = new Uint8ClampedArray(width * 4); - const result = pixels.slice(0); - for (let y = 0; y < halfHeight; ++y) { - const topOffset = y * bytesPerRow; - const bottomOffset = (height - y - 1) * bytesPerRow; - - temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); - - result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); - - result.set(temp, bottomOffset); - } - return result; -} - -module.exports = { - gpuMock -}; - -},{}],5:[function(require,module,exports){ -const { utils } = require('./utils'); - -function alias(name, source) { - const fnString = source.toString(); - return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) { - ${ utils.getFunctionBodyFromString(fnString) } -}`)(); -} - -module.exports = { - alias -}; -},{"./utils":112}],6:[function(require,module,exports){ -const { FunctionNode } = require('../function-node'); - -class CPUFunctionNode extends FunctionNode { - astFunction(ast, retArr) { - - if (!this.isRootKernel) { - retArr.push('function'); - retArr.push(' '); - retArr.push(this.name); - retArr.push('('); - - for (let i = 0; i < this.argumentNames.length; ++i) { - const argumentName = this.argumentNames[i]; - - if (i > 0) { - retArr.push(', '); + }, + flatten3dArrayTo(array, target) { + let offset = 0; + for (let z = 0; z < array.length; z++) { + for (let y = 0; y < array[z].length; y++) { + target.set(array[z][y], offset); + offset += array[z][y].length; } - retArr.push('user_'); - retArr.push(argumentName); } - - retArr.push(') {\n'); - } - - for (let i = 0; i < ast.body.body.length; ++i) { - this.astGeneric(ast.body.body[i], retArr); - retArr.push('\n'); - } - - if (!this.isRootKernel) { - retArr.push('}\n'); - } - return retArr; - } - - astReturnStatement(ast, retArr) { - const type = this.returnType || this.getType(ast.argument); - - if (!this.returnType) { - this.returnType = type; - } - - if (this.isRootKernel) { - retArr.push(this.leadingReturnStatement); - this.astGeneric(ast.argument, retArr); - retArr.push(';\n'); - retArr.push(this.followingReturnStatement); - retArr.push('continue;\n'); - } else if (this.isSubKernel) { - retArr.push(`subKernelResult_${ this.name } = `); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - retArr.push(`return subKernelResult_${ this.name };`); - } else { - retArr.push('return '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - } - return retArr; - } - - astLiteral(ast, retArr) { - - if (isNaN(ast.value)) { - throw this.astErrorOutput( - 'Non-numeric literal not supported : ' + ast.value, - ast - ); - } - - retArr.push(ast.value); - - return retArr; - } - - astBinaryExpression(ast, retArr) { - retArr.push('('); - this.astGeneric(ast.left, retArr); - retArr.push(ast.operator); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - return retArr; - } - - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput( - 'IdentifierExpression - not an Identifier', - idtNode - ); - } - - switch (idtNode.name) { - case 'Infinity': - retArr.push('Infinity'); - break; - default: - if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { - retArr.push('constants_' + idtNode.name); - } else { - retArr.push('user_' + idtNode.name); - } - } - - return retArr; - } - - astForStatement(forNode, retArr) { - if (forNode.type !== 'ForStatement') { - throw this.astErrorOutput('Invalid for statement', forNode); - } - - const initArr = []; - const testArr = []; - const updateArr = []; - const bodyArr = []; - let isSafe = null; - - if (forNode.init) { - this.pushState('in-for-loop-init'); - this.astGeneric(forNode.init, initArr); - for (let i = 0; i < initArr.length; i++) { - if (initArr[i].includes && initArr[i].includes(',')) { - isSafe = false; + }, + flatten4dArrayTo(array, target) { + let offset = 0; + for (let l = 0; l < array.length; l++) { + for (let z = 0; z < array[l].length; z++) { + for (let y = 0; y < array[l][z].length; y++) { + target.set(array[l][z][y], offset); + offset += array[l][z][y].length; + } } } - this.popState('in-for-loop-init'); - } else { - isSafe = false; - } - - if (forNode.test) { - this.astGeneric(forNode.test, testArr); - } else { - isSafe = false; - } - - if (forNode.update) { - this.astGeneric(forNode.update, updateArr); - } else { - isSafe = false; - } - - if (forNode.body) { - this.pushState('loop-body'); - this.astGeneric(forNode.body, bodyArr); - this.popState('loop-body'); - } - - if (isSafe === null) { - isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); - } - - if (isSafe) { - retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); - retArr.push(bodyArr.join('')); - retArr.push('}\n'); - } else { - const iVariableName = this.getInternalVariableName('safeI'); - if (initArr.length > 0) { - retArr.push(initArr.join(''), ';\n'); + }, + flattenTo(array, target) { + if (isArray(array[0])) { + if (isArray(array[0][0])) { + if (isArray(array[0][0][0])) { + utils$1.flatten4dArrayTo(array, target); + } else { + utils$1.flatten3dArrayTo(array, target); + } + } else { + utils$1.flatten2dArrayTo(array, target); + } + } else { + target.set(array); } - retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) { - retArr.push(`if (!${testArr.join('')}) break;\n`); + }, + splitArray(array, part) { + const result = []; + for (let i = 0; i < array.length; i += part) { + result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part)); } - retArr.push(bodyArr.join('')); - retArr.push(`\n${updateArr.join('')};`); - retArr.push('}\n'); - } - return retArr; - } - - astWhileStatement(whileNode, retArr) { - if (whileNode.type !== 'WhileStatement') { - throw this.astErrorOutput( - 'Invalid while statement', - whileNode - ); - } - - retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); - retArr.push('if ('); - this.astGeneric(whileNode.test, retArr); - retArr.push(') {\n'); - this.astGeneric(whileNode.body, retArr); - retArr.push('} else {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - } - - astDoWhileStatement(doWhileNode, retArr) { - if (doWhileNode.type !== 'DoWhileStatement') { - throw this.astErrorOutput( - 'Invalid while statement', - doWhileNode - ); - } - - retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); - this.astGeneric(doWhileNode.body, retArr); - retArr.push('if (!'); - this.astGeneric(doWhileNode.test, retArr); - retArr.push(') {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - - } - - astAssignmentExpression(assNode, retArr) { - const declaration = this.getDeclaration(assNode.left); - if (declaration && !declaration.assignable) { - throw this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode); - } - this.astGeneric(assNode.left, retArr); - retArr.push(assNode.operator); - this.astGeneric(assNode.right, retArr); - return retArr; - } - - astBlockStatement(bNode, retArr) { - if (this.isState('loop-body')) { - this.pushState('block-body'); - for (let i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); + return result; + }, + getAstString, + allPropertiesOf(obj) { + const props = []; + do { + props.push.apply(props, Object.getOwnPropertyNames(obj)); + } while (obj = Object.getPrototypeOf(obj)); + return props; + }, + linesToString(lines) { + if (lines.length > 0) { + return lines.join(';\n') + ';\n'; + } else { + return '\n'; } - this.popState('block-body'); - } else { - retArr.push('{\n'); - for (let i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); + }, + warnDeprecated, + functionToIFunction, + flipPixels(pixels, width, height) { + const halfHeight = height / 2 | 0; + const bytesPerRow = width * 4; + const temp = new Uint8ClampedArray(width * 4); + const result = pixels.slice(0); + for (let y = 0; y < halfHeight; ++y) { + const topOffset = y * bytesPerRow; + const bottomOffset = (height - y - 1) * bytesPerRow; + temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); + result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); + result.set(temp, bottomOffset); } - retArr.push('}\n'); - } - return retArr; - } - - astVariableDeclaration(varDecNode, retArr) { - if (varDecNode.kind === 'var' && this.warnVarUsage) { - this.varWarn(); - } - retArr.push(`${varDecNode.kind} `); - const { declarations } = varDecNode; - for (let i = 0; i < declarations.length; i++) { - if (i > 0) { - retArr.push(','); + return result; + }, + erectPackedFloat: (array, width) => { + return array.subarray(0, width); + }, + erect2DPackedFloat: (array, width, height) => { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xStart = y * width; + const xEnd = xStart + width; + yResults[y] = array.subarray(xStart, xEnd); } - this.astGeneric(declarations[i], retArr); - } - if (!this.isState('in-for-loop-init')) { - retArr.push(';'); - } - return retArr; - } - - astIfStatement(ifNode, retArr) { - retArr.push('if ('); - this.astGeneric(ifNode.test, retArr); - retArr.push(')'); - if (ifNode.consequent.type === 'BlockStatement') { - this.astGeneric(ifNode.consequent, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.consequent, retArr); - retArr.push('\n}\n'); - } - - if (ifNode.alternate) { - retArr.push('else '); - if (ifNode.alternate.type === 'BlockStatement') { - this.astGeneric(ifNode.alternate, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.alternate, retArr); - retArr.push('\n}\n'); + return yResults; + }, + erect3DPackedFloat: (array, width, height, depth) => { + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xStart = (z * height * width) + y * width; + const xEnd = xStart + width; + yResults[y] = array.subarray(xStart, xEnd); + } + zResults[z] = yResults; + } + return zResults; + }, + erectMemoryOptimizedFloat: (array, width) => { + return array.subarray(0, width); + }, + erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat, + erectFloat: (array, width) => { + const xResults = new Float32Array(width); + let i = 0; + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; } - } - return retArr; - - } - - astSwitchStatement(ast, retArr) { - const { discriminant, cases } = ast; - retArr.push('switch ('); - this.astGeneric(discriminant, retArr); - retArr.push(') {\n'); - for (let i = 0; i < cases.length; i++) { - if (cases[i].test === null) { - retArr.push('default:\n'); - this.astGeneric(cases[i].consequent, retArr); - if (cases[i].consequent && cases[i].consequent.length > 0) { - retArr.push('break;\n'); + return xResults; + }, + erect2DFloat: (array, width, height) => { + const yResults = new Array(height); + let i = 0; + for (let y = 0; y < height; y++) { + const xResults = new Float32Array(width); + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; } - continue; + yResults[y] = xResults; } - retArr.push('case '); - this.astGeneric(cases[i].test, retArr); - retArr.push(':\n'); - if (cases[i].consequent && cases[i].consequent.length > 0) { - this.astGeneric(cases[i].consequent, retArr); - retArr.push('break;\n'); + return yResults; + }, + erect3DFloat: (array, width, height, depth) => { + const zResults = new Array(depth); + let i = 0; + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Float32Array(width); + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; + } + yResults[y] = xResults; + } + zResults[z] = yResults; } - } - retArr.push('\n}'); - } - - astThisExpression(tNode, retArr) { - retArr.push('_this'); - return retArr; - } + return zResults; + }, + erectArray2: (array, width) => { + const xResults = new Array(width); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 2); + } + return xResults; + }, + erect2DArray2: (array, width, height) => { + const yResults = new Array(height); + const XResultsMax = width * 4; + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * XResultsMax; + let i = 0; + for (let x = 0; x < XResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 2); + } + yResults[y] = xResults; + } + return yResults; + }, + erect3DArray2: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 2); + } + yResults[y] = xResults; + } + zResults[z] = yResults; + } + return zResults; + }, + erectArray3: (array, width) => { + const xResults = new Array(width); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 3); + } + return xResults; + }, + erect2DArray3: (array, width, height) => { + const xResultsMax = width * 4; + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * xResultsMax; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 3); + } + yResults[y] = xResults; + } + return yResults; + }, + erect3DArray3: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 3); + } + yResults[y] = xResults; + } + zResults[z] = yResults; + } + return zResults; + }, + erectArray4: (array, width) => { + const xResults = new Array(array); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 4); + } + return xResults; + }, + erect2DArray4: (array, width, height) => { + const xResultsMax = width * 4; + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * xResultsMax; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 4); + } + yResults[y] = xResults; + } + return yResults; + }, + erect3DArray4: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 4); + } + yResults[y] = xResults; + } + zResults[z] = yResults; + } + return zResults; + }, + flattenFunctionToString: (source, settings) => { + const { findDependency, thisLookup, doNotDefine } = settings; + let flattened = settings.flattened; + if (!flattened) { + flattened = settings.flattened = {}; + } + const ast = parse(source); + const functionDependencies = []; + function flatten(ast) { + if (Array.isArray(ast)) { + const results = []; + for (let i = 0; i < ast.length; i++) { + results.push(flatten(ast[i])); + } + return results.join(''); + } + switch (ast.type) { + case 'Program': + return flatten(ast.body); + case 'FunctionDeclaration': + return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; + case 'BlockStatement': { + const result = []; + for (let i = 0; i < ast.body.length; i++) { + result.push(flatten(ast.body[i]), ';\n'); + } + return `{\n${result.join('')}}`; + } + case 'VariableDeclaration': + switch (ast.declarations[0].id.type) { + case 'ObjectPattern': { + const source = flatten(ast.declarations[0].init); + const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; + if (/this/.test(source)) { + const result = []; + const lookups = properties.map(thisLookup); + for (let i = 0; i < lookups.length; i++) { + const lookup = lookups[i]; + if (lookup === null) continue; + const property = properties[i]; + result.push(`${ast.kind} ${ property } = ${ lookup };\n`); + } + return result.join(''); + } + return `${ast.kind} { ${properties} } = ${source}`; + } + case 'ArrayPattern': + return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; + } + if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { + return ''; + } + return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`; + case 'CallExpression': { + if (ast.callee.property.name === 'subarray') { + return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') { + return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + if (ast.callee.object.type === 'ThisExpression') { + functionDependencies.push(findDependency('this', ast.callee.property.name)); + return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else if (ast.callee.object.name) { + const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name); + if (foundSource === null) { + return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else { + functionDependencies.push(foundSource); + return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + } else if (ast.callee.object.type === 'MemberExpression') { + return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else { + throw new Error('unknown ast.callee'); + } + } + case 'ReturnStatement': + return `return ${flatten(ast.argument)}`; + case 'BinaryExpression': + return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`; + case 'UnaryExpression': + if (ast.prefix) { + return `${ast.operator} ${flatten(ast.argument)}`; + } else { + return `${flatten(ast.argument)} ${ast.operator}`; + } + case 'ExpressionStatement': + return `(${flatten(ast.expression)})`; + case 'ArrowFunctionExpression': + return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`; + case 'Literal': + return ast.raw; + case 'Identifier': + return ast.name; + case 'MemberExpression': + if (ast.object.type === 'ThisExpression') { + return thisLookup(ast.property.name); + } + if (ast.computed) { + return `${flatten(ast.object)}[${flatten(ast.property)}]`; + } + return flatten(ast.object) + '.' + flatten(ast.property); + case 'ThisExpression': + return 'this'; + case 'NewExpression': + return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + case 'ForStatement': + return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`; + case 'AssignmentExpression': + return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`; + case 'UpdateExpression': + return `${flatten(ast.argument)}${ast.operator}`; + case 'IfStatement': + return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`; + case 'ThrowStatement': + return `throw ${flatten(ast.argument)}`; + case 'ObjectPattern': + return ast.properties.map(flatten).join(', '); + case 'ArrayPattern': + return ast.elements.map(flatten).join(', '); + case 'DebuggerStatement': + return 'debugger;'; + case 'ConditionalExpression': + return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`; + case 'Property': + if (ast.kind === 'init') { + return flatten(ast.key); + } + } + throw new Error(`unhandled ast.type of ${ ast.type }`); + } + const result = flatten(ast); + if (functionDependencies.length > 0) { + const flattenedFunctionDependencies = []; + for (let i = 0; i < functionDependencies.length; i++) { + const functionDependency = functionDependencies[i]; + if (!flattened[functionDependency]) { + flattened[functionDependency] = true; + } + flattenedFunctionDependencies.push(utils$1.flattenFunctionToString(functionDependency, settings) + ';\n'); + } + return flattenedFunctionDependencies.join('') + result; + } + return result; + }, + }; - astMemberExpression(mNode, retArr) { - const { - signature, - type, - property, - xProperty, - yProperty, - zProperty, - name, - origin - } = this.getMemberExpressionDetails(mNode); - switch (signature) { - case 'this.thread.value': - retArr.push(`_this.thread.${ name }`); - return retArr; - case 'this.output.value': - switch (name) { - case 'x': - retArr.push('outputX'); - break; - case 'y': - retArr.push('outputY'); + class Kernel { + static get isSupported() { + throw new Error(`"isSupported" not implemented on ${ this.name }`); + } + static isContextMatch(context) { + throw new Error(`"isContextMatch" not implemented on ${ this.name }`); + } + static getFeatures() { + throw new Error(`"getFeatures" not implemented on ${ this.name }`); + } + static destroyContext(context) { + throw new Error(`"destroyContext" called on ${ this.name }`); + } + static nativeFunctionArguments() { + throw new Error(`"nativeFunctionArguments" called on ${ this.name }`); + } + static nativeFunctionReturnType() { + throw new Error(`"nativeFunctionReturnType" called on ${ this.name }`); + } + static combineKernels() { + throw new Error(`"combineKernels" called on ${ this.name }`); + } + constructor(source, settings) { + if (typeof source !== 'object') { + if (typeof source !== 'string') { + throw new Error('source not a string'); + } + if (!isFunctionString(source)) { + throw new Error('source not a function string'); + } + } + this.useLegacyEncoder = false; + this.fallbackRequested = false; + this.onRequestFallback = null; + this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null; + this.argumentTypes = null; + this.argumentSizes = null; + this.argumentBitRatios = null; + this.kernelArguments = null; + this.kernelConstants = null; + this.source = source; + this.output = null; + this.debug = false; + this.graphical = false; + this.loopMaxIterations = 0; + this.constants = null; + this.constantTypes = null; + this.constantBitRatios = null; + this.dynamicArguments = false; + this.dynamicOutput = false; + this.canvas = null; + this.context = null; + this.checkContext = null; + this.gpu = null; + this.functions = null; + this.nativeFunctions = null; + this.injectedNative = null; + this.subKernels = null; + this.validate = true; + this.immutable = false; + this.pipeline = false; + this.precision = null; + this.tactic = 'balanced'; + this.plugins = null; + this.returnType = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.optimizeFloatMemory = null; + this.strictIntegers = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + } + mergeSettings(settings) { + for (let p in settings) { + if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue; + switch (p) { + case 'output': + if (!Array.isArray(settings.output)) { + this.setOutput(settings.output); + continue; + } break; - case 'z': - retArr.push('outputZ'); + case 'functions': + if (typeof settings.functions[0] === 'function') { + this.functions = settings.functions.map(source => functionToIFunction(source)); + continue; + } break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); + case 'graphical': + if (settings[p] && !settings.hasOwnProperty('precision')) { + this.precision = 'unsigned'; + } + this[p] = settings[p]; + continue; } - return retArr; - case 'value': - throw this.astErrorOutput('Unexpected expression', mNode); - case 'value[]': - case 'value[][]': - case 'value[][][]': - case 'value.value': - if (origin === 'Math') { - retArr.push(Math[name]); - return retArr; + this[p] = settings[p]; + } + if (!this.canvas) this.canvas = this.initCanvas(); + if (!this.context) this.context = this.initContext(); + if (!this.plugins) this.plugins = this.initPlugins(settings); + } + build() { + throw new Error(`"build" not defined on ${ this.constructor.name }`); + } + run() { + throw new Error(`"run" not defined on ${ this.constructor.name }`) + } + initCanvas() { + throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`); + } + initContext() { + throw new Error(`"initContext" not defined on ${ this.constructor.name }`); + } + initPlugins(settings) { + throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`); + } + setupArguments(args) { + this.kernelArguments = []; + if (!this.argumentTypes) { + if (!this.argumentTypes) { + this.argumentTypes = []; + for (let i = 0; i < args.length; i++) { + const argType = getVariableType(args[i], this.strictIntegers); + const type = argType === 'Integer' ? 'Number' : argType; + this.argumentTypes.push(type); + this.kernelArguments.push({ + type + }); + } } - switch (property) { - case 'r': - retArr.push(`user_${ name }[0]`); - return retArr; - case 'g': - retArr.push(`user_${ name }[1]`); - return retArr; - case 'b': - retArr.push(`user_${ name }[2]`); - return retArr; - case 'a': - retArr.push(`user_${ name }[3]`); - return retArr; + } else { + for (let i = 0; i < this.argumentTypes.length; i++) { + this.kernelArguments.push({ + type: this.argumentTypes[i] + }); } - break; - case 'this.constants.value': - case 'this.constants.value[]': - case 'this.constants.value[][]': - case 'this.constants.value[][][]': - break; - case 'fn()[]': - this.astGeneric(mNode.object, retArr); - retArr.push('['); - this.astGeneric(mNode.property, retArr); - retArr.push(']'); - return retArr; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - - if (!mNode.computed) { - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - retArr.push(`${origin}_${name}`); - return retArr; + } + this.argumentSizes = new Array(args.length); + this.argumentBitRatios = new Int32Array(args.length); + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + this.argumentSizes[i] = arg.constructor === Input ? arg.size : null; + this.argumentBitRatios[i] = this.getBitRatio(arg); + } + if (this.argumentNames.length !== args.length) { + throw new Error(`arguments are miss-aligned`); } } - - const markupName = `${origin}_${name}`; - - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - case 'HTMLImageArray': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'HTMLImage': - default: - let size; - let isInput; - if (origin === 'constants') { - const constant = this.constants[name]; - isInput = this.constantTypes[name] === 'Input'; - size = isInput ? constant.size : null; - } else { - isInput = this.isInput(name); - size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null; - } - retArr.push(`${ markupName }`); - if (zProperty && yProperty) { - if (isInput) { - retArr.push('[('); - this.astGeneric(zProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`); - this.astGeneric(yProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + setupConstants() { + this.kernelConstants = []; + let needsConstantTypes = this.constantTypes === null; + if (needsConstantTypes) { + this.constantTypes = {}; + } + this.constantBitRatios = {}; + if (this.constants) { + for (let name in this.constants) { + if (needsConstantTypes) { + const type = getVariableType(this.constants[name], this.strictIntegers); + this.constantTypes[name] = type; + this.kernelConstants.push({ + name, + type + }); } else { - retArr.push('['); - this.astGeneric(zProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(yProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + this.kernelConstants.push({ + name, + type: this.constantTypes[name] + }); } - } else if (yProperty) { - if (isInput) { - retArr.push('[('); - this.astGeneric(yProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + this.constantBitRatios[name] = this.getBitRatio(this.constants[name]); + } + } + } + setOptimizeFloatMemory(flag) { + this.optimizeFloatMemory = flag; + return this; + } + setOutput(output) { + if (output.hasOwnProperty('x')) { + if (output.hasOwnProperty('y')) { + if (output.hasOwnProperty('z')) { + this.output = [output.x, output.y, output.z]; } else { - retArr.push('['); - this.astGeneric(yProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + this.output = [output.x, output.y]; } - } else if (typeof xProperty !== 'undefined') { - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); + } else { + this.output = [output.x]; } + } else { + this.output = output; + } + return this; } - return retArr; - } - - astCallExpression(ast, retArr) { - if (ast.type !== 'CallExpression') { - throw this.astErrorOutput('Unknown CallExpression', ast); + setDebug(flag) { + this.debug = flag; + return this; } - let functionName = this.astMemberExpressionUnroll(ast.callee); - - if (this.calledFunctions.indexOf(functionName) < 0) { - this.calledFunctions.push(functionName); + setGraphical(flag) { + this.graphical = flag; + this.precision = 'unsigned'; + return this; } - - const isMathFunction = this.isAstMathFunction(ast); - - if (this.onFunctionCall) { - this.onFunctionCall(this.name, functionName, ast.arguments); + setLoopMaxIterations(max) { + this.loopMaxIterations = max; + return this; } - - retArr.push(functionName); - - retArr.push('('); - const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - - let argumentType = this.getType(argument); - if (!targetTypes[i]) { - this.triggerImplyArgumentType(functionName, i, argumentType, this); + setConstants(constants) { + this.constants = constants; + return this; + } + setConstantTypes(constantTypes) { + this.constantTypes = constantTypes; + return this; + } + setFunctions(functions) { + if (typeof functions[0] === 'function') { + this.functions = functions.map(source => functionToIFunction(source)); + } else { + this.functions = functions; } - - if (i > 0) { - retArr.push(', '); + return this; + } + setNativeFunctions(nativeFunctions) { + this.nativeFunctions = nativeFunctions; + return this; + } + setInjectedNative(injectedNative) { + this.injectedNative = injectedNative; + return this; + } + setPipeline(flag) { + this.pipeline = flag; + return this; + } + setPrecision(flag) { + this.precision = flag; + return this; + } + setOutputToTexture(flag) { + warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); + this.pipeline = flag; + return this; + } + setImmutable(flag) { + this.immutable = flag; + return this; + } + setCanvas(canvas) { + this.canvas = canvas; + return this; + } + setStrictIntegers(flag) { + this.strictIntegers = flag; + return this; + } + setDynamicOutput(flag) { + this.dynamicOutput = flag; + return this; + } + setHardcodeConstants(flag) { + warnDeprecated('method', 'setHardcodeConstants'); + this.setDynamicOutput(flag); + this.setDynamicArguments(flag); + return this; + } + setDynamicArguments(flag) { + this.dynamicArguments = flag; + return this; + } + setUseLegacyEncoder(flag) { + this.useLegacyEncoder = flag; + return this; + } + setWarnVarUsage(flag) { + this.warnVarUsage = flag; + return this; + } + getCanvas() { + warnDeprecated('method', 'getCanvas'); + return this.canvas; + } + getWebGl() { + warnDeprecated('method', 'getWebGl'); + return this.context; + } + setContext(context) { + this.context = context; + return this; + } + setArgumentTypes(argumentTypes) { + if (Array.isArray(argumentTypes)) { + this.argumentTypes = argumentTypes; + } else { + this.argumentTypes = []; + for (const p in argumentTypes) { + const argumentIndex = this.argumentNames.indexOf(p); + if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); + this.argumentTypes[argumentIndex] = argumentTypes[p]; + } } - this.astGeneric(argument, retArr); + return this; } - retArr.push(')'); - - return retArr; - } - - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('new Float32Array(['); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); + setTactic(tactic) { + this.tactic = tactic; + return this; + } + requestFallback(args) { + if (!this.onRequestFallback) { + throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); } - const subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr) + this.fallbackRequested = true; + return this.onRequestFallback(args); } - retArr.push('])'); - - return retArr; - } - - astDebuggerStatement(arrNode, retArr) { - retArr.push('debugger;'); - return retArr; - } -} - -module.exports = { - CPUFunctionNode -}; -},{"../function-node":10}],7:[function(require,module,exports){ -const { utils } = require('../../utils'); - -function constantsToString(constants, types) { - const results = []; - for (const name in types) { - if (!types.hasOwnProperty(name)) continue; - const type = types[name]; - const constant = constants[name]; - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - results.push(`${name}:${constant}`); - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); - break; + validateSettings() { + throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`); } - } - return `{ ${ results.join() } }`; -} - -function cpuKernelString(cpuKernel, name) { - const header = []; - const thisProperties = []; - const beforeReturn = []; - - const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString()); - - header.push( - ' const { context, canvas, constants: incomingConstants } = settings;', - ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`, - ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`, - ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`, - ); - - thisProperties.push( - ' constants: _constants,', - ' context,', - ' output,', - ' thread: {x: 0, y: 0, z: 0},', - ); - - if (cpuKernel.graphical) { - header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`); - header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`); - - const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), { - thisLookup: (propertyName) => { - switch (propertyName) { - case '_colorData': - return '_colorData'; - case '_imageData': - return '_imageData'; - case 'output': - return 'output'; - case 'thread': - return 'this.thread'; - } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: (object, name) => { - return null; + addSubKernel(subKernel) { + if (this.subKernels === null) { + this.subKernels = []; } - }); - - const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), { - thisLookup: (propertyName) => { - switch (propertyName) { - case '_colorData': - return '_colorData'; - case '_imageData': - return '_imageData'; - case 'output': - return 'output'; - case 'thread': - return 'this.thread'; + if (!subKernel.source) throw new Error('subKernel missing "source" property'); + if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property'); + if (!subKernel.name) throw new Error('subKernel missing "name" property'); + this.subKernels.push(subKernel); + return this; + } + destroy(removeCanvasReferences) { + throw new Error(`"destroy" called on ${ this.constructor.name }`); + } + getBitRatio(value) { + if (this.precision === 'single') { + return 4; + } else if (Array.isArray(value[0])) { + return this.getBitRatio(value[0]); + } else if (value.constructor === Input) { + return this.getBitRatio(value.value); + } + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + return 1; + case Uint16Array: + case Int16Array: + return 2; + case Float32Array: + case Int32Array: + default: + return 4; + } + } + getPixels() { + throw new Error(`"getPixels" called on ${ this.constructor.name }`); + } + checkOutput() { + if (!this.output || !isArray(this.output)) throw new Error('kernel.output not an array'); + if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value'); + for (let i = 0; i < this.output.length; i++) { + if (isNaN(this.output[i]) || this.output[i] < 1) { + throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`); } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: () => { - return null; } - }); - - thisProperties.push( - ' _imageData,', - ' _colorData,', - ` color: ${colorFn},`, - ); - - beforeReturn.push( - ` kernel.getPixels = ${getPixelsFn};` - ); + } + toJSON() { + const settings = { + output: this.output, + threadDim: this.threadDim, + pipeline: this.pipeline, + argumentNames: this.argumentNames, + argumentsTypes: this.argumentTypes, + constants: this.constants, + pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null, + returnType: this.returnType, + }; + return { + settings + }; + } } - const constantTypes = []; - const constantKeys = Object.keys(cpuKernel.constantTypes); - for (let i = 0; i < constantKeys.length; i++) { - constantTypes.push(cpuKernel.constantTypes[constantKeys]); - } - if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) { - const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), { - doNotDefine: ['canvas'], - findDependency: (object, name) => { - if (object === 'this') { - return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString(); - } - return null; - }, - thisLookup: (propertyName) => { - switch (propertyName) { - case 'canvas': - return; - case 'context': - return 'context'; + class FunctionBuilder { + static fromKernel(kernel, FunctionNode, extraNodeOptions) { + const { + kernelArguments, + kernelConstants, + argumentNames, + argumentSizes, + argumentBitRatios, + constants, + constantBitRatios, + debug, + loopMaxIterations, + nativeFunctions, + output, + optimizeFloatMemory, + precision, + plugins, + source, + subKernels, + functions, + leadingReturnStatement, + followingReturnStatement, + dynamicArguments, + dynamicOutput, + warnVarUsage, + } = kernel; + const argumentTypes = new Array(kernelArguments.length); + const constantTypes = {}; + for (let i = 0; i < kernelArguments.length; i++) { + argumentTypes[i] = kernelArguments[i].type; + } + for (let i = 0; i < kernelConstants.length; i++) { + const kernelConstant = kernelConstants[i]; + constantTypes[kernelConstant.name] = kernelConstant.type; + } + const needsArgumentType = (functionName, index) => { + return functionBuilder.needsArgumentType(functionName, index); + }; + const assignArgumentType = (functionName, index, type) => { + functionBuilder.assignArgumentType(functionName, index, type); + }; + const lookupReturnType = (functionName, ast, requestingNode) => { + return functionBuilder.lookupReturnType(functionName, ast, requestingNode); + }; + const lookupFunctionArgumentTypes = (functionName) => { + return functionBuilder.lookupFunctionArgumentTypes(functionName); + }; + const lookupFunctionArgumentName = (functionName, argumentIndex) => { + return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex); + }; + const lookupFunctionArgumentBitRatio = (functionName, argumentName) => { + return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName); + }; + const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => { + functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode); + }; + const triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => { + functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex); + }; + const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => { + return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName); + }; + const onFunctionCall = (functionName, calleeFunctionName, args) => { + functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); + }; + const onNestedFunction = (ast, returnType) => { + const argumentNames = []; + for (let i = 0; i < ast.params.length; i++) { + argumentNames.push(ast.params[i].name); } + const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { + returnType: null, + ast, + name: ast.id.name, + argumentNames, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + warnVarUsage, + })); + nestedFunction.traceFunctionAST(ast); + functionBuilder.addFunctionNode(nestedFunction); + }; + const nodeOptions = Object.assign({ + isRootKernel: false, + onNestedFunction, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + optimizeFloatMemory, + precision, + constants, + constantTypes, + constantBitRatios, + debug, + loopMaxIterations, + output, + plugins, + dynamicArguments, + dynamicOutput, + }, extraNodeOptions || {}); + const rootNodeOptions = Object.assign({}, nodeOptions, { + isRootKernel: true, + name: 'kernel', + argumentNames, + argumentTypes, + argumentSizes, + argumentBitRatios, + leadingReturnStatement, + followingReturnStatement, + }); + if (typeof source === 'object' && source.functionNodes) { + return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode); + } + const rootNode = new FunctionNode(source, rootNodeOptions); + let functionNodes = null; + if (functions) { + functionNodes = functions.map((fn) => new FunctionNode(fn.source, { + returnType: fn.returnType, + argumentTypes: fn.argumentTypes, + output, + plugins, + constants, + constantTypes, + constantBitRatios, + optimizeFloatMemory, + precision, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + })); } - }); - beforeReturn.push(flattenedImageTo3DArray); - thisProperties.push(` _mediaTo2DArray,`); - thisProperties.push(` _imageTo3DArray,`); - } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) { - const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), { - findDependency: (object, name) => { - return null; - }, - thisLookup: (propertyName) => { - switch (propertyName) { - case 'canvas': - return 'settings.canvas'; - case 'context': - return 'settings.context'; - } - throw new Error('unhandled thisLookup'); + let subKernelNodes = null; + if (subKernels) { + subKernelNodes = subKernels.map((subKernel) => { + const { name, source } = subKernel; + return new FunctionNode(source, Object.assign({}, nodeOptions, { + name, + isSubKernel: true, + isRootKernel: false, + })); + }); } - }); - beforeReturn.push(flattenedImageTo2DArray); - thisProperties.push(` _mediaTo2DArray,`); - } - - return `function(settings) { -${ header.join('\n') } - for (const p in _constantTypes) { - if (!_constantTypes.hasOwnProperty(p)) continue; - const type = _constantTypes[p]; - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - if (incomingConstants.hasOwnProperty(p)) { - console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); - } - continue; - } - if (!incomingConstants.hasOwnProperty(p)) { - throw new Error('constant ' + p + ' not found'); - } - _constants[p] = incomingConstants[p]; - } - const kernel = (function() { -${cpuKernel._kernelString} - }) - .apply({ ${thisProperties.join('\n')} }); - ${ beforeReturn.join('\n') } - return kernel; -}`; -} - -module.exports = { - cpuKernelString -}; -},{"../../utils":112}],8:[function(require,module,exports){ -const { Kernel } = require('../kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { CPUFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const { cpuKernelString } = require('./kernel-string'); - -class CPUKernel extends Kernel { - static getFeatures() { - return this.features; - } - static get features() { - return Object.freeze({ - kernelMap: true, - isIntegerDivisionAccurate: true - }); - } - static get isSupported() { - return true; - } - static isContextMatch(context) { - return false; - } - static get mode() { - return 'cpu'; - } - - static nativeFunctionArguments() { - return null; - } - - static nativeFunctionReturnType() { - return null; - } - - static combineKernels(combinedKernel) { - return combinedKernel; - } - - constructor(source, settings) { - super(source, settings); - this.mergeSettings(source.settings || settings); - - this._imageData = null; - this._colorData = null; - this._kernelString = null; - this.thread = { - x: 0, - y: 0, - z: 0 - }; - this.translatedSources = null; - } - - initCanvas() { - if (typeof document !== 'undefined') { - return document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - return new OffscreenCanvas(0, 0); + const functionBuilder = new FunctionBuilder({ + kernel, + rootNode, + functionNodes, + nativeFunctions, + subKernelNodes + }); + return functionBuilder; } - } - - initContext() { - if (!this.canvas) return null; - return this.canvas.getContext('2d'); - } - - initPlugins(settings) { - return []; - } - - validateSettings(args) { - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); + constructor(settings) { + settings = settings || {}; + this.kernel = settings.kernel; + this.rootNode = settings.rootNode; + this.functionNodes = settings.functionNodes || []; + this.subKernelNodes = settings.subKernelNodes || []; + this.nativeFunctions = settings.nativeFunctions || []; + this.functionMap = {}; + this.nativeFunctionNames = []; + this.lookupChain = []; + this.argumentChain = []; + this.functionNodeDependencies = {}; + this.functionCalls = {}; + if (this.rootNode) { + this.functionMap['kernel'] = this.rootNode; } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { - this.output = args[0].output; - } else { - throw new Error('Auto output not supported for input type: ' + argType); + if (this.functionNodes) { + for (let i = 0; i < this.functionNodes.length; i++) { + this.functionMap[this.functionNodes[i].name] = this.functionNodes[i]; + } + } + if (this.subKernelNodes) { + for (let i = 0; i < this.subKernelNodes.length; i++) { + this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i]; + } + } + if (this.nativeFunctions) { + for (let i = 0; i < this.nativeFunctions.length; i++) { + const nativeFunction = this.nativeFunctions[i]; + this.nativeFunctionNames.push(nativeFunction.name); + } } } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + addFunctionNode(functionNode) { + if (!functionNode.name) throw new Error('functionNode.name needs set'); + this.functionMap[functionNode.name] = functionNode; + if (functionNode.isRootKernel) { + this.rootNode = functionNode; } } - - this.checkOutput(); - } - - translateSource() { - this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = '; - if (this.subKernels) { - const followingReturnStatement = [] - for (let i = 0; i < this.subKernels.length; i++) { - const { - name - } = this.subKernels[i]; - followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`); + traceFunctionCalls(functionName, retList) { + functionName = functionName || 'kernel'; + retList = retList || []; + if (this.nativeFunctionNames.indexOf(functionName) > -1) { + if (retList.indexOf(functionName) === -1) { + retList.push(functionName); + } + return retList; } - this.followingReturnStatement = followingReturnStatement.join(''); + const functionNode = this.functionMap[functionName]; + if (functionNode) { + const functionIndex = retList.indexOf(functionName); + if (functionIndex === -1) { + retList.push(functionName); + functionNode.toString(); + for (let i = 0; i < functionNode.calledFunctions.length; ++i) { + this.traceFunctionCalls(functionNode.calledFunctions[i], retList); + } + } else { + const dependantFunctionName = retList.splice(functionIndex, 1)[0]; + retList.push(dependantFunctionName); + } + } + return retList; } - const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); - this.translatedSources = functionBuilder.getPrototypes('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + getPrototypeString(functionName) { + return this.getPrototypes(functionName).join('\n'); } - } - - build() { - this.setupConstants(); - this.setupArguments(arguments); - this.validateSettings(arguments); - this.translateSource(); - - if (this.graphical) { - const { - canvas, - output - } = this; - if (!canvas) { - throw new Error('no canvas available for using graphical output'); + getPrototypes(functionName) { + if (this.rootNode) { + this.rootNode.toString(); } - const width = output[0]; - const height = output[1] || 1; - canvas.width = width; - canvas.height = height; - this._imageData = this.context.createImageData(width, height); - this._colorData = new Uint8ClampedArray(width * height * 4); + if (functionName) { + return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + } + return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); } - - const kernelString = this.getKernelString(); - this.kernelString = kernelString; - - if (this.debug) { - console.log('Function output:'); - console.log(kernelString); + getStringFromFunctionNames(functionList) { + const ret = []; + for (let i = 0; i < functionList.length; ++i) { + const node = this.functionMap[functionList[i]]; + if (node) { + ret.push(this.functionMap[functionList[i]].toString()); + } + } + return ret.join('\n'); } - - try { - this.run = new Function([], kernelString).bind(this)(); - } catch (e) { - console.error('An error occurred compiling the javascript: ', e); + getPrototypesFromFunctionNames(functionList) { + const ret = []; + for (let i = 0; i < functionList.length; ++i) { + const functionName = functionList[i]; + const functionIndex = this.nativeFunctionNames.indexOf(functionName); + if (functionIndex > -1) { + ret.push(this.nativeFunctions[functionIndex].source); + continue; + } + const node = this.functionMap[functionName]; + if (node) { + ret.push(node.toString()); + } + } + return ret; } - } - - color(r, g, b, a) { - if (typeof a === 'undefined') { - a = 1; + toJSON() { + return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => { + const nativeIndex = this.nativeFunctions.indexOf(name); + if (nativeIndex > -1) { + return { + name, + source: this.nativeFunctions[nativeIndex].source + }; + } else if (this.functionMap[name]) { + return this.functionMap[name].toJSON(); + } else { + throw new Error(`function ${ name } not found`); + } + }); } - - r = Math.floor(r * 255); - g = Math.floor(g * 255); - b = Math.floor(b * 255); - a = Math.floor(a * 255); - - const width = this.output[0]; - const height = this.output[1]; - - const x = this.thread.x; - const y = height - this.thread.y - 1; - - const index = x + y * width; - - this._colorData[index * 4 + 0] = r; - this._colorData[index * 4 + 1] = g; - this._colorData[index * 4 + 2] = b; - this._colorData[index * 4 + 3] = a; - } - - getKernelString() { - if (this._kernelString !== null) return this._kernelString; - - let kernelThreadString = null; - let { - translatedSources - } = this; - if (translatedSources.length > 1) { - translatedSources = translatedSources.filter(fn => { - if (/^function/.test(fn)) return fn; - kernelThreadString = fn; - return false; - }) - } else { - kernelThreadString = translatedSources.shift(); - } - return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() }; - ${ this.injectedNative || '' } - const _this = this; - ${ this._processConstants() } - return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { - ${ this._processArguments() } - ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) } - ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' } - };`; - } - - toString() { - return cpuKernelString(this); - } - - _getLoopMaxString() { - return ( - this.loopMaxIterations ? - ` ${ parseInt(this.loopMaxIterations) };` : - ' 1000;' - ); - } - - _processConstants() { - if (!this.constants) return ''; - - const result = []; - for (let p in this.constants) { - const type = this.constantTypes[p]; - switch (type) { - case 'HTMLImage': - case 'HTMLVideo': - result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`); - break; - case 'HTMLImageArray': - result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`); - break; - case 'Input': - result.push(` const constants_${p} = this.constants.${p}.value;\n`); - break; - default: - result.push(` const constants_${p} = this.constants.${p};\n`); + fromJSON(jsonFunctionNodes, FunctionNode) { + this.functionMap = {}; + for (let i = 0; i < jsonFunctionNodes.length; i++) { + const jsonFunctionNode = jsonFunctionNodes[i]; + this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings); } + return this; } - return result.join(''); - } - - _processArguments() { - const result = []; - for (let i = 0; i < this.argumentTypes.length; i++) { - const variableName = `user_${this.argumentNames[i]}`; - switch (this.argumentTypes[i]) { - case 'HTMLImage': - case 'HTMLVideo': - result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`); - break; - case 'HTMLImageArray': - result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`); - break; - case 'Input': - result.push(` ${variableName} = ${variableName}.value;\n`); - break; - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'NumberTexture': - case 'MemoryOptimizedNumberTexture': - result.push(` - if (${variableName}.toArray) { - if (!_this.textureCache) { - _this.textureCache = []; - _this.arrayCache = []; - } - const textureIndex = _this.textureCache.indexOf(${variableName}); - if (textureIndex !== -1) { - ${variableName} = _this.arrayCache[textureIndex]; - } else { - _this.textureCache.push(${variableName}); - ${variableName} = ${variableName}.toArray(); - _this.arrayCache.push(${variableName}); + getString(functionName) { + if (functionName) { + return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse()); } - }`); - break; + return this.getStringFromFunctionNames(Object.keys(this.functionMap)); + } + lookupReturnType(functionName, ast, requestingNode) { + if (ast.type !== 'CallExpression') { + throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`); + } + if (this._isNativeFunction(functionName)) { + return this._lookupNativeFunctionReturnType(functionName); + } else if (this._isFunction(functionName)) { + const node = this._getFunction(functionName); + if (node.returnType) { + return node.returnType; + } else { + for (let i = 0; i < this.lookupChain.length; i++) { + if (this.lookupChain[i].ast === ast) { + if (node.argumentTypes.length === 0 && ast.arguments.length > 0) { + const args = ast.arguments; + for (let j = 0; j < args.length; j++) { + this.lookupChain.push({ + name: requestingNode.name, + ast: args[i], + requestingNode + }); + node.argumentTypes[j] = requestingNode.getType(args[j]); + this.lookupChain.pop(); + } + return node.returnType = node.getType(node.getJsAST()); + } + throw new Error('circlical logic detected!'); + } + } + this.lookupChain.push({ + name: requestingNode.name, + ast, + requestingNode + }); + const type = node.getType(node.getJsAST()); + this.lookupChain.pop(); + return node.returnType = type; + } } + return null; } - return result.join(''); - } - - _mediaTo2DArray(media) { - const canvas = this.canvas; - const width = media.width > 0 ? media.width : media.videoWidth; - const height = media.height > 0 ? media.height : media.videoHeight; - if (canvas.width < width) { - canvas.width = width; - } - if (canvas.height < height) { - canvas.height = height; - } - const ctx = this.context; - ctx.drawImage(media, 0, 0, width, height); - const pixelsData = ctx.getImageData(0, 0, width, height).data; - const imageArray = new Array(height); - let index = 0; - for (let y = height - 1; y >= 0; y--) { - const row = imageArray[y] = new Array(width); - for (let x = 0; x < width; x++) { - const pixel = new Float32Array(4); - pixel[0] = pixelsData[index++] / 255; - pixel[1] = pixelsData[index++] / 255; - pixel[2] = pixelsData[index++] / 255; - pixel[3] = pixelsData[index++] / 255; - row[x] = pixel; + _getFunction(functionName) { + if (!this._isFunction(functionName)) ; + return this.functionMap[functionName]; + } + _isFunction(functionName) { + return Boolean(this.functionMap[functionName]); + } + _getNativeFunction(functionName) { + for (let i = 0; i < this.nativeFunctions.length; i++) { + if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i]; } + return null; } - return imageArray; - } - - getPixels(flip) { - const [width, height] = this.output; - return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0); - } - - _imageTo3DArray(images) { - const imagesArray = new Array(images.length); - for (let i = 0; i < images.length; i++) { - imagesArray[i] = this._mediaTo2DArray(images[i]); + _isNativeFunction(functionName) { + return Boolean(this._getNativeFunction(functionName)); } - return imagesArray; - } - - _resultKernelBody(kernelString) { - switch (this.output.length) { - case 1: - return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); - case 2: - return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); - case 3: - return this._resultKernel3DLoop(kernelString) + this._kernelOutput(); - default: - throw new Error('unsupported size kernel'); + _lookupNativeFunctionReturnType(functionName) { + let nativeFunction = this._getNativeFunction(functionName); + if (nativeFunction) { + return nativeFunction.returnType; + } + throw new Error(`Native function ${ functionName } not found`); } - } - - _graphicalKernelBody(kernelThreadString) { - switch (this.output.length) { - case 2: - return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput(); - default: - throw new Error('unsupported size kernel'); + lookupFunctionArgumentTypes(functionName) { + if (this._isNativeFunction(functionName)) { + return this._getNativeFunction(functionName).argumentTypes; + } else if (this._isFunction(functionName)) { + return this._getFunction(functionName).argumentTypes; + } + return null; } - } - - _graphicalOutput() { - return ` - this._imageData.data.set(this._colorData); - this.context.putImageData(this._imageData, 0, 0); - return;` - } - - _getKernelResultTypeConstructorString() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return 'Float32Array'; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return 'Array'; - default: - if (this.graphical) { - return 'Float32Array'; + lookupFunctionArgumentName(functionName, argumentIndex) { + return this._getFunction(functionName).argumentNames[argumentIndex]; + } + lookupFunctionArgumentBitRatio(functionName, argumentName) { + if (!this._isFunction(functionName)) { + throw new Error('function not found'); + } + if (this.rootNode.name === functionName) { + const i = this.rootNode.argumentNames.indexOf(argumentName); + if (i !== -1) { + return this.rootNode.argumentBitRatios[i]; + } else { + throw new Error('argument bit ratio not found'); } - throw new Error(`unhandled returnType ${ this.returnType }`); + } else { + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymIndex]; + if (!argumentSynonym) { + throw new Error('argument synonym not found'); + } + return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName); + } + } + needsArgumentType(functionName, i) { + if (!this._isFunction(functionName)) return false; + const fnNode = this._getFunction(functionName); + return !fnNode.argumentTypes[i]; + } + assignArgumentType(functionName, i, argumentType, requestingNode) { + if (!this._isFunction(functionName)) return; + const fnNode = this._getFunction(functionName); + if (!fnNode.argumentTypes[i]) { + fnNode.argumentTypes[i] = argumentType; + } + } + trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) { + if (!this._isFunction(calleeFunctionName)) return; + const node = this._getFunction(calleeFunctionName); + if (!node.argumentSynonym) { + node.argumentSynonym = {}; + } + const calleeArgumentName = node.argumentNames[argumentIndex]; + if (!node.argumentSynonym[calleeArgumentName]) { + node.argumentSynonym[calleeArgumentName] = {}; + } + node.synonymIndex++; + node.argumentSynonym[node.synonymIndex] = { + functionName, + argumentName, + calleeArgumentName, + calleeFunctionName, + }; } - } - - _resultKernel1DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const result = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - ${ kernelString } - }`; - } - - _resultKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const result = new Array(outputY); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - const resultX = result[y] = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } + lookupArgumentSynonym(originFunctionName, functionName, argumentName) { + if (originFunctionName === functionName) return argumentName; + if (!this._isFunction(functionName)) return null; + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymUseIndex]; + if (!argumentSynonym) return null; + if (argumentSynonym.calleeArgumentName !== argumentName) return null; + node.synonymUseIndex++; + if (originFunctionName !== functionName) { + return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName); } - }`; - } - - _graphicalKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } + return argumentSynonym.argumentName; + } + trackFunctionCall(functionName, calleeFunctionName, args) { + if (!this.functionNodeDependencies[functionName]) { + this.functionNodeDependencies[functionName] = new Set(); + this.functionCalls[functionName] = []; } - }`; - } - - _resultKernel3DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - const result = new Array(outputZ); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let z = 0; z < outputZ; z++) { - this.thread.z = z; - const resultY = result[z] = new Array(outputY); - ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.y = y; - const resultX = resultY[y] = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } + this.functionNodeDependencies[functionName].add(calleeFunctionName); + this.functionCalls[functionName].push(args); + } + getKernelResultType() { + return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast); + } + getSubKernelResultType(index) { + const subKernelNode = this.subKernelNodes[index]; + let called = false; + for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) { + const functionCall = this.rootNode.functionCalls[functionCallIndex]; + if (functionCall.ast.callee.name === subKernelNode.name) { + called = true; } } - }`; - } - - _kernelOutput() { - if (!this.subKernels) { - return '\n return result;'; + if (!called) { + throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); + } + return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST()); } - return `\n return { - result: result, - ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') } - };`; - } - - _mapSubKernels(fn) { - return this.subKernels === null ? [''] : - this.subKernels.map(fn); - } - - - - destroy(removeCanvasReference) { - if (removeCanvasReference) { - delete this.canvas; + getReturnTypes() { + const result = { + [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast), + }; + const list = this.traceFunctionCalls(this.rootNode.name); + for (let i = 0; i < list.length; i++) { + const functionName = list[i]; + const functionNode = this.functionMap[functionName]; + result[functionName] = functionNode.getType(functionNode.ast); + } + return result; } } - static destroyContext(context) {} - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON(); - return json; - } - - setOutput(output) { - super.setOutput(output); - const [width, height] = this.output; - if (this.graphical) { - this._imageData = this.context.createImageData(width, height); - this._colorData = new Uint8ClampedArray(width * height * 4); + class FunctionTracer { + constructor(ast) { + this.runningContexts = []; + this.contexts = []; + this.functionCalls = []; + this.declarations = []; + this.identifiers = []; + this.functions = []; + this.returnStatements = []; + this.inLoopInit = false; + this.scan(ast); } - } -} - -module.exports = { - CPUKernel -}; -},{"../../utils":112,"../function-builder":9,"../kernel":35,"./function-node":6,"./kernel-string":7}],9:[function(require,module,exports){ -class FunctionBuilder { - static fromKernel(kernel, FunctionNode, extraNodeOptions) { - const { - kernelArguments, - kernelConstants, - argumentNames, - argumentSizes, - argumentBitRatios, - constants, - constantBitRatios, - debug, - loopMaxIterations, - nativeFunctions, - output, - optimizeFloatMemory, - precision, - plugins, - source, - subKernels, - functions, - leadingReturnStatement, - followingReturnStatement, - dynamicArguments, - dynamicOutput, - warnVarUsage, - } = kernel; - - const argumentTypes = new Array(kernelArguments.length); - const constantTypes = {}; - - for (let i = 0; i < kernelArguments.length; i++) { - argumentTypes[i] = kernelArguments[i].type; + get currentContext() { + return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; } - - for (let i = 0; i < kernelConstants.length; i++) { - const kernelConstant = kernelConstants[i]; - constantTypes[kernelConstant.name] = kernelConstant.type; + newContext(run) { + const newContext = Object.assign({}, this.currentContext); + this.contexts.push(newContext); + this.runningContexts.push(newContext); + run(); + this.runningContexts.pop(); } - - const needsArgumentType = (functionName, index) => { - return functionBuilder.needsArgumentType(functionName, index); - }; - - const assignArgumentType = (functionName, index, type) => { - functionBuilder.assignArgumentType(functionName, index, type); - }; - - const lookupReturnType = (functionName, ast, requestingNode) => { - return functionBuilder.lookupReturnType(functionName, ast, requestingNode); - }; - - const lookupFunctionArgumentTypes = (functionName) => { - return functionBuilder.lookupFunctionArgumentTypes(functionName); - }; - - const lookupFunctionArgumentName = (functionName, argumentIndex) => { - return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex); - }; - - const lookupFunctionArgumentBitRatio = (functionName, argumentName) => { - return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName); - }; - - const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => { - functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode); - }; - - const triggerImplyArgumentBitRatio = (functionName, argumentName, calleeFunctionName, argumentIndex) => { - functionBuilder.assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex); - }; - - const onFunctionCall = (functionName, calleeFunctionName, args) => { - functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); - }; - - const onNestedFunction = (ast, returnType) => { - const argumentNames = []; - for (let i = 0; i < ast.params.length; i++) { - argumentNames.push(ast.params[i].name); + scan(ast) { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.scan(ast[i]); + } + return; + } + switch (ast.type) { + case 'Program': + this.scan(ast.body); + break; + case 'BlockStatement': + this.newContext(() => { + this.scan(ast.body); + }); + break; + case 'AssignmentExpression': + case 'LogicalExpression': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'BinaryExpression': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'UpdateExpression': + case 'UnaryExpression': + this.scan(ast.argument); + break; + case 'VariableDeclaration': + this.scan(ast.declarations); + break; + case 'VariableDeclarator': + const { currentContext } = this; + const declaration = { + ast: ast, + context: currentContext, + name: ast.id.name, + origin: 'declaration', + forceInteger: this.inLoopInit, + assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name), + }; + currentContext[ast.id.name] = declaration; + this.declarations.push(declaration); + this.scan(ast.id); + this.scan(ast.init); + break; + case 'FunctionExpression': + case 'FunctionDeclaration': + if (this.runningContexts.length === 0) { + this.scan(ast.body); + } else { + this.functions.push(ast); + } + break; + case 'IfStatement': + this.scan(ast.test); + this.scan(ast.consequent); + if (ast.alternate) this.scan(ast.alternate); + break; + case 'ForStatement': + this.newContext(() => { + this.inLoopInit = true; + this.scan(ast.init); + this.inLoopInit = false; + this.scan(ast.test); + this.scan(ast.update); + this.newContext(() => { + this.scan(ast.body); + }); + }); + break; + case 'DoWhileStatement': + case 'WhileStatement': + this.newContext(() => { + this.scan(ast.body); + this.scan(ast.test); + }); + break; + case 'Identifier': + this.identifiers.push({ + context: this.currentContext, + ast, + }); + break; + case 'ReturnStatement': + this.returnStatements.push(ast); + this.scan(ast.argument); + break; + case 'MemberExpression': + this.scan(ast.object); + this.scan(ast.property); + break; + case 'ExpressionStatement': + this.scan(ast.expression); + break; + case 'CallExpression': + this.functionCalls.push({ + context: this.currentContext, + ast, + }); + this.scan(ast.arguments); + break; + case 'ArrayExpression': + this.scan(ast.elements); + break; + case 'ConditionalExpression': + this.scan(ast.test); + this.scan(ast.alternate); + this.scan(ast.consequent); + break; + case 'SwitchStatement': + this.scan(ast.discriminant); + this.scan(ast.cases); + break; + case 'SwitchCase': + this.scan(ast.test); + this.scan(ast.consequent); + break; + case 'ThisExpression': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'Literal': + case 'DebuggerStatement': + case 'EmptyStatement': + case 'BreakStatement': + case 'ContinueStatement': + break; + default: + throw new Error(`unhandled type "${ast.type}"`); } - const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { - returnType: null, - ast, - name: ast.id.name, - argumentNames, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - warnVarUsage, - })); - nestedFunction.traceFunctionAST(ast); - functionBuilder.addFunctionNode(nestedFunction); - }; - - const nodeOptions = Object.assign({ - isRootKernel: false, - onNestedFunction, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - optimizeFloatMemory, - precision, - constants, - constantTypes, - constantBitRatios, - debug, - loopMaxIterations, - output, - plugins, - dynamicArguments, - dynamicOutput, - }, extraNodeOptions || {}); - - const rootNodeOptions = Object.assign({}, nodeOptions, { - isRootKernel: true, - name: 'kernel', - argumentNames, - argumentTypes, - argumentSizes, - argumentBitRatios, - leadingReturnStatement, - followingReturnStatement, - }); - - if (typeof source === 'object' && source.functionNodes) { - return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode); - } - - const rootNode = new FunctionNode(source, rootNodeOptions); - - let functionNodes = null; - if (functions) { - functionNodes = functions.map((fn) => new FunctionNode(fn.source, { - returnType: fn.returnType, - argumentTypes: fn.argumentTypes, - output, - plugins, - constants, - constantTypes, - constantBitRatios, - optimizeFloatMemory, - precision, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - onNestedFunction, - })); - } - - let subKernelNodes = null; - if (subKernels) { - subKernelNodes = subKernels.map((subKernel) => { - const { name, source } = subKernel; - return new FunctionNode(source, Object.assign({}, nodeOptions, { - name, - isSubKernel: true, - isRootKernel: false, - })); - }); } - - const functionBuilder = new FunctionBuilder({ - kernel, - rootNode, - functionNodes, - nativeFunctions, - subKernelNodes - }); - - return functionBuilder; } - constructor(settings) { - settings = settings || {}; - this.kernel = settings.kernel; - this.rootNode = settings.rootNode; - this.functionNodes = settings.functionNodes || []; - this.subKernelNodes = settings.subKernelNodes || []; - this.nativeFunctions = settings.nativeFunctions || []; - this.functionMap = {}; - this.nativeFunctionNames = []; - this.lookupChain = []; - this.argumentChain = []; - this.functionNodeDependencies = {}; - this.functionCalls = {}; - - if (this.rootNode) { - this.functionMap['kernel'] = this.rootNode; - } - - if (this.functionNodes) { - for (let i = 0; i < this.functionNodes.length; i++) { - this.functionMap[this.functionNodes[i].name] = this.functionNodes[i]; + class FunctionNode { + constructor(source, settings) { + if (!source && !settings.ast) { + throw new Error('source parameter is missing'); } - } - - if (this.subKernelNodes) { - for (let i = 0; i < this.subKernelNodes.length; i++) { - this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i]; + settings = settings || {}; + this.source = source; + this.ast = null; + this.name = typeof source === 'string' ? settings.isRootKernel ? + 'kernel' : + (settings.name || getFunctionNameFromString(source)) : null; + this.calledFunctions = []; + this.constants = {}; + this.constantTypes = {}; + this.constantBitRatios = {}; + this.isRootKernel = false; + this.isSubKernel = false; + this.debug = null; + this.declarations = null; + this.functions = null; + this.identifiers = null; + this.contexts = null; + this.functionCalls = null; + this.states = []; + this.needsArgumentType = null; + this.assignArgumentType = null; + this.lookupReturnType = null; + this.lookupFunctionArgumentTypes = null; + this.lookupFunctionArgumentBitRatio = null; + this.triggerImplyArgumentType = null; + this.triggerImplyArgumentBitRatio = null; + this.onNestedFunction = null; + this.onFunctionCall = null; + this.optimizeFloatMemory = null; + this.precision = null; + this.loopMaxIterations = null; + this.argumentNames = (typeof this.source === 'string' ? getArgumentNamesFromString(this.source) : null); + this.argumentTypes = []; + this.argumentSizes = []; + this.argumentBitRatios = null; + this.returnType = null; + this.output = []; + this.plugins = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.dynamicOutput = null; + this.dynamicArguments = null; + this.strictTypingChecking = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + if (settings) { + for (const p in settings) { + if (!settings.hasOwnProperty(p)) continue; + if (!this.hasOwnProperty(p)) continue; + this[p] = settings[p]; + } } + this.literalTypes = {}; + this.validate(); + this._string = null; + this._internalVariableNames = {}; } - - if (this.nativeFunctions) { - for (let i = 0; i < this.nativeFunctions.length; i++) { - const nativeFunction = this.nativeFunctions[i]; - this.nativeFunctionNames.push(nativeFunction.name); + validate() { + if (typeof this.source !== 'string' && !this.ast) { + throw new Error('this.source not a string'); + } + if (!this.ast && !isFunctionString(this.source)) { + throw new Error('this.source not a function string'); + } + if (!this.name) { + throw new Error('this.name could not be set'); + } + if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) { + throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`); + } + if (this.output.length < 1) { + throw new Error('this.output is not big enough'); } } - } - - addFunctionNode(functionNode) { - if (!functionNode.name) throw new Error('functionNode.name needs set'); - this.functionMap[functionNode.name] = functionNode; - if (functionNode.isRootKernel) { - this.rootNode = functionNode; + isIdentifierConstant(name) { + if (!this.constants) return false; + return this.constants.hasOwnProperty(name); } - } - - traceFunctionCalls(functionName, retList) { - functionName = functionName || 'kernel'; - retList = retList || []; - - if (this.nativeFunctionNames.indexOf(functionName) > -1) { - if (retList.indexOf(functionName) === -1) { - retList.push(functionName); - } - return retList; + isInput(argumentName) { + return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input'; } - - const functionNode = this.functionMap[functionName]; - if (functionNode) { - const functionIndex = retList.indexOf(functionName); - if (functionIndex === -1) { - retList.push(functionName); - functionNode.toString(); - for (let i = 0; i < functionNode.calledFunctions.length; ++i) { - this.traceFunctionCalls(functionNode.calledFunctions[i], retList); - } - } else { - const dependantFunctionName = retList.splice(functionIndex, 1)[0]; - retList.push(dependantFunctionName); + pushState(state) { + this.states.push(state); + } + popState(state) { + if (this.state !== state) { + throw new Error(`Cannot popState ${ state } when in ${ this.state }`); } + this.states.pop(); } - - return retList; - } - - getPrototypeString(functionName) { - return this.getPrototypes(functionName).join('\n'); - } - - getPrototypes(functionName) { - if (this.rootNode) { - this.rootNode.toString(); + isState(state) { + return this.state === state; } - if (functionName) { - return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + get state() { + return this.states[this.states.length - 1]; } - return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); - } - - getStringFromFunctionNames(functionList) { - const ret = []; - for (let i = 0; i < functionList.length; ++i) { - const node = this.functionMap[functionList[i]]; - if (node) { - ret.push(this.functionMap[functionList[i]].toString()); + astMemberExpressionUnroll(ast) { + if (ast.type === 'Identifier') { + return ast.name; + } else if (ast.type === 'ThisExpression') { + return 'this'; } - } - return ret.join('\n'); - } - - getPrototypesFromFunctionNames(functionList) { - const ret = []; - for (let i = 0; i < functionList.length; ++i) { - const functionName = functionList[i]; - const functionIndex = this.nativeFunctionNames.indexOf(functionName); - if (functionIndex > -1) { - ret.push(this.nativeFunctions[functionIndex].source); - continue; + if (ast.type === 'MemberExpression') { + if (ast.object && ast.property) { + if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { + return this.astMemberExpressionUnroll(ast.property); + } + return ( + this.astMemberExpressionUnroll(ast.object) + + '.' + + this.astMemberExpressionUnroll(ast.property) + ); + } } - const node = this.functionMap[functionName]; - if (node) { - ret.push(node.toString()); + if (ast.hasOwnProperty('expressions')) { + const firstExpression = ast.expressions[0]; + if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) { + return this.astMemberExpressionUnroll(ast.expressions[1]); + } } + throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast); } - return ret; - } - - toJSON() { - return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => { - const nativeIndex = this.nativeFunctions.indexOf(name); - if (nativeIndex > -1) { - return { - name, - source: this.nativeFunctions[nativeIndex].source - }; - } else if (this.functionMap[name]) { - return this.functionMap[name].toJSON(); - } else { - throw new Error(`function ${ name } not found`); + getJsAST(inParser) { + if (this.ast) { + return this.ast; } - }); - } - - fromJSON(jsonFunctionNodes, FunctionNode) { - this.functionMap = {}; - for (let i = 0; i < jsonFunctionNodes.length; i++) { - const jsonFunctionNode = jsonFunctionNodes[i]; - this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings); - } - return this; - } - - getString(functionName) { - if (functionName) { - return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse()); - } - return this.getStringFromFunctionNames(Object.keys(this.functionMap)); - } - - lookupReturnType(functionName, ast, requestingNode) { - if (ast.type !== 'CallExpression') { - throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`); - } - if (this._isNativeFunction(functionName)) { - return this._lookupNativeFunctionReturnType(functionName); - } else if (this._isFunction(functionName)) { - const node = this._getFunction(functionName); - if (node.returnType) { - return node.returnType; - } else { - for (let i = 0; i < this.lookupChain.length; i++) { - if (this.lookupChain[i].ast === ast) { - if (node.argumentTypes.length === 0 && ast.arguments.length > 0) { - const args = ast.arguments; - for (let j = 0; j < args.length; j++) { - this.lookupChain.push({ - name: requestingNode.name, - ast: args[i], - requestingNode - }); - node.argumentTypes[j] = requestingNode.getType(args[j]); - this.lookupChain.pop(); - } - return node.returnType = node.getType(node.getJsAST()); + if (typeof this.source === 'object') { + this.traceFunctionAST(this.source); + return this.ast = this.source; + } + const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : parse; + if (inParser === null) { + throw new Error('Missing JS to AST parser'); + } + const ast = Object.freeze(parser(`const parser_${ this.name } = ${ this.source };`, { + locations: true + })); + const functionAST = ast.body[0].declarations[0].init; + this.traceFunctionAST(functionAST); + if (!ast) { + throw new Error('Failed to parse JS code'); + } + return this.ast = functionAST; + } + traceFunctionAST(ast) { + const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast); + this.contexts = contexts; + this.identifiers = identifiers; + this.functionCalls = functionCalls; + this.declarations = []; + this.functions = functions; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + const { ast, context, name, origin, forceInteger, assignable } = declaration; + const { init } = ast; + const dependencies = this.getDependencies(init); + let valueType = null; + if (forceInteger) { + valueType = 'Integer'; + } else { + if (init) { + const realType = this.getType(init); + switch (realType) { + case 'Integer': + case 'Float': + case 'Number': + if (init.type === 'MemberExpression') { + valueType = realType; + } else { + valueType = 'Number'; + } + break; + case 'LiteralInteger': + valueType = 'Number'; + break; + default: + valueType = realType; } - - throw new Error('circlical logic detected!'); } } - this.lookupChain.push({ - name: requestingNode.name, + this.declarations.push({ + valueType, + dependencies, + isSafe: this.isSafeDependencies(dependencies), ast, - requestingNode + name, + context, + origin, + assignable, }); - const type = node.getType(node.getJsAST()); - this.lookupChain.pop(); - return node.returnType = type; - } - } - - return null; - } - - _getFunction(functionName) { - if (!this._isFunction(functionName)) { - new Error(`Function ${functionName} not found`); - } - return this.functionMap[functionName]; - } - - _isFunction(functionName) { - return Boolean(this.functionMap[functionName]); - } - - _getNativeFunction(functionName) { - for (let i = 0; i < this.nativeFunctions.length; i++) { - if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i]; - } - return null; - } - - _isNativeFunction(functionName) { - return Boolean(this._getNativeFunction(functionName)); - } - - _lookupNativeFunctionReturnType(functionName) { - let nativeFunction = this._getNativeFunction(functionName); - if (nativeFunction) { - return nativeFunction.returnType; - } - throw new Error(`Native function ${ functionName } not found`); - } - - lookupFunctionArgumentTypes(functionName) { - if (this._isNativeFunction(functionName)) { - return this._getNativeFunction(functionName).argumentTypes; - } else if (this._isFunction(functionName)) { - return this._getFunction(functionName).argumentTypes; - } - return null; - } - - lookupFunctionArgumentName(functionName, argumentIndex) { - return this._getFunction(functionName).argumentNames[argumentIndex]; - } - - lookupFunctionArgumentBitRatio(functionName, argumentName) { - if (!this._isFunction(functionName)) { - throw new Error('function not found'); - } - if (this.rootNode.name === functionName) { - const i = this.rootNode.argumentNames.indexOf(argumentName); - if (i !== -1) { - return this.rootNode.argumentBitRatios[i]; - } - } - const node = this._getFunction(functionName); - const i = node.argumentNames.indexOf(argumentName); - if (i === -1) { - throw new Error('argument not found'); - } - const bitRatio = node.argumentBitRatios[i]; - if (typeof bitRatio !== 'number') { - throw new Error('argument bit ratio not found'); - } - return bitRatio; - } - - needsArgumentType(functionName, i) { - if (!this._isFunction(functionName)) return false; - const fnNode = this._getFunction(functionName); - return !fnNode.argumentTypes[i]; - } - - assignArgumentType(functionName, i, argumentType, requestingNode) { - if (!this._isFunction(functionName)) return; - const fnNode = this._getFunction(functionName); - if (!fnNode.argumentTypes[i]) { - fnNode.argumentTypes[i] = argumentType; - } - } - - assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex) { - const node = this._getFunction(functionName); - if (this._isNativeFunction(calleeFunctionName)) return null; - const calleeNode = this._getFunction(calleeFunctionName); - const i = node.argumentNames.indexOf(argumentName); - if (i === -1) { - throw new Error(`Argument ${argumentName} not found in arguments from function ${functionName}`); - } - const bitRatio = node.argumentBitRatios[i]; - if (typeof bitRatio !== 'number') { - throw new Error(`Bit ratio for argument ${argumentName} not found in function ${functionName}`); - } - if (!calleeNode.argumentBitRatios) { - calleeNode.argumentBitRatios = new Array(calleeNode.argumentNames.length); - } - const calleeBitRatio = calleeNode.argumentBitRatios[i]; - if (typeof calleeBitRatio === 'number') { - if (calleeBitRatio !== bitRatio) { - throw new Error(`Incompatible bit ratio found at function ${functionName} at argument ${argumentName}`); - } - return calleeBitRatio; - } - calleeNode.argumentBitRatios[i] = bitRatio; - return bitRatio; - } - - trackFunctionCall(functionName, calleeFunctionName, args) { - if (!this.functionNodeDependencies[functionName]) { - this.functionNodeDependencies[functionName] = new Set(); - this.functionCalls[functionName] = []; - } - this.functionNodeDependencies[functionName].add(calleeFunctionName); - this.functionCalls[functionName].push(args); - } - - getKernelResultType() { - return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast); - } - - getSubKernelResultType(index) { - const subKernelNode = this.subKernelNodes[index]; - let called = false; - for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) { - const functionCall = this.rootNode.functionCalls[functionCallIndex]; - if (functionCall.ast.callee.name === subKernelNode.name) { - called = true; } - } - if (!called) { - throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); - } - return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST()); - } - - getReturnTypes() { - const result = { - [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast), - }; - const list = this.traceFunctionCalls(this.rootNode.name); - for (let i = 0; i < list.length; i++) { - const functionName = list[i]; - const functionNode = this.functionMap[functionName]; - result[functionName] = functionNode.getType(functionNode.ast); - } - return result; - } -} - -module.exports = { - FunctionBuilder -}; - -},{}],10:[function(require,module,exports){ -const acorn = require('acorn'); -const { utils } = require('../utils'); -const { FunctionTracer } = require('./function-tracer'); - -class FunctionNode { - constructor(source, settings) { - if (!source && !settings.ast) { - throw new Error('source parameter is missing'); - } - settings = settings || {}; - this.source = source; - this.ast = null; - this.name = typeof source === 'string' ? settings.isRootKernel ? - 'kernel' : - (settings.name || utils.getFunctionNameFromString(source)) : null; - this.calledFunctions = []; - this.constants = {}; - this.constantTypes = {}; - this.constantBitRatios = {}; - this.isRootKernel = false; - this.isSubKernel = false; - this.debug = null; - this.declarations = null; - this.functions = null; - this.identifiers = null; - this.contexts = null; - this.functionCalls = null; - this.states = []; - this.needsArgumentType = null; - this.assignArgumentType = null; - this.lookupReturnType = null; - this.lookupFunctionArgumentTypes = null; - this.lookupFunctionArgumentBitRatio = null; - this.triggerImplyArgumentType = null; - this.triggerImplyArgumentBitRatio = null; - this.onNestedFunction = null; - this.onFunctionCall = null; - this.optimizeFloatMemory = null; - this.precision = null; - this.loopMaxIterations = null; - this.argumentNames = (typeof this.source === 'string' ? utils.getArgumentNamesFromString(this.source) : null); - this.argumentTypes = []; - this.argumentSizes = []; - this.argumentBitRatios = null; - this.returnType = null; - this.output = []; - this.plugins = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.dynamicOutput = null; - this.dynamicArguments = null; - this.strictTypingChecking = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - - if (settings) { - for (const p in settings) { - if (!settings.hasOwnProperty(p)) continue; - if (!this.hasOwnProperty(p)) continue; - this[p] = settings[p]; + for (let i = 0; i < functions.length; i++) { + this.onNestedFunction(functions[i]); } } - - this.literalTypes = {}; - - this.validate(); - this._string = null; - this._internalVariableNames = {}; - } - - validate() { - if (typeof this.source !== 'string' && !this.ast) { - throw new Error('this.source not a string'); - } - - if (!this.ast && !utils.isFunctionString(this.source)) { - throw new Error('this.source not a function string'); - } - - if (!this.name) { - throw new Error('this.name could not be set'); - } - - if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) { - throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`); - } - - if (this.output.length < 1) { - throw new Error('this.output is not big enough'); - } - } - - isIdentifierConstant(name) { - if (!this.constants) return false; - return this.constants.hasOwnProperty(name); - } - - isInput(argumentName) { - return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input'; - } - - pushState(state) { - this.states.push(state); - } - - popState(state) { - if (this.state !== state) { - throw new Error(`Cannot popState ${ state } when in ${ this.state }`); - } - this.states.pop(); - } - - isState(state) { - return this.state === state; - } - - get state() { - return this.states[this.states.length - 1]; - } - - astMemberExpressionUnroll(ast) { - if (ast.type === 'Identifier') { - return ast.name; - } else if (ast.type === 'ThisExpression') { - return 'this'; - } - - if (ast.type === 'MemberExpression') { - if (ast.object && ast.property) { - if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { - return this.astMemberExpressionUnroll(ast.property); + getDeclaration(ast) { + for (let i = 0; i < this.identifiers.length; i++) { + const identifier = this.identifiers[i]; + if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { + for (let j = 0; j < this.declarations.length; j++) { + const declaration = this.declarations[j]; + if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { + return declaration; + } + } } - - return ( - this.astMemberExpressionUnroll(ast.object) + - '.' + - this.astMemberExpressionUnroll(ast.property) - ); } + return null; } - - if (ast.hasOwnProperty('expressions')) { - const firstExpression = ast.expressions[0]; - if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) { - return this.astMemberExpressionUnroll(ast.expressions[1]); + getVariableType(ast) { + if (ast.type !== 'Identifier') { + throw new Error(`ast of ${ast.type} not "Identifier"`); } - } - - throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast); - } - - getJsAST(inParser) { - if (this.ast) { - return this.ast; - } - if (typeof this.source === 'object') { - this.traceFunctionAST(this.source); - return this.ast = this.source; - } - - inParser = inParser || acorn; - if (inParser === null) { - throw new Error('Missing JS to AST parser'); - } - - const ast = Object.freeze(inParser.parse(`const parser_${ this.name } = ${ this.source };`, { - locations: true - })); - const functionAST = ast.body[0].declarations[0].init; - this.traceFunctionAST(functionAST); - - if (!ast) { - throw new Error('Failed to parse JS code'); - } - - return this.ast = functionAST; - } - - traceFunctionAST(ast) { - const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast); - this.contexts = contexts; - this.identifiers = identifiers; - this.functionCalls = functionCalls; - this.declarations = []; - this.functions = functions; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - const { ast, context, name, origin, forceInteger, assignable } = declaration; - const { init } = ast; - const dependencies = this.getDependencies(init); - let valueType = null; - - if (forceInteger) { - valueType = 'Integer'; + let type = null; + const argumentIndex = this.argumentNames.indexOf(ast.name); + if (argumentIndex === -1) { + const declaration = this.getDeclaration(ast); + if (declaration) { + return declaration.valueType; + } } else { - if (init) { - const realType = this.getType(init); - switch (realType) { - case 'Integer': - case 'Float': - case 'Number': - if (init.type === 'MemberExpression') { - valueType = realType; - } else { - valueType = 'Number'; - } - break; - case 'LiteralInteger': - valueType = 'Number'; - break; - default: - valueType = realType; - } + const argumentType = this.argumentTypes[argumentIndex]; + if (argumentType) { + type = argumentType; } } - this.declarations.push({ - valueType, - dependencies, - isSafe: this.isSafeDependencies(dependencies), - ast, - name, - context, - origin, - assignable, - }); - } - - for (let i = 0; i < functions.length; i++) { - this.onNestedFunction(functions[i]); - } - } - - getDeclaration(ast) { - for (let i = 0; i < this.identifiers.length; i++) { - const identifier = this.identifiers[i]; - if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { - for (let j = 0; j < this.declarations.length; j++) { - const declaration = this.declarations[j]; - if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { - return declaration; - } - } + if (!type && this.strictTypingChecking) { + throw new Error(`Declaration of ${name} not found`); } + return type; } - return null; - } - - getVariableType(ast) { - if (ast.type !== 'Identifier') { - throw new Error(`ast of ${ast.type} not "Identifier"`); - } - let type = null; - const argumentIndex = this.argumentNames.indexOf(ast.name); - if (argumentIndex === -1) { - const declaration = this.getDeclaration(ast); - if (declaration) { - return declaration.valueType; + getLookupType(type) { + if (!typeLookupMap.hasOwnProperty(type)) { + throw new Error(`unknown typeLookupMap ${ type }`); } - } else { - const argumentType = this.argumentTypes[argumentIndex]; - if (argumentType) { - type = argumentType; + return typeLookupMap[type]; + } + getConstantType(constantName) { + if (this.constantTypes[constantName]) { + const type = this.constantTypes[constantName]; + if (type === 'Float') { + return 'Number'; + } else { + return type; + } } + throw new Error(`Type for constant "${ constantName }" not declared`); } - if (!type && this.strictTypingChecking) { - throw new Error(`Declaration of ${name} not found`); + toString() { + if (this._string) return this._string; + return this._string = this.astGeneric(this.getJsAST(), []).join('').trim(); } - return type; - } - - getLookupType(type) { - if (!typeLookupMap.hasOwnProperty(type)) { - throw new Error(`unknown typeLookupMap ${ type }`); + toJSON() { + const settings = { + source: this.source, + name: this.name, + constants: this.constants, + constantTypes: this.constantTypes, + isRootKernel: this.isRootKernel, + isSubKernel: this.isSubKernel, + debug: this.debug, + output: this.output, + loopMaxIterations: this.loopMaxIterations, + argumentNames: this.argumentNames, + argumentTypes: this.argumentTypes, + argumentSizes: this.argumentSizes, + returnType: this.returnType, + leadingReturnStatement: this.leadingReturnStatement, + followingReturnStatement: this.followingReturnStatement, + }; + return { + ast: this.ast, + settings + }; } - return typeLookupMap[type]; - } - - getConstantType(constantName) { - if (this.constantTypes[constantName]) { - const type = this.constantTypes[constantName]; - if (type === 'Float') { - return 'Number'; - } else { - return type; + getType(ast) { + if (Array.isArray(ast)) { + return this.getType(ast[ast.length - 1]); } - } - throw new Error(`Type for constant "${ constantName }" not declared`); - } - - toString() { - if (this._string) return this._string; - return this._string = this.astGeneric(this.getJsAST(), []).join('').trim(); - } - - toJSON() { - const settings = { - source: this.source, - name: this.name, - constants: this.constants, - constantTypes: this.constantTypes, - isRootKernel: this.isRootKernel, - isSubKernel: this.isSubKernel, - debug: this.debug, - output: this.output, - loopMaxIterations: this.loopMaxIterations, - argumentNames: this.argumentNames, - argumentTypes: this.argumentTypes, - argumentSizes: this.argumentSizes, - returnType: this.returnType, - leadingReturnStatement: this.leadingReturnStatement, - followingReturnStatement: this.followingReturnStatement, - }; - - return { - ast: this.ast, - settings - }; - } - - getType(ast) { - if (Array.isArray(ast)) { - return this.getType(ast[ast.length - 1]); - } - switch (ast.type) { - case 'BlockStatement': - return this.getType(ast.body); - case 'ArrayExpression': - return `Array(${ ast.elements.length })`; - case 'Literal': - const literalKey = `${ast.start},${ast.end}`; - if (this.literalTypes[literalKey]) { - return this.literalTypes[literalKey]; - } - if (Number.isInteger(ast.value)) { - return 'LiteralInteger'; - } else if (ast.value === true || ast.value === false) { - return 'Boolean'; - } else { - return 'Number'; - } - case 'AssignmentExpression': - return this.getType(ast.left); - case 'CallExpression': - if (this.isAstMathFunction(ast)) { + switch (ast.type) { + case 'BlockStatement': + return this.getType(ast.body); + case 'ArrayExpression': + return `Array(${ ast.elements.length })`; + case 'Literal': + const literalKey = `${ast.start},${ast.end}`; + if (this.literalTypes[literalKey]) { + return this.literalTypes[literalKey]; + } + if (Number.isInteger(ast.value)) { + return 'LiteralInteger'; + } else if (ast.value === true || ast.value === false) { + return 'Boolean'; + } else { return 'Number'; } - if (!ast.callee || !ast.callee.name) { - if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) { - const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name; + case 'AssignmentExpression': + return this.getType(ast.left); + case 'CallExpression': + if (this.isAstMathFunction(ast)) { + return 'Number'; + } + if (!ast.callee || !ast.callee.name) { + if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) { + const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name; + this.inferArgumentTypesIfNeeded(functionName, ast.arguments); + return this.lookupReturnType(functionName, ast, this); + } + throw this.astErrorOutput('Unknown call expression', ast); + } + if (ast.callee && ast.callee.name) { + const functionName = ast.callee.name; this.inferArgumentTypesIfNeeded(functionName, ast.arguments); return this.lookupReturnType(functionName, ast, this); } - throw this.astErrorOutput('Unknown call expression', ast); - } - if (ast.callee && ast.callee.name) { - const functionName = ast.callee.name; - this.inferArgumentTypesIfNeeded(functionName, ast.arguments); - return this.lookupReturnType(functionName, ast, this); - } - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); - case 'BinaryExpression': - switch (ast.operator) { - case '%': - case '/': - if (this.fixIntegerDivisionAccuracy) { - return 'Number'; - } else { - break; + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + case 'BinaryExpression': + switch (ast.operator) { + case '%': + case '/': + if (this.fixIntegerDivisionAccuracy) { + return 'Number'; + } else { + break; + } + case '>': + case '<': + return 'Boolean'; + case '&': + case '|': + case '^': + case '<<': + case '>>': + case '>>>': + return 'Integer'; + } + const type = this.getType(ast.left); + if (this.isState('skip-literal-correction')) return type; + if (type === 'LiteralInteger') { + const rightType = this.getType(ast.right); + if (rightType === 'LiteralInteger') { + if (ast.left.value % 1 === 0) { + return 'Integer'; + } else { + return 'Float'; + } } - case '>': - case '<': - return 'Boolean'; - case '&': - case '|': - case '^': - case '<<': - case '>>': - case '>>>': - return 'Integer'; + return rightType; + } + return typeLookupMap[type] || type; + case 'UpdateExpression': + return this.getType(ast.argument); + case 'UnaryExpression': + if (ast.operator === '~') { + return 'Integer'; + } + return this.getType(ast.argument); + case 'VariableDeclaration': { + const declarations = ast.declarations; + let lastType; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + lastType = this.getType(declaration); + } + if (!lastType) { + throw this.astErrorOutput(`Unable to find type for declaration`, ast); + } + return lastType; } - const type = this.getType(ast.left); - if (this.isState('skip-literal-correction')) return type; - if (type === 'LiteralInteger') { - const rightType = this.getType(ast.right); - if (rightType === 'LiteralInteger') { - if (ast.left.value % 1 === 0) { - return 'Integer'; - } else { - return 'Float'; + case 'VariableDeclarator': + const declaration = this.getDeclaration(ast.id); + if (!declaration) { + throw this.astErrorOutput(`Unable to find declarator`, ast); + } + if (!declaration.valueType) { + throw this.astErrorOutput(`Unable to find declarator valueType`, ast); + } + return declaration.valueType; + case 'Identifier': + if (ast.name === 'Infinity') { + return 'Number'; + } + if (this.isAstVariable(ast)) { + const signature = this.getVariableSignature(ast); + if (signature === 'value') { + const type = this.getVariableType(ast); + if (!type) { + throw this.astErrorOutput(`Unable to find identifier valueType`, ast); + } + return type; } } - return rightType; - } - return typeLookupMap[type] || type; - case 'UpdateExpression': - return this.getType(ast.argument); - case 'UnaryExpression': - if (ast.operator === '~') { - return 'Integer'; - } - return this.getType(ast.argument); - case 'VariableDeclaration': { - const declarations = ast.declarations; - let lastType; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - lastType = this.getType(declaration); - } - if (!lastType) { - throw this.astErrorOutput(`Unable to find type for declaration`, ast); - } - return lastType; - } - case 'VariableDeclarator': - const declaration = this.getDeclaration(ast.id); - if (!declaration) { - throw this.astErrorOutput(`Unable to find declarator`, ast); - } - - if (!declaration.valueType) { - throw this.astErrorOutput(`Unable to find declarator valueType`, ast); - } - - return declaration.valueType; - case 'Identifier': - if (ast.name === 'Infinity') { - return 'Number'; - } - if (this.isAstVariable(ast)) { - const signature = this.getVariableSignature(ast); - if (signature === 'value') { - const type = this.getVariableType(ast); - if (!type) { - throw this.astErrorOutput(`Unable to find identifier valueType`, ast); - } - return type; + const origin = this.findIdentifierOrigin(ast); + if (origin && origin.init) { + return this.getType(origin.init); } - } - const origin = this.findIdentifierOrigin(ast); - if (origin && origin.init) { - return this.getType(origin.init); - } - return null; - case 'ReturnStatement': - return this.getType(ast.argument); - case 'MemberExpression': - if (this.isAstMathFunction(ast)) { - switch (ast.property.name) { - case 'ceil': - return 'Integer'; - case 'floor': - return 'Integer'; - case 'round': - return 'Integer'; + return null; + case 'ReturnStatement': + return this.getType(ast.argument); + case 'MemberExpression': + if (this.isAstMathFunction(ast)) { + switch (ast.property.name) { + case 'ceil': + return 'Integer'; + case 'floor': + return 'Integer'; + case 'round': + return 'Integer'; + } + return 'Number'; } - return 'Number'; - } - if (this.isAstVariable(ast)) { - const variableSignature = this.getVariableSignature(ast); - switch (variableSignature) { - case 'value[]': - return this.getLookupType(this.getVariableType(ast.object)); - case 'value[][]': - return this.getLookupType(this.getVariableType(ast.object.object)); - case 'value[][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object)); - case 'value[][][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object.object)); - case 'value.thread.value': - case 'this.thread.value': - return 'Integer'; - case 'this.output.value': - return this.dynamicOutput ? 'Integer' : 'LiteralInteger'; - case 'this.constants.value': - return this.getConstantType(ast.property.name); - case 'this.constants.value[]': - return this.getLookupType(this.getConstantType(ast.object.property.name)); - case 'this.constants.value[][]': - return this.getLookupType(this.getConstantType(ast.object.object.property.name)); - case 'this.constants.value[][][]': - return this.getLookupType(this.getConstantType(ast.object.object.object.property.name)); - case 'this.constants.value[][][][]': - return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name)); - case 'fn()[]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][][]': - return this.getLookupType(this.getType(ast.object)); - case 'value.value': - if (this.isAstMathVariable(ast)) { - return 'Number'; - } - switch (ast.property.name) { - case 'r': - return this.getLookupType(this.getVariableType(ast.object)); - case 'g': - return this.getLookupType(this.getVariableType(ast.object)); - case 'b': - return this.getLookupType(this.getVariableType(ast.object)); - case 'a': - return this.getLookupType(this.getVariableType(ast.object)); - } - case '[][]': - return 'Number'; + if (this.isAstVariable(ast)) { + const variableSignature = this.getVariableSignature(ast); + switch (variableSignature) { + case 'value[]': + return this.getLookupType(this.getVariableType(ast.object)); + case 'value[][]': + return this.getLookupType(this.getVariableType(ast.object.object)); + case 'value[][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object)); + case 'value[][][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object.object)); + case 'value.thread.value': + case 'this.thread.value': + return 'Integer'; + case 'this.output.value': + return this.dynamicOutput ? 'Integer' : 'LiteralInteger'; + case 'this.constants.value': + return this.getConstantType(ast.property.name); + case 'this.constants.value[]': + return this.getLookupType(this.getConstantType(ast.object.property.name)); + case 'this.constants.value[][]': + return this.getLookupType(this.getConstantType(ast.object.object.property.name)); + case 'this.constants.value[][][]': + return this.getLookupType(this.getConstantType(ast.object.object.object.property.name)); + case 'this.constants.value[][][][]': + return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name)); + case 'fn()[]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][][]': + return this.getLookupType(this.getType(ast.object)); + case 'value.value': + if (this.isAstMathVariable(ast)) { + return 'Number'; + } + switch (ast.property.name) { + case 'r': + return this.getLookupType(this.getVariableType(ast.object)); + case 'g': + return this.getLookupType(this.getVariableType(ast.object)); + case 'b': + return this.getLookupType(this.getVariableType(ast.object)); + case 'a': + return this.getLookupType(this.getVariableType(ast.object)); + } + case '[][]': + return 'Number'; + } + throw this.astErrorOutput('Unhandled getType MemberExpression', ast); } throw this.astErrorOutput('Unhandled getType MemberExpression', ast); - } - throw this.astErrorOutput('Unhandled getType MemberExpression', ast); - case 'ConditionalExpression': - return this.getType(ast.consequent); - case 'FunctionDeclaration': - case 'FunctionExpression': - const lastReturn = this.findLastReturn(ast.body); - if (lastReturn) { - return this.getType(lastReturn); - } - return null; - case 'IfStatement': - return this.getType(ast.consequent); - default: - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); - } - } - - inferArgumentTypesIfNeeded(functionName, args) { - for (let i = 0; i < args.length; i++) { - if (!this.needsArgumentType(functionName, i)) continue; - const type = this.getType(args[i]); - if (!type) { - throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]); - } - this.assignArgumentType(functionName, i, type); - } - } - - isAstMathVariable(ast) { - const mathProperties = [ - 'E', - 'PI', - 'SQRT2', - 'SQRT1_2', - 'LN2', - 'LN10', - 'LOG2E', - 'LOG10E', - ]; - return ast.type === 'MemberExpression' && - ast.object && ast.object.type === 'Identifier' && - ast.object.name === 'Math' && - ast.property && - ast.property.type === 'Identifier' && - mathProperties.indexOf(ast.property.name) > -1; - } - - isAstMathFunction(ast) { - const mathFunctions = [ - 'abs', - 'acos', - 'asin', - 'atan', - 'atan2', - 'ceil', - 'cos', - 'exp', - 'floor', - 'log', - 'log2', - 'max', - 'min', - 'pow', - 'random', - 'round', - 'sign', - 'sin', - 'sqrt', - 'tan', - ]; - return ast.type === 'CallExpression' && - ast.callee && - ast.callee.type === 'MemberExpression' && - ast.callee.object && - ast.callee.object.type === 'Identifier' && - ast.callee.object.name === 'Math' && - ast.callee.property && - ast.callee.property.type === 'Identifier' && - mathFunctions.indexOf(ast.callee.property.name) > -1; - } - - isAstVariable(ast) { - return ast.type === 'Identifier' || ast.type === 'MemberExpression'; - } - - isSafe(ast) { - return this.isSafeDependencies(this.getDependencies(ast)); - } - - isSafeDependencies(dependencies) { - return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true; - } - - getDependencies(ast, dependencies, isNotSafe) { - if (!dependencies) { - dependencies = []; - } - if (!ast) return null; - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.getDependencies(ast[i], dependencies, isNotSafe); + case 'ConditionalExpression': + return this.getType(ast.consequent); + case 'FunctionDeclaration': + case 'FunctionExpression': + const lastReturn = this.findLastReturn(ast.body); + if (lastReturn) { + return this.getType(lastReturn); + } + return null; + case 'IfStatement': + return this.getType(ast.consequent); + default: + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); } - return dependencies; } - switch (ast.type) { - case 'AssignmentExpression': - this.getDependencies(ast.left, dependencies, isNotSafe); - this.getDependencies(ast.right, dependencies, isNotSafe); - return dependencies; - case 'ConditionalExpression': - this.getDependencies(ast.test, dependencies, isNotSafe); - this.getDependencies(ast.alternate, dependencies, isNotSafe); - this.getDependencies(ast.consequent, dependencies, isNotSafe); + inferArgumentTypesIfNeeded(functionName, args) { + for (let i = 0; i < args.length; i++) { + if (!this.needsArgumentType(functionName, i)) continue; + const type = this.getType(args[i]); + if (!type) { + throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]); + } + this.assignArgumentType(functionName, i, type); + } + } + isAstMathVariable(ast) { + const mathProperties = [ + 'E', + 'PI', + 'SQRT2', + 'SQRT1_2', + 'LN2', + 'LN10', + 'LOG2E', + 'LOG10E', + ]; + return ast.type === 'MemberExpression' && + ast.object && ast.object.type === 'Identifier' && + ast.object.name === 'Math' && + ast.property && + ast.property.type === 'Identifier' && + mathProperties.indexOf(ast.property.name) > -1; + } + isAstMathFunction(ast) { + const mathFunctions = [ + 'abs', + 'acos', + 'asin', + 'atan', + 'atan2', + 'ceil', + 'cos', + 'exp', + 'floor', + 'log', + 'log2', + 'max', + 'min', + 'pow', + 'random', + 'round', + 'sign', + 'sin', + 'sqrt', + 'tan', + ]; + return ast.type === 'CallExpression' && + ast.callee && + ast.callee.type === 'MemberExpression' && + ast.callee.object && + ast.callee.object.type === 'Identifier' && + ast.callee.object.name === 'Math' && + ast.callee.property && + ast.callee.property.type === 'Identifier' && + mathFunctions.indexOf(ast.callee.property.name) > -1; + } + isAstVariable(ast) { + return ast.type === 'Identifier' || ast.type === 'MemberExpression'; + } + isSafe(ast) { + return this.isSafeDependencies(this.getDependencies(ast)); + } + isSafeDependencies(dependencies) { + return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true; + } + getDependencies(ast, dependencies, isNotSafe) { + if (!dependencies) { + dependencies = []; + } + if (!ast) return null; + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.getDependencies(ast[i], dependencies, isNotSafe); + } return dependencies; - case 'Literal': - dependencies.push({ - origin: 'literal', - value: ast.value, - isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value) - }); - break; - case 'VariableDeclarator': - return this.getDependencies(ast.init, dependencies, isNotSafe); - case 'Identifier': - const declaration = this.getDeclaration(ast); - if (declaration) { + } + switch (ast.type) { + case 'AssignmentExpression': + this.getDependencies(ast.left, dependencies, isNotSafe); + this.getDependencies(ast.right, dependencies, isNotSafe); + return dependencies; + case 'ConditionalExpression': + this.getDependencies(ast.test, dependencies, isNotSafe); + this.getDependencies(ast.alternate, dependencies, isNotSafe); + this.getDependencies(ast.consequent, dependencies, isNotSafe); + return dependencies; + case 'Literal': + dependencies.push({ + origin: 'literal', + value: ast.value, + isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value) + }); + break; + case 'VariableDeclarator': + return this.getDependencies(ast.init, dependencies, isNotSafe); + case 'Identifier': + const declaration = this.getDeclaration(ast); + if (declaration) { + dependencies.push({ + name: ast.name, + origin: 'declaration', + isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies), + }); + } else if (this.argumentNames.indexOf(ast.name) > -1) { + dependencies.push({ + name: ast.name, + origin: 'argument', + isSafe: false, + }); + } else if (this.strictTypingChecking) { + throw new Error(`Cannot find identifier origin "${ast.name}"`); + } + break; + case 'FunctionDeclaration': + return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe); + case 'ReturnStatement': + return this.getDependencies(ast.argument, dependencies); + case 'BinaryExpression': + isNotSafe = (ast.operator === '/' || ast.operator === '*'); + this.getDependencies(ast.left, dependencies, isNotSafe); + this.getDependencies(ast.right, dependencies, isNotSafe); + return dependencies; + case 'UnaryExpression': + case 'UpdateExpression': + return this.getDependencies(ast.argument, dependencies, isNotSafe); + case 'VariableDeclaration': + return this.getDependencies(ast.declarations, dependencies, isNotSafe); + case 'ArrayExpression': dependencies.push({ - name: ast.name, origin: 'declaration', - isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies), + isSafe: true, }); - } else if (this.argumentNames.indexOf(ast.name) > -1) { + return dependencies; + case 'CallExpression': dependencies.push({ - name: ast.name, - origin: 'argument', - isSafe: false, + origin: 'function', + isSafe: true, }); - } else if (this.strictTypingChecking) { - throw new Error(`Cannot find identifier origin "${ast.name}"`); - } - break; - case 'FunctionDeclaration': - return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe); - case 'ReturnStatement': - return this.getDependencies(ast.argument, dependencies); - case 'BinaryExpression': - isNotSafe = (ast.operator === '/' || ast.operator === '*'); - this.getDependencies(ast.left, dependencies, isNotSafe); - this.getDependencies(ast.right, dependencies, isNotSafe); - return dependencies; - case 'UnaryExpression': - case 'UpdateExpression': - return this.getDependencies(ast.argument, dependencies, isNotSafe); - case 'VariableDeclaration': - return this.getDependencies(ast.declarations, dependencies, isNotSafe); - case 'ArrayExpression': - dependencies.push({ - origin: 'declaration', - isSafe: true, - }); - return dependencies; - case 'CallExpression': - dependencies.push({ - origin: 'function', - isSafe: true, - }); - return dependencies; - case 'MemberExpression': - const details = this.getMemberExpressionDetails(ast); - switch (details.signature) { - case 'value[]': - this.getDependencies(ast.object, dependencies, isNotSafe); - break; - case 'value[][]': - this.getDependencies(ast.object.object, dependencies, isNotSafe); - break; - case 'value[][][]': - this.getDependencies(ast.object.object.object, dependencies, isNotSafe); - break; - case 'this.output.value': - if (this.dynamicOutput) { - dependencies.push({ - name: details.name, - origin: 'output', - isSafe: false, - }); - } - break; - } - if (details) { - if (details.property) { - this.getDependencies(details.property, dependencies, isNotSafe); + return dependencies; + case 'MemberExpression': + const details = this.getMemberExpressionDetails(ast); + switch (details.signature) { + case 'value[]': + this.getDependencies(ast.object, dependencies, isNotSafe); + break; + case 'value[][]': + this.getDependencies(ast.object.object, dependencies, isNotSafe); + break; + case 'value[][][]': + this.getDependencies(ast.object.object.object, dependencies, isNotSafe); + break; + case 'this.output.value': + if (this.dynamicOutput) { + dependencies.push({ + name: details.name, + origin: 'output', + isSafe: false, + }); + } + break; } - if (details.xProperty) { - this.getDependencies(details.xProperty, dependencies, isNotSafe); + if (details) { + if (details.property) { + this.getDependencies(details.property, dependencies, isNotSafe); + } + if (details.xProperty) { + this.getDependencies(details.xProperty, dependencies, isNotSafe); + } + if (details.yProperty) { + this.getDependencies(details.yProperty, dependencies, isNotSafe); + } + if (details.zProperty) { + this.getDependencies(details.zProperty, dependencies, isNotSafe); + } + return dependencies; } - if (details.yProperty) { - this.getDependencies(details.yProperty, dependencies, isNotSafe); + default: + throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); + } + return dependencies; + } + getVariableSignature(ast) { + if (!this.isAstVariable(ast)) { + throw new Error(`ast of type "${ ast.type }" is not a variable signature`); + } + if (ast.type === 'Identifier') { + return 'value'; + } + const signature = []; + while (true) { + if (!ast) break; + if (ast.computed) { + signature.push('[]'); + } else if (ast.type === 'ThisExpression') { + signature.unshift('this'); + } else if (ast.property && ast.property.name) { + if ( + ast.property.name === 'x' || + ast.property.name === 'y' || + ast.property.name === 'z' + ) { + signature.unshift('.value'); + } else if ( + ast.property.name === 'constants' || + ast.property.name === 'thread' || + ast.property.name === 'output' + ) { + signature.unshift('.' + ast.property.name); + } else { + signature.unshift('.value'); } - if (details.zProperty) { - this.getDependencies(details.zProperty, dependencies, isNotSafe); + } else if (ast.name) { + signature.unshift('value'); + } else if (ast.callee && ast.callee.name) { + signature.unshift('fn()'); + } else if (ast.elements) { + signature.unshift('[]'); + } else { + signature.unshift('unknown'); + } + ast = ast.object; + } + const signatureString = signature.join(''); + const allowedExpressions = [ + 'value', + 'value[]', + 'value[][]', + 'value[][][]', + 'value[][][][]', + 'value.value', + 'value.thread.value', + 'this.thread.value', + 'this.output.value', + 'this.constants.value', + 'this.constants.value[]', + 'this.constants.value[][]', + 'this.constants.value[][][]', + 'this.constants.value[][][][]', + 'fn()[]', + 'fn()[][]', + 'fn()[][][]', + '[][]', + ]; + if (allowedExpressions.indexOf(signatureString) > -1) { + return signatureString; + } + return null; + } + build() { + return this.toString().length > 0; + } + astGeneric(ast, retArr) { + if (ast === null) { + throw this.astErrorOutput('NULL ast', ast); + } else { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.astGeneric(ast[i], retArr); } - return dependencies; + return retArr; } - default: - throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); + switch (ast.type) { + case 'FunctionDeclaration': + return this.astFunctionDeclaration(ast, retArr); + case 'FunctionExpression': + return this.astFunctionExpression(ast, retArr); + case 'ReturnStatement': + return this.astReturnStatement(ast, retArr); + case 'Literal': + return this.astLiteral(ast, retArr); + case 'BinaryExpression': + return this.astBinaryExpression(ast, retArr); + case 'Identifier': + return this.astIdentifierExpression(ast, retArr); + case 'AssignmentExpression': + return this.astAssignmentExpression(ast, retArr); + case 'ExpressionStatement': + return this.astExpressionStatement(ast, retArr); + case 'EmptyStatement': + return this.astEmptyStatement(ast, retArr); + case 'BlockStatement': + return this.astBlockStatement(ast, retArr); + case 'IfStatement': + return this.astIfStatement(ast, retArr); + case 'SwitchStatement': + return this.astSwitchStatement(ast, retArr); + case 'BreakStatement': + return this.astBreakStatement(ast, retArr); + case 'ContinueStatement': + return this.astContinueStatement(ast, retArr); + case 'ForStatement': + return this.astForStatement(ast, retArr); + case 'WhileStatement': + return this.astWhileStatement(ast, retArr); + case 'DoWhileStatement': + return this.astDoWhileStatement(ast, retArr); + case 'VariableDeclaration': + return this.astVariableDeclaration(ast, retArr); + case 'VariableDeclarator': + return this.astVariableDeclarator(ast, retArr); + case 'ThisExpression': + return this.astThisExpression(ast, retArr); + case 'SequenceExpression': + return this.astSequenceExpression(ast, retArr); + case 'UnaryExpression': + return this.astUnaryExpression(ast, retArr); + case 'UpdateExpression': + return this.astUpdateExpression(ast, retArr); + case 'LogicalExpression': + return this.astLogicalExpression(ast, retArr); + case 'MemberExpression': + return this.astMemberExpression(ast, retArr); + case 'CallExpression': + return this.astCallExpression(ast, retArr); + case 'ArrayExpression': + return this.astArrayExpression(ast, retArr); + case 'DebuggerStatement': + return this.astDebuggerStatement(ast, retArr); + case 'ConditionalExpression': + return this.astConditionalExpression(ast, retArr); + } + throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); + } } - return dependencies; - } - - getVariableSignature(ast) { - if (!this.isAstVariable(ast)) { - throw new Error(`ast of type "${ ast.type }" is not a variable signature`); - } - if (ast.type === 'Identifier') { - return 'value'; - } - const signature = []; - while (true) { - if (!ast) break; - if (ast.computed) { - signature.push('[]'); - } else if (ast.type === 'ThisExpression') { - signature.unshift('this'); - } else if (ast.property && ast.property.name) { - if ( - ast.property.name === 'x' || - ast.property.name === 'y' || - ast.property.name === 'z' - ) { - signature.unshift('.value'); - } else if ( - ast.property.name === 'constants' || - ast.property.name === 'thread' || - ast.property.name === 'output' - ) { - signature.unshift('.' + ast.property.name); - } else { - signature.unshift('.value'); - } - } else if (ast.name) { - signature.unshift('value'); - } else if (ast.callee && ast.callee.name) { - signature.unshift('fn()'); - } else if (ast.elements) { - signature.unshift('[]'); - } else { - signature.unshift('unknown'); + astErrorOutput(error, ast) { + if (typeof this.source !== 'string') { + return new Error(error); } - ast = ast.object; + const debugString = getAstString(this.source, ast); + const leadingSource = this.source.substr(ast.start); + const splitLines = leadingSource.split(/\n/); + const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0; + return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`); } - - const signatureString = signature.join(''); - const allowedExpressions = [ - 'value', - 'value[]', - 'value[][]', - 'value[][][]', - 'value[][][][]', - 'value.value', - 'value.thread.value', - 'this.thread.value', - 'this.output.value', - 'this.constants.value', - 'this.constants.value[]', - 'this.constants.value[][]', - 'this.constants.value[][][]', - 'this.constants.value[][][][]', - 'fn()[]', - 'fn()[][]', - 'fn()[][][]', - '[][]', - ]; - if (allowedExpressions.indexOf(signatureString) > -1) { - return signatureString; + astDebuggerStatement(arrNode, retArr) { + return retArr; } - return null; - } - - build() { - return this.toString().length > 0; - } - - astGeneric(ast, retArr) { - if (ast === null) { - throw this.astErrorOutput('NULL ast', ast); - } else { - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.astGeneric(ast[i], retArr); - } + astConditionalExpression(ast, retArr) { + if (ast.type !== 'ConditionalExpression') { + throw this.astErrorOutput('Not a conditional expression', ast); + } + retArr.push('('); + this.astGeneric(ast.test, retArr); + retArr.push('?'); + this.astGeneric(ast.consequent, retArr); + retArr.push(':'); + this.astGeneric(ast.alternate, retArr); + retArr.push(')'); + return retArr; + } + astFunction(ast, retArr) { + throw new Error(`"astFunction" not defined on ${ this.constructor.name }`); + } + astFunctionDeclaration(ast, retArr) { + if (this.isChildFunction(ast)) { return retArr; } - - switch (ast.type) { - case 'FunctionDeclaration': - return this.astFunctionDeclaration(ast, retArr); - case 'FunctionExpression': - return this.astFunctionExpression(ast, retArr); - case 'ReturnStatement': - return this.astReturnStatement(ast, retArr); - case 'Literal': - return this.astLiteral(ast, retArr); - case 'BinaryExpression': - return this.astBinaryExpression(ast, retArr); - case 'Identifier': - return this.astIdentifierExpression(ast, retArr); - case 'AssignmentExpression': - return this.astAssignmentExpression(ast, retArr); - case 'ExpressionStatement': - return this.astExpressionStatement(ast, retArr); - case 'EmptyStatement': - return this.astEmptyStatement(ast, retArr); - case 'BlockStatement': - return this.astBlockStatement(ast, retArr); - case 'IfStatement': - return this.astIfStatement(ast, retArr); - case 'SwitchStatement': - return this.astSwitchStatement(ast, retArr); - case 'BreakStatement': - return this.astBreakStatement(ast, retArr); - case 'ContinueStatement': - return this.astContinueStatement(ast, retArr); - case 'ForStatement': - return this.astForStatement(ast, retArr); - case 'WhileStatement': - return this.astWhileStatement(ast, retArr); - case 'DoWhileStatement': - return this.astDoWhileStatement(ast, retArr); - case 'VariableDeclaration': - return this.astVariableDeclaration(ast, retArr); - case 'VariableDeclarator': - return this.astVariableDeclarator(ast, retArr); - case 'ThisExpression': - return this.astThisExpression(ast, retArr); - case 'SequenceExpression': - return this.astSequenceExpression(ast, retArr); - case 'UnaryExpression': - return this.astUnaryExpression(ast, retArr); - case 'UpdateExpression': - return this.astUpdateExpression(ast, retArr); - case 'LogicalExpression': - return this.astLogicalExpression(ast, retArr); - case 'MemberExpression': - return this.astMemberExpression(ast, retArr); - case 'CallExpression': - return this.astCallExpression(ast, retArr); - case 'ArrayExpression': - return this.astArrayExpression(ast, retArr); - case 'DebuggerStatement': - return this.astDebuggerStatement(ast, retArr); - case 'ConditionalExpression': - return this.astConditionalExpression(ast, retArr); + return this.astFunction(ast, retArr); + } + astFunctionExpression(ast, retArr) { + if (this.isChildFunction(ast)) { + return retArr; } - - throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); + return this.astFunction(ast, retArr); } - } - astErrorOutput(error, ast) { - if (typeof this.source !== 'string') { - return new Error(error); + isChildFunction(ast) { + for (let i = 0; i < this.functions.length; i++) { + if (this.functions[i] === ast) { + return true; + } + } + return false; } - - const debugString = utils.getAstString(this.source, ast); - const leadingSource = this.source.substr(ast.start); - const splitLines = leadingSource.split(/\n/); - const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0; - return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`); - } - - astDebuggerStatement(arrNode, retArr) { - return retArr; - } - - astConditionalExpression(ast, retArr) { - if (ast.type !== 'ConditionalExpression') { - throw this.astErrorOutput('Not a conditional expression', ast); - } - retArr.push('('); - this.astGeneric(ast.test, retArr); - retArr.push('?'); - this.astGeneric(ast.consequent, retArr); - retArr.push(':'); - this.astGeneric(ast.alternate, retArr); - retArr.push(')'); - return retArr; - } - - astFunction(ast, retArr) { - throw new Error(`"astFunction" not defined on ${ this.constructor.name }`); - } - - astFunctionDeclaration(ast, retArr) { - if (this.isChildFunction(ast)) { + astReturnStatement(ast, retArr) { return retArr; } - return this.astFunction(ast, retArr); - } - astFunctionExpression(ast, retArr) { - if (this.isChildFunction(ast)) { + astLiteral(ast, retArr) { + this.literalTypes[`${ast.start},${ast.end}`] = 'Number'; return retArr; } - return this.astFunction(ast, retArr); - } - isChildFunction(ast) { - for (let i = 0; i < this.functions.length; i++) { - if (this.functions[i] === ast) { - return true; - } + astBinaryExpression(ast, retArr) { + return retArr; } - return false; - } - astReturnStatement(ast, retArr) { - return retArr; - } - astLiteral(ast, retArr) { - this.literalTypes[`${ast.start},${ast.end}`] = 'Number'; - return retArr; - } - astBinaryExpression(ast, retArr) { - return retArr; - } - astIdentifierExpression(ast, retArr) { - return retArr; - } - astAssignmentExpression(ast, retArr) { - return retArr; - } - astExpressionStatement(esNode, retArr) { - this.astGeneric(esNode.expression, retArr); - retArr.push(';'); - return retArr; - } - astEmptyStatement(eNode, retArr) { - return retArr; - } - astBlockStatement(ast, retArr) { - return retArr; - } - astIfStatement(ast, retArr) { - return retArr; - } - astSwitchStatement(ast, retArr) { - return retArr; - } - astBreakStatement(brNode, retArr) { - retArr.push('break;'); - return retArr; - } - astContinueStatement(crNode, retArr) { - retArr.push('continue;\n'); - return retArr; - } - astForStatement(ast, retArr) { - return retArr; - } - astWhileStatement(ast, retArr) { - return retArr; - } - astDoWhileStatement(ast, retArr) { - return retArr; - } - astVariableDeclaration(varDecNode, retArr) { - const declarations = varDecNode.declarations; - if (!declarations || !declarations[0] || !declarations[0].init) { - throw this.astErrorOutput('Unexpected expression', varDecNode); + astIdentifierExpression(ast, retArr) { + return retArr; } - const result = []; - const firstDeclaration = declarations[0]; - const init = firstDeclaration.init; - let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); - if (type === 'LiteralInteger') { - type = 'Number'; - } - const markupType = typeMap[type]; - if (!markupType) { - throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); - } - let dependencies = this.getDependencies(firstDeclaration.init); - throw new Error('remove me'); - this.declarations[firstDeclaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: dependencies.every(dependency => dependency.isSafe) - }); - const initResult = [`${type} user_${firstDeclaration.id.name}=`]; - this.astGeneric(init, initResult); - result.push(initResult.join('')); - - for (let i = 1; i < declarations.length; i++) { - const declaration = declarations[i]; - dependencies = this.getDependencies(declaration); - throw new Error('Remove me'); - this.declarations[declaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: false - }); - this.astGeneric(declaration, result); + astAssignmentExpression(ast, retArr) { + return retArr; } - - retArr.push(retArr, result.join(',')); - retArr.push(';'); - return retArr; - } - astVariableDeclarator(iVarDecNode, retArr) { - this.astGeneric(iVarDecNode.id, retArr); - if (iVarDecNode.init !== null) { - retArr.push('='); - this.astGeneric(iVarDecNode.init, retArr); + astExpressionStatement(esNode, retArr) { + this.astGeneric(esNode.expression, retArr); + retArr.push(';'); + return retArr; } - return retArr; - } - astThisExpression(ast, retArr) { - return retArr; - } - astSequenceExpression(sNode, retArr) { - for (let i = 0; i < sNode.expressions.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(sNode.expressions, retArr); + astEmptyStatement(eNode, retArr) { + return retArr; } - return retArr; - } - astUnaryExpression(uNode, retArr) { - const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); - if (unaryResult) { + astBlockStatement(ast, retArr) { return retArr; } - - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); + astIfStatement(ast, retArr) { + return retArr; } - - return retArr; - } - - checkAndUpconvertBitwiseUnary(uNode, retArr) {} - - astUpdateExpression(uNode, retArr) { - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); + astSwitchStatement(ast, retArr) { + return retArr; } - - return retArr; - } - astLogicalExpression(logNode, retArr) { - retArr.push('('); - this.astGeneric(logNode.left, retArr); - retArr.push(logNode.operator); - this.astGeneric(logNode.right, retArr); - retArr.push(')'); - return retArr; - } - astMemberExpression(ast, retArr) { - return retArr; - } - astCallExpression(ast, retArr) { - return retArr; - } - astArrayExpression(ast, retArr) { - return retArr; - } - - getMemberExpressionDetails(ast) { - if (ast.type !== 'MemberExpression') { - throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast); - } - let name = null; - let type = null; - const variableSignature = this.getVariableSignature(ast); - switch (variableSignature) { - case 'value': - return null; - case 'value.thread.value': - case 'this.thread.value': - case 'this.output.value': - return { - signature: variableSignature, - type: 'Integer', - name: ast.property.name - }; - case 'value[]': - if (typeof ast.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object), - xProperty: ast.property - }; - case 'value[][]': - if (typeof ast.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object), - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value[][][]': - if (typeof ast.object.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object.object), - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value[][][][]': - if (typeof ast.object.object.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object.object.object), - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value.value': - if (typeof ast.property.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); + astBreakStatement(brNode, retArr) { + retArr.push('break;'); + return retArr; + } + astContinueStatement(crNode, retArr) { + retArr.push('continue;\n'); + return retArr; + } + astForStatement(ast, retArr) { + return retArr; + } + astWhileStatement(ast, retArr) { + return retArr; + } + astDoWhileStatement(ast, retArr) { + return retArr; + } + astVariableDeclaration(varDecNode, retArr) { + const declarations = varDecNode.declarations; + if (!declarations || !declarations[0] || !declarations[0].init) { + throw this.astErrorOutput('Unexpected expression', varDecNode); + } + const result = []; + const firstDeclaration = declarations[0]; + const init = firstDeclaration.init; + let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); + if (type === 'LiteralInteger') { + type = 'Number'; + } + const markupType = typeMap[type]; + if (!markupType) { + throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); + } + let dependencies = this.getDependencies(firstDeclaration.init); + throw new Error('remove me'); + this.declarations[firstDeclaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: dependencies.every(dependency => dependency.isSafe) + }); + const initResult = [`${type} user_${firstDeclaration.id.name}=`]; + this.astGeneric(init, initResult); + result.push(initResult.join('')); + for (let i = 1; i < declarations.length; i++) { + const declaration = declarations[i]; + dependencies = this.getDependencies(declaration); + throw new Error('Remove me'); + this.declarations[declaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: false + }); + this.astGeneric(declaration, result); + } + retArr.push(retArr, result.join(',')); + retArr.push(';'); + return retArr; + } + astVariableDeclarator(iVarDecNode, retArr) { + this.astGeneric(iVarDecNode.id, retArr); + if (iVarDecNode.init !== null) { + retArr.push('='); + this.astGeneric(iVarDecNode.init, retArr); + } + return retArr; + } + astThisExpression(ast, retArr) { + return retArr; + } + astSequenceExpression(sNode, retArr) { + for (let i = 0; i < sNode.expressions.length; i++) { + if (i > 0) { + retArr.push(','); } - if (this.isAstMathVariable(ast)) { - name = ast.property.name; + this.astGeneric(sNode.expressions, retArr); + } + return retArr; + } + astUnaryExpression(uNode, retArr) { + const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); + if (unaryResult) { + return retArr; + } + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } + return retArr; + } + checkAndUpconvertBitwiseUnary(uNode, retArr) {} + astUpdateExpression(uNode, retArr) { + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } + return retArr; + } + astLogicalExpression(logNode, retArr) { + retArr.push('('); + this.astGeneric(logNode.left, retArr); + retArr.push(logNode.operator); + this.astGeneric(logNode.right, retArr); + retArr.push(')'); + return retArr; + } + astMemberExpression(ast, retArr) { + return retArr; + } + astCallExpression(ast, retArr) { + return retArr; + } + astArrayExpression(ast, retArr) { + return retArr; + } + getMemberExpressionDetails(ast) { + if (ast.type !== 'MemberExpression') { + throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast); + } + let name = null; + let type = null; + const variableSignature = this.getVariableSignature(ast); + switch (variableSignature) { + case 'value': + return null; + case 'value.thread.value': + case 'this.thread.value': + case 'this.output.value': return { - name, - origin: 'Math', - type: 'Number', signature: variableSignature, + type: 'Integer', + name: ast.property.name }; - } - switch (ast.property.name) { - case 'r': - case 'g': - case 'b': - case 'a': - name = ast.object.name; - return { - name, - property: ast.property.name, - origin: 'user', - signature: variableSignature, - type: 'Number' - }; - default: - throw this.astErrorOutput('Unexpected expression', ast); - } - case 'this.constants.value': - if (typeof ast.property.name !== 'string') { + case 'value[]': + if (typeof ast.object.name !== 'string') { throw this.astErrorOutput('Unexpected expression', ast); } - name = ast.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } + name = ast.object.name; return { name, - type, - origin: 'constants', + origin: 'user', signature: variableSignature, + type: this.getVariableType(ast.object), + xProperty: ast.property }; - case 'this.constants.value[]': - if (typeof ast.object.property.name !== 'string') { + case 'value[][]': + if (typeof ast.object.object.name !== 'string') { throw this.astErrorOutput('Unexpected expression', ast); } - name = ast.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } + name = ast.object.object.name; return { name, - type, - origin: 'constants', + origin: 'user', signature: variableSignature, + type: this.getVariableType(ast.object.object), + yProperty: ast.object.property, xProperty: ast.property, }; - case 'this.constants.value[][]': { - if (typeof ast.object.object.property.name !== 'string') { + case 'value[][][]': + if (typeof ast.object.object.object.name !== 'string') { throw this.astErrorOutput('Unexpected expression', ast); } - name = ast.object.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } + name = ast.object.object.object.name; return { name, - type, - origin: 'constants', - signature: variableSignature, - yProperty: ast.object.property, - xProperty: ast.property, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, }; - } - case 'this.constants.value[][][]': { - if (typeof ast.object.object.object.property.name !== 'string') { + case 'value[][][][]': + if (typeof ast.object.object.object.object.name !== 'string') { throw this.astErrorOutput('Unexpected expression', ast); } - name = ast.object.object.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } + name = ast.object.object.object.object.name; return { name, - type, - origin: 'constants', - signature: variableSignature, - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - } - case 'fn()[]': - case '[][]': - return { - signature: variableSignature, - property: ast.property, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, }; - default: - throw this.astErrorOutput('Unexpected expression', ast); - } - } - - findIdentifierOrigin(astToFind) { - const stack = [this.ast]; - - while (stack.length > 0) { - const atNode = stack[0]; - if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) { - return atNode; + case 'value.value': + if (typeof ast.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + if (this.isAstMathVariable(ast)) { + name = ast.property.name; + return { + name, + origin: 'Math', + type: 'Number', + signature: variableSignature, + }; + } + switch (ast.property.name) { + case 'r': + case 'g': + case 'b': + case 'a': + name = ast.object.name; + return { + name, + property: ast.property.name, + origin: 'user', + signature: variableSignature, + type: 'Number' + }; + default: + throw this.astErrorOutput('Unexpected expression', ast); + } + case 'this.constants.value': + if (typeof ast.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + }; + case 'this.constants.value[]': + if (typeof ast.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + xProperty: ast.property, + }; + case 'this.constants.value[][]': { + if (typeof ast.object.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + yProperty: ast.object.property, + xProperty: ast.property, + }; + } + case 'this.constants.value[][][]': { + if (typeof ast.object.object.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, + }; + } + case 'fn()[]': + case '[][]': + return { + signature: variableSignature, + property: ast.property, + }; + default: + throw this.astErrorOutput('Unexpected expression', ast); } - stack.shift(); - if (atNode.argument) { - stack.push(atNode.argument); - } else if (atNode.body) { - stack.push(atNode.body); - } else if (atNode.declarations) { - stack.push(atNode.declarations); - } else if (Array.isArray(atNode)) { - for (let i = 0; i < atNode.length; i++) { - stack.push(atNode[i]); + } + findIdentifierOrigin(astToFind) { + const stack = [this.ast]; + while (stack.length > 0) { + const atNode = stack[0]; + if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) { + return atNode; + } + stack.shift(); + if (atNode.argument) { + stack.push(atNode.argument); + } else if (atNode.body) { + stack.push(atNode.body); + } else if (atNode.declarations) { + stack.push(atNode.declarations); + } else if (Array.isArray(atNode)) { + for (let i = 0; i < atNode.length; i++) { + stack.push(atNode[i]); + } } } + return null; } - return null; - } - - findLastReturn(ast) { - const stack = [ast || this.ast]; - - while (stack.length > 0) { - const atNode = stack.pop(); - if (atNode.type === 'ReturnStatement') { - return atNode; - } - if (atNode.type === 'FunctionDeclaration') { - continue; - } - if (atNode.argument) { - stack.push(atNode.argument); - } else if (atNode.body) { - stack.push(atNode.body); - } else if (atNode.declarations) { - stack.push(atNode.declarations); - } else if (Array.isArray(atNode)) { - for (let i = 0; i < atNode.length; i++) { - stack.push(atNode[i]); - } - } else if (atNode.consequent) { - stack.push(atNode.consequent); - } else if (atNode.cases) { - stack.push(atNode.cases); + findLastReturn(ast) { + const stack = [ast || this.ast]; + while (stack.length > 0) { + const atNode = stack.pop(); + if (atNode.type === 'ReturnStatement') { + return atNode; + } + if (atNode.type === 'FunctionDeclaration') { + continue; + } + if (atNode.argument) { + stack.push(atNode.argument); + } else if (atNode.body) { + stack.push(atNode.body); + } else if (atNode.declarations) { + stack.push(atNode.declarations); + } else if (Array.isArray(atNode)) { + for (let i = 0; i < atNode.length; i++) { + stack.push(atNode[i]); + } + } else if (atNode.consequent) { + stack.push(atNode.consequent); + } else if (atNode.cases) { + stack.push(atNode.cases); + } } + return null; } - return null; - } - - getInternalVariableName(name) { - if (!this._internalVariableNames.hasOwnProperty(name)) { - this._internalVariableNames[name] = 0; - } - this._internalVariableNames[name]++; - if (this._internalVariableNames[name] === 1) { - return name; - } - return name + this._internalVariableNames[name]; - } - - varWarn() { - console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); - } -} - -const typeLookupMap = { - 'Number': 'Number', - 'Float': 'Float', - 'Integer': 'Integer', - 'Array': 'Number', - 'Array(2)': 'Number', - 'Array(3)': 'Number', - 'Array(4)': 'Number', - 'Array2D': 'Number', - 'Array3D': 'Number', - 'Input': 'Number', - 'HTMLImage': 'Array(4)', - 'HTMLVideo': 'Array(4)', - 'HTMLImageArray': 'Array(4)', - 'NumberTexture': 'Number', - 'MemoryOptimizedNumberTexture': 'Number', - 'Array1D(2)': 'Array(2)', - 'Array1D(3)': 'Array(3)', - 'Array1D(4)': 'Array(4)', - 'Array2D(2)': 'Array(2)', - 'Array2D(3)': 'Array(3)', - 'Array2D(4)': 'Array(4)', - 'Array3D(2)': 'Array(2)', - 'Array3D(3)': 'Array(3)', - 'Array3D(4)': 'Array(4)', - 'ArrayTexture(1)': 'Number', - 'ArrayTexture(2)': 'Array(2)', - 'ArrayTexture(3)': 'Array(3)', - 'ArrayTexture(4)': 'Array(4)', -}; - -module.exports = { - FunctionNode -}; -},{"../utils":112,"./function-tracer":11,"acorn":1}],11:[function(require,module,exports){ -class FunctionTracer { - constructor(ast) { - this.runningContexts = []; - this.contexts = []; - this.functionCalls = []; - this.declarations = []; - this.identifiers = []; - this.functions = []; - this.returnStatements = []; - this.inLoopInit = false; - this.scan(ast); - } - - get currentContext() { - return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; - } - - newContext(run) { - const newContext = Object.assign({}, this.currentContext); - this.contexts.push(newContext); - this.runningContexts.push(newContext); - run(); - this.runningContexts.pop(); - } - - scan(ast) { - if (!ast) return; - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.scan(ast[i]); - } - return; - } - switch (ast.type) { - case 'Program': - this.scan(ast.body); - break; - case 'BlockStatement': - this.newContext(() => { - this.scan(ast.body); - }); - break; - case 'AssignmentExpression': - case 'LogicalExpression': - this.scan(ast.left); - this.scan(ast.right); - break; - case 'BinaryExpression': - this.scan(ast.left); - this.scan(ast.right); - break; - case 'UpdateExpression': - case 'UnaryExpression': - this.scan(ast.argument); - break; - case 'VariableDeclaration': - this.scan(ast.declarations); - break; - case 'VariableDeclarator': - const { currentContext } = this; - const declaration = { - ast: ast, - context: currentContext, - name: ast.id.name, - origin: 'declaration', - forceInteger: this.inLoopInit, - assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name), - }; - currentContext[ast.id.name] = declaration; - this.declarations.push(declaration); - this.scan(ast.id); - this.scan(ast.init); - break; - case 'FunctionExpression': - case 'FunctionDeclaration': - if (this.runningContexts.length === 0) { - this.scan(ast.body); - } else { - this.functions.push(ast); - } - break; - case 'IfStatement': - this.scan(ast.test); - this.scan(ast.consequent); - if (ast.alternate) this.scan(ast.alternate); - break; - case 'ForStatement': - this.newContext(() => { - this.inLoopInit = true; - this.scan(ast.init); - this.inLoopInit = false; - this.scan(ast.test); - this.scan(ast.update); - this.newContext(() => { - this.scan(ast.body); - }); - }); - break; - case 'DoWhileStatement': - case 'WhileStatement': - this.newContext(() => { - this.scan(ast.body); - this.scan(ast.test); - }); - break; - case 'Identifier': - this.identifiers.push({ - context: this.currentContext, - ast, - }); - break; - case 'ReturnStatement': - this.returnStatements.push(ast); - this.scan(ast.argument); - break; - case 'MemberExpression': - this.scan(ast.object); - this.scan(ast.property); - break; - case 'ExpressionStatement': - this.scan(ast.expression); - break; - case 'CallExpression': - this.functionCalls.push({ - context: this.currentContext, - ast, - }); - this.scan(ast.arguments); - break; - case 'ArrayExpression': - this.scan(ast.elements); - break; - case 'ConditionalExpression': - this.scan(ast.test); - this.scan(ast.alternate); - this.scan(ast.consequent); - break; - case 'SwitchStatement': - this.scan(ast.discriminant); - this.scan(ast.cases); - break; - case 'SwitchCase': - this.scan(ast.test); - this.scan(ast.consequent); - break; - - case 'ThisExpression': - case 'Literal': - case 'DebuggerStatement': - case 'EmptyStatement': - case 'BreakStatement': - case 'ContinueStatement': - break; - - default: - throw new Error(`unhandled type "${ast.type}"`); - } - } -} - -module.exports = { - FunctionTracer, -}; -},{}],12:[function(require,module,exports){ -const { glWiretap } = require('gl-wiretap'); -const { utils } = require('../../utils'); - -function toStringWithoutUtils(fn) { - return fn.toString() - .replace('=>', '') - .replace(/^function /, '') - .replace(/utils[.]/g, '/*utils.*/'); -} + getInternalVariableName(name) { + if (!this._internalVariableNames.hasOwnProperty(name)) { + this._internalVariableNames[name] = 0; + } + this._internalVariableNames[name]++; + if (this._internalVariableNames[name] === 1) { + return name; + } + return name + this._internalVariableNames[name]; + } + varWarn() { + console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); + } + } + const typeLookupMap = { + 'Number': 'Number', + 'Float': 'Float', + 'Integer': 'Integer', + 'Array': 'Number', + 'Array(2)': 'Number', + 'Array(3)': 'Number', + 'Array(4)': 'Number', + 'Array2D': 'Number', + 'Array3D': 'Number', + 'Input': 'Number', + 'HTMLImage': 'Array(4)', + 'HTMLVideo': 'Array(4)', + 'HTMLImageArray': 'Array(4)', + 'NumberTexture': 'Number', + 'MemoryOptimizedNumberTexture': 'Number', + 'Array1D(2)': 'Array(2)', + 'Array1D(3)': 'Array(3)', + 'Array1D(4)': 'Array(4)', + 'Array2D(2)': 'Array(2)', + 'Array2D(3)': 'Array(3)', + 'Array2D(4)': 'Array(4)', + 'Array3D(2)': 'Array(2)', + 'Array3D(3)': 'Array(3)', + 'Array3D(4)': 'Array(4)', + 'ArrayTexture(1)': 'Number', + 'ArrayTexture(2)': 'Array(2)', + 'ArrayTexture(3)': 'Array(3)', + 'ArrayTexture(4)': 'Array(4)', + }; -function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { - args = args ? Array.from(args).map(arg => { - switch (typeof arg) { - case 'boolean': - return new Boolean(arg); - case 'number': - return new Number(arg); - default: - return arg; - } - }) : null; - const uploadedValues = []; - const postResult = []; - const context = glWiretap(originKernel.context, { - useTrackablePrimitives: true, - onReadPixels: (targetName) => { - if (kernel.subKernels) { - if (!subKernelsResultVariableSetup) { - postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`); - subKernelsResultVariableSetup = true; - } else { - const property = kernel.subKernels[subKernelsResultIndex++].property; - postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`); - } - if (subKernelsResultIndex === kernel.subKernels.length) { - postResult.push(' return result;'); + class CPUFunctionNode extends FunctionNode { + astFunction(ast, retArr) { + if (!this.isRootKernel) { + retArr.push('function'); + retArr.push(' '); + retArr.push(this.name); + retArr.push('('); + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + if (i > 0) { + retArr.push(', '); + } + retArr.push('user_'); + retArr.push(argumentName); } - return; + retArr.push(') {\n'); } - if (targetName) { - postResult.push(` return ${getRenderString(targetName, kernel)};`); - } else { - postResult.push(` return null;`); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); } - }, - onUnrecognizedArgumentLookup: (argument) => { - const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues); - if (argumentName) { - return argumentName; + if (!this.isRootKernel) { + retArr.push('}\n'); } - const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues); - if (constantName) { - return constantName; + return retArr; + } + astReturnStatement(ast, retArr) { + const type = this.returnType || this.getType(ast.argument); + if (!this.returnType) { + this.returnType = type; } - return null; + if (this.isRootKernel) { + retArr.push(this.leadingReturnStatement); + this.astGeneric(ast.argument, retArr); + retArr.push(';\n'); + retArr.push(this.followingReturnStatement); + retArr.push('continue;\n'); + } else if (this.isSubKernel) { + retArr.push(`subKernelResult_${ this.name } = `); + this.astGeneric(ast.argument, retArr); + retArr.push(';'); + retArr.push(`return subKernelResult_${ this.name };`); + } else { + retArr.push('return '); + this.astGeneric(ast.argument, retArr); + retArr.push(';'); + } + return retArr; } - }); - let subKernelsResultVariableSetup = false; - let subKernelsResultIndex = 0; - const { - source, - canvas, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - kernelArguments, - kernelConstants, - } = originKernel; - const kernel = new Kernel(source, { - canvas, - context, - checkContext: false, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - }); - let result = []; - context.setIndent(2); - kernel.build.apply(kernel, args); - result.push(context.toString()); - context.reset(); - - kernel.kernelArguments.forEach((kernelArgument, i) => { - switch (kernelArgument.type) { - case 'Integer': - case 'Boolean': - case 'Number': - case 'Float': - case 'Array': - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - case 'HTMLImage': - case 'HTMLVideo': - context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); - break; - case 'HTMLImageArray': - for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) { - const arg = args[i]; - context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]); - } - break; - case 'Input': - context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); - break; - case 'MemoryOptimizedNumberTexture': - case 'NumberTexture': - case 'Array1D(2)': - case 'Array1D(3)': - case 'Array1D(4)': - case 'Array2D(2)': - case 'Array2D(3)': - case 'Array2D(4)': - case 'Array3D(2)': - case 'Array3D(3)': - case 'Array3D(4)': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture); - break; - default: - throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`); + astLiteral(ast, retArr) { + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + retArr.push(ast.value); + return retArr; } - }); - result.push('/** start of injected functions **/'); - result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.isArray)}`); - if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) { - result.push( - ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};` - ); - } - result.push('/** end of injected functions **/'); - result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`); - context.setIndent(4); - kernel.run.apply(kernel, args); - if (kernel.renderKernels) { - kernel.renderKernels(); - } else if (kernel.renderOutput) { - kernel.renderOutput(); - } - result.push(' /** start setup uploads for kernel values **/'); - kernel.kernelArguments.forEach(kernelArgument => { - result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n ')); - }); - result.push(' /** end setup uploads for kernel values **/'); - result.push(context.toString()); - if (kernel.renderOutput === kernel.renderTexture) { - context.reset(); - const results = kernel.renderKernels(); - const textureName = context.getContextVariableName(kernel.outputTexture); - result.push(` return { - result: { - texture: ${ textureName }, - type: '${ results.result.type }', - toArray: ${ getToArrayString(results.result, textureName) } - },`); - const { subKernels, subKernelOutputTextures } = kernel; - for (let i = 0; i < subKernels.length; i++) { - const texture = subKernelOutputTextures[i]; - const subKernel = subKernels[i]; - const subKernelResult = results[subKernel.property]; - const subKernelTextureName = context.getContextVariableName(texture); - result.push(` - ${subKernel.property}: { - texture: ${ subKernelTextureName }, - type: '${ subKernelResult.type }', - toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } - },`); + astBinaryExpression(ast, retArr) { + retArr.push('('); + this.astGeneric(ast.left, retArr); + retArr.push(ast.operator); + this.astGeneric(ast.right, retArr); + retArr.push(')'); + return retArr; } - result.push(` };`); - } - result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`); - result.push(postResult.join('\n')); - result.push(' };'); - if (kernel.graphical) { - result.push(getGetPixelsString(kernel)); - result.push(` innerKernel.getPixels = getPixels;`); - } - result.push(' return innerKernel;'); - - let constantsUpload = []; - kernelConstants.forEach((kernelConstant) => { - constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`); - }); - return `function kernel(settings) { - const { context, constants } = settings; - ${constantsUpload.join('')} - ${setupContextString ? setupContextString : ''} -${result.join('\n')} -}`; -} - -function getRenderString(targetName, kernel) { - const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`; - if (kernel.output[2]) { - return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`; - } - if (kernel.output[1]) { - return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`; - } - - return `renderOutput(${readBackValue}, ${kernel.output[0]})`; -} - -function getGetPixelsString(kernel) { - const getPixels = kernel.getPixels.toString(); - const useFunctionKeyword = !/^function/.test(getPixels); - return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, { - findDependency: (object, name) => { - if (object === 'utils') { - return `const ${name} = ${utils[name].toString()};`; - } - return null; - }, - thisLookup: (property) => { - if (property === 'context') { - return null; + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); } - if (kernel.hasOwnProperty(property)) { - return JSON.stringify(kernel[property]); + switch (idtNode.name) { + case 'Infinity': + retArr.push('Infinity'); + break; + default: + if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { + retArr.push('constants_' + idtNode.name); + } else { + retArr.push('user_' + idtNode.name); + } } - throw new Error(`unhandled thisLookup ${ property }`); + return retArr; } - }); -} - -function getToArrayString(kernelResult, textureName) { - const toArray = kernelResult.toArray.toString(); - const useFunctionKeyword = !/^function/.test(toArray); - const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, { - findDependency: (object, name) => { - if (object === 'utils') { - return `const ${name} = ${utils[name].toString()};`; - } else if (object === 'this') { - return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + astForStatement(forNode, retArr) { + if (forNode.type !== 'ForStatement') { + throw this.astErrorOutput('Invalid for statement', forNode); + } + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + if (forNode.init) { + this.pushState('in-for-loop-init'); + this.astGeneric(forNode.init, initArr); + for (let i = 0; i < initArr.length; i++) { + if (initArr[i].includes && initArr[i].includes(',')) { + isSafe = false; + } + } + this.popState('in-for-loop-init'); } else { - throw new Error('unhandled fromObject'); + isSafe = false; } - }, - thisLookup: (property) => { - if (property === 'texture') { - return textureName; + if (forNode.test) { + this.astGeneric(forNode.test, testArr); + } else { + isSafe = false; } - if (kernelResult.hasOwnProperty(property)) { - return JSON.stringify(kernelResult[property]); + if (forNode.update) { + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; } - throw new Error(`unhandled thisLookup ${ property }`); - } - }); - return `() => { - ${flattenedFunctions} - return toArray(); - }`; -} - -function findKernelValue(argument, kernelValues, values, context, uploadedValues) { - if (argument === null) return null; - switch (typeof argument) { - case 'boolean': - case 'number': - return null; - } - if ( - typeof HTMLImageElement !== 'undefined' && - argument instanceof HTMLImageElement - ) { - for (let i = 0; i < kernelValues.length; i++) { - const kernelValue = kernelValues[i]; - if (kernelValue.type !== 'HTMLImageArray') continue; - if (kernelValue.uploadValue !== argument) continue; - const variableIndex = values[i].indexOf(argument); - if (variableIndex === -1) continue; - const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`; - context.insertVariable(variableName, argument); - return variableName; - } - return null; - } - - for (let i = 0; i < kernelValues.length; i++) { - const kernelValue = kernelValues[i]; - if (argument !== kernelValue.uploadValue) continue; - const variable = `uploadValue_${kernelValue.name}`; - context.insertVariable(variable, kernelValue); - return variable; - } - return null; -} - -module.exports = { - glKernelString -}; -},{"../../utils":112,"gl-wiretap":3}],13:[function(require,module,exports){ -const { Kernel } = require('../kernel'); -const { Texture } = require('../../texture'); -const { utils } = require('../../utils'); -const { GLTextureArray2Float } = require('./texture/array-2-float'); -const { GLTextureArray2Float2D } = require('./texture/array-2-float-2d'); -const { GLTextureArray2Float3D } = require('./texture/array-2-float-3d'); -const { GLTextureArray3Float } = require('./texture/array-3-float'); -const { GLTextureArray3Float2D } = require('./texture/array-3-float-2d'); -const { GLTextureArray3Float3D } = require('./texture/array-3-float-3d'); -const { GLTextureArray4Float } = require('./texture/array-4-float'); -const { GLTextureArray4Float2D } = require('./texture/array-4-float-2d'); -const { GLTextureArray4Float3D } = require('./texture/array-4-float-3d'); -const { GLTextureFloat } = require('./texture/float'); -const { GLTextureFloat2D } = require('./texture/float-2d'); -const { GLTextureFloat3D } = require('./texture/float-3d'); -const { GLTextureMemoryOptimized } = require('./texture/memory-optimized'); -const { GLTextureMemoryOptimized2D } = require('./texture/memory-optimized-2d'); -const { GLTextureMemoryOptimized3D } = require('./texture/memory-optimized-3d'); -const { GLTextureUnsigned } = require('./texture/unsigned'); -const { GLTextureUnsigned2D } = require('./texture/unsigned-2d'); -const { GLTextureUnsigned3D } = require('./texture/unsigned-3d'); -const { GLTextureGraphical } = require('./texture/graphical'); - -class GLKernel extends Kernel { - static get mode() { - return 'gpu'; - } - - static getIsFloatRead() { - const kernelString = `function kernelFunction() { - return 1; - }`; - const kernel = new this(kernelString, { - context: this.testContext, - canvas: this.testCanvas, - validate: false, - output: [1], - precision: 'single', - returnType: 'Number', - tactic: 'speed', - }); - kernel.build(); - kernel.run(); - const result = kernel.renderOutput(); - kernel.destroy(true); - return result[0] === 1; - } - - static getIsIntegerDivisionAccurate() { - function kernelFunction(v1, v2) { - return v1[this.thread.x] / v2[this.thread.x]; - } - const kernel = new this(kernelFunction.toString(), { - context: this.testContext, - canvas: this.testCanvas, - validate: false, - output: [2], - returnType: 'Number', - precision: 'unsigned', - tactic: 'speed', - }); - const args = [ - [6, 6030401], - [3, 3991] - ]; - kernel.build.apply(kernel, args); - kernel.run.apply(kernel, args); - const result = kernel.renderOutput(); - kernel.destroy(true); - return result[0] === 2 && result[1] === 1511; - } - - static get testCanvas() { - throw new Error(`"testCanvas" not defined on ${ this.name }`); - } - - static get testContext() { - throw new Error(`"testContext" not defined on ${ this.name }`); - } - - static get features() { - throw new Error(`"features" not defined on ${ this.name }`); - } - - static setupFeatureChecks() { - throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); - } - - setFixIntegerDivisionAccuracy(fix) { - this.fixIntegerDivisionAccuracy = fix; - return this; - } - - setPrecision(flag) { - this.precision = flag; - return this; - } - - setFloatTextures(flag) { - utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory'); - this.floatTextures = flag; - return this; - } - - static nativeFunctionArguments(source) { - const argumentTypes = []; - const argumentNames = []; - const states = []; - const isStartingVariableName = /^[a-zA-Z_]/; - const isVariableChar = /[a-zA-Z_0-9]/; - let i = 0; - let argumentName = null; - let argumentType = null; - while (i < source.length) { - const char = source[i]; - const nextChar = source[i + 1]; - const state = states.length > 0 ? states[states.length - 1] : null; - - if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') { - states.push('MULTI_LINE_COMMENT'); - i += 2; - continue; - } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') { - states.pop(); - i += 2; - continue; + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); } - - else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') { - states.push('COMMENT'); - i += 2; - continue; - } else if (state === 'COMMENT' && char === '\n') { - states.pop(); - i++; - continue; + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); } - - else if (state === null && char === '(') { - states.push('FUNCTION_ARGUMENTS'); - i++; - continue; - } else if (state === 'FUNCTION_ARGUMENTS') { - if (char === ')') { - states.pop(); - break; + if (isSafe) { + retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); + retArr.push(bodyArr.join('')); + retArr.push('}\n'); + } else { + const iVariableName = this.getInternalVariableName('safeI'); + if (initArr.length > 0) { + retArr.push(initArr.join(''), ';\n'); } - if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'float'; - argumentName = ''; - i += 6; - continue; - } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'int'; - argumentName = ''; - i += 4; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec2'; - argumentName = ''; - i += 5; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec3'; - argumentName = ''; - i += 5; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec4'; - argumentName = ''; - i += 5; - continue; + retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) { + retArr.push(`if (!${testArr.join('')}) break;\n`); } + retArr.push(bodyArr.join('')); + retArr.push(`\n${updateArr.join('')};`); + retArr.push('}\n'); } - - else if (state === 'DECLARE_VARIABLE') { - if (argumentName === '') { - if (char === ' ') { - i++; - continue; - } - if (!isStartingVariableName.test(char)) { - throw new Error('variable name is not expected string'); - } - } - argumentName += char; - if (!isVariableChar.test(nextChar)) { - states.pop(); - argumentNames.push(argumentName); - argumentTypes.push(typeMap[argumentType]); - } + return retArr; + } + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput( + 'Invalid while statement', + whileNode + ); } - - i++; + retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); + retArr.push('if ('); + this.astGeneric(whileNode.test, retArr); + retArr.push(') {\n'); + this.astGeneric(whileNode.body, retArr); + retArr.push('} else {\n'); + retArr.push('break;\n'); + retArr.push('}\n'); + retArr.push('}\n'); + return retArr; } - if (states.length > 0) { - throw new Error('GLSL function was not parsable'); + astDoWhileStatement(doWhileNode, retArr) { + if (doWhileNode.type !== 'DoWhileStatement') { + throw this.astErrorOutput( + 'Invalid while statement', + doWhileNode + ); + } + retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); + this.astGeneric(doWhileNode.body, retArr); + retArr.push('if (!'); + this.astGeneric(doWhileNode.test, retArr); + retArr.push(') {\n'); + retArr.push('break;\n'); + retArr.push('}\n'); + retArr.push('}\n'); + return retArr; } - return { - argumentNames, - argumentTypes, - }; - } - - static nativeFunctionReturnType(source) { - return typeMap[source.match(/int|float|vec[2-4]/)[0]]; - } - - static combineKernels(combinedKernel, lastKernel) { - combinedKernel.apply(null, arguments); - const { - texSize, - context, - threadDim - } = lastKernel.texSize; - let result; - if (lastKernel.precision === 'single') { - const w = texSize[0]; - const h = Math.ceil(texSize[1] / 4); - result = new Float32Array(w * h * 4 * 4); - context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result); - } else { - const bytes = new Uint8Array(texSize[0] * texSize[1] * 4); - context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes); - result = new Float32Array(bytes.buffer); + astAssignmentExpression(assNode, retArr) { + const declaration = this.getDeclaration(assNode.left); + if (declaration && !declaration.assignable) { + throw new this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode); + } + this.astGeneric(assNode.left, retArr); + retArr.push(assNode.operator); + this.astGeneric(assNode.right, retArr); + return retArr; } - - result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]); - - if (lastKernel.output.length === 1) { - return result; - } else if (lastKernel.output.length === 2) { - return utils.splitArray(result, lastKernel.output[0]); - } else if (lastKernel.output.length === 3) { - const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); - return cube.map(function(x) { - return utils.splitArray(x, lastKernel.output[0]); - }); + astBlockStatement(bNode, retArr) { + if (this.isState('loop-body')) { + this.pushState('block-body'); + for (let i = 0; i < bNode.body.length; i++) { + this.astGeneric(bNode.body[i], retArr); + } + this.popState('block-body'); + } else { + retArr.push('{\n'); + for (let i = 0; i < bNode.body.length; i++) { + this.astGeneric(bNode.body[i], retArr); + } + retArr.push('}\n'); + } + return retArr; } - } - - constructor(source, settings) { - super(source, settings); - this.transferValues = null; - this.formatValues = null; - this.TextureConstructor = null; - this.renderOutput = null; - this.renderRawOutput = null; - this.texSize = null; - this.translatedSource = null; - this.renderStrategy = null; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - } - - checkTextureSize() { - const { features } = this.constructor; - if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) { - throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`); + astVariableDeclaration(varDecNode, retArr) { + if (varDecNode.kind === 'var' && this.warnVarUsage) { + this.varWarn(); + } + retArr.push(`${varDecNode.kind} `); + const { declarations } = varDecNode; + for (let i = 0; i < declarations.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(declarations[i], retArr); + } + if (!this.isState('in-for-loop-init')) { + retArr.push(';'); + } + return retArr; } - } - - translateSource() { - throw new Error(`"translateSource" not defined on ${this.constructor.name}`); - } - - pickRenderStrategy(args) { - if (this.graphical) { - this.renderRawOutput = this.readPackedPixelsToUint8Array; - this.transferValues = (pixels) => pixels; - this.TextureConstructor = GLTextureGraphical; - return null; + astIfStatement(ifNode, retArr) { + retArr.push('if ('); + this.astGeneric(ifNode.test, retArr); + retArr.push(')'); + if (ifNode.consequent.type === 'BlockStatement') { + this.astGeneric(ifNode.consequent, retArr); + } else { + retArr.push(' {\n'); + this.astGeneric(ifNode.consequent, retArr); + retArr.push('\n}\n'); + } + if (ifNode.alternate) { + retArr.push('else '); + if (ifNode.alternate.type === 'BlockStatement') { + this.astGeneric(ifNode.alternate, retArr); + } else { + retArr.push(' {\n'); + this.astGeneric(ifNode.alternate, retArr); + retArr.push('\n}\n'); + } + } + return retArr; } - if (this.precision === 'unsigned') { - this.renderRawOutput = this.readPackedPixelsToUint8Array; - this.transferValues = this.readPackedPixelsToFloat32Array; - if (this.pipeline) { - this.renderOutput = this.renderTexture; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToTextures; + astSwitchStatement(ast, retArr) { + const { discriminant, cases } = ast; + retArr.push('switch ('); + this.astGeneric(discriminant, retArr); + retArr.push(') {\n'); + for (let i = 0; i < cases.length; i++) { + if (cases[i].test === null) { + retArr.push('default:\n'); + this.astGeneric(cases[i].consequent, retArr); + if (cases[i].consequent && cases[i].consequent.length > 0) { + retArr.push('break;\n'); + } + continue; } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': + retArr.push('case '); + this.astGeneric(cases[i].test, retArr); + retArr.push(':\n'); + if (cases[i].consequent && cases[i].consequent.length > 0) { + this.astGeneric(cases[i].consequent, retArr); + retArr.push('break;\n'); + } + } + retArr.push('\n}'); + } + astThisExpression(tNode, retArr) { + retArr.push('_this'); + return retArr; + } + astMemberExpression(mNode, retArr) { + const { + signature, + type, + property, + xProperty, + yProperty, + zProperty, + name, + origin + } = this.getMemberExpressionDetails(mNode); + switch (signature) { + case 'this.thread.value': + retArr.push(`_this.thread.${ name }`); + return retArr; + case 'this.output.value': + switch (name) { + case 'x': + retArr.push('outputX'); + break; + case 'y': + retArr.push('outputY'); + break; + case 'z': + retArr.push('outputZ'); + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + return retArr; + case 'value': + throw this.astErrorOutput('Unexpected expression', mNode); + case 'value[]': + case 'value[][]': + case 'value[][][]': + case 'value.value': + if (origin === 'Math') { + retArr.push(Math[name]); + return retArr; + } + switch (property) { + case 'r': + retArr.push(`user_${ name }[0]`); + return retArr; + case 'g': + retArr.push(`user_${ name }[1]`); + return retArr; + case 'b': + retArr.push(`user_${ name }[2]`); + return retArr; + case 'a': + retArr.push(`user_${ name }[3]`); + return retArr; + } + break; + case 'this.constants.value': + case 'this.constants.value[]': + case 'this.constants.value[][]': + case 'this.constants.value[][][]': + break; + case 'fn()[]': + this.astGeneric(mNode.object, retArr); + retArr.push('['); + this.astGeneric(mNode.property, retArr); + retArr.push(']'); + return retArr; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + if (!mNode.computed) { + switch (type) { case 'Number': case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureUnsigned3D; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - return null; + case 'Float': + case 'Boolean': + retArr.push(`${origin}_${name}`); + return retArr; + } + } + const markupName = `${origin}_${name}`; + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + case 'HTMLImageArray': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'HTMLImage': + default: + let size; + let isInput; + if (origin === 'constants') { + const constant = this.constants[name]; + isInput = this.constantTypes[name] === 'Input'; + size = isInput ? constant.size : null; + } else { + isInput = this.isInput(name); + size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null; + } + retArr.push(`${ markupName }`); + if (zProperty && yProperty) { + if (isInput) { + retArr.push('[('); + this.astGeneric(zProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`); + this.astGeneric(yProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); + this.astGeneric(xProperty, retArr); + retArr.push(']'); } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - return null; + retArr.push('['); + this.astGeneric(zProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(yProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); } - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return this.requestFallback(args); - } - } else { - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToArrays; - } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - this.renderOutput = this.renderValues; - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureUnsigned3D; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - this.formatValues = utils.erect3DPackedFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - this.formatValues = utils.erect2DPackedFloat; - return null; + } else if (yProperty) { + if (isInput) { + retArr.push('[('); + this.astGeneric(yProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); + this.astGeneric(xProperty, retArr); + retArr.push(']'); } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - this.formatValues = utils.erectPackedFloat; - return null; + retArr.push('['); + this.astGeneric(yProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); } - - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return this.requestFallback(args); - } + } else if (typeof xProperty !== 'undefined') { + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } } - } else if (this.precision === 'single') { - this.renderRawOutput = this.readFloatPixelsToFloat32Array; - this.transferValues = this.readFloatPixelsToFloat32Array; - if (this.pipeline) { - this.renderStrategy = renderStrategy.FloatTexture; - this.renderOutput = this.renderTexture; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToTextures; - } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.optimizeFloatMemory) { - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - return null; - } - } else { - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureFloat3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - return null; - } - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - return null; - } - } + return retArr; + } + astCallExpression(ast, retArr) { + if (ast.type !== 'CallExpression') { + throw this.astErrorOutput('Unknown CallExpression', ast); } - this.renderOutput = this.renderValues; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToArrays; + let functionName = this.astMemberExpressionUnroll(ast.callee); + if (this.calledFunctions.indexOf(functionName) < 0) { + this.calledFunctions.push(functionName); } - if (this.optimizeFloatMemory) { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized3D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; - this.formatValues = utils.erectMemoryOptimized3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; - this.formatValues = utils.erectMemoryOptimized2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; - this.formatValues = utils.erectMemoryOptimizedFloat; - return null; - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } + const isMathFunction = this.isAstMathFunction(ast); + if (this.onFunctionCall) { + this.onFunctionCall(this.name, functionName, ast.arguments); + } + retArr.push(functionName); + retArr.push('('); + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + let argumentType = this.getType(argument); + if (!targetTypes[i]) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); } - } else { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureFloat3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; - this.formatValues = utils.erect3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; - this.formatValues = utils.erect2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - this.renderStrategy = renderStrategy.FloatPixelToFloat; - this.formatValues = utils.erectFloat; - return null; - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } + if (i > 0) { + retArr.push(', '); } + this.astGeneric(argument, retArr); } - } else { - throw new Error(`unhandled precision of "${this.precision}"`); + retArr.push(')'); + return retArr; } - - throw new Error(`unhandled return type "${this.returnType}"`); - } - - getKernelString() { - throw new Error(`abstract method call`); - } - - getMainResultTexture() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Integer': - case 'Number': - return this.getMainResultNumberTexture(); - case 'Array(2)': - return this.getMainResultArray2Texture(); - case 'Array(3)': - return this.getMainResultArray3Texture(); - case 'Array(4)': - return this.getMainResultArray4Texture(); - default: - throw new Error(`unhandled returnType type ${ this.returnType }`); + astArrayExpression(arrNode, retArr) { + const arrLen = arrNode.elements.length; + retArr.push('new Float32Array(['); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + this.astGeneric(subNode, retArr); + } + retArr.push('])'); + return retArr; } - } - - getMainResultKernelNumberTexture() { - throw new Error(`abstract method call`); - } - getMainResultSubKernelNumberTexture() { - throw new Error(`abstract method call`); - } - getMainResultKernelArray2Texture() { - throw new Error(`abstract method call`); - } - getMainResultSubKernelArray2Texture() { - throw new Error(`abstract method call`); - } - getMainResultKernelArray3Texture() { - throw new Error(`abstract method call`); - } - getMainResultSubKernelArray3Texture() { - throw new Error(`abstract method call`); - } - getMainResultKernelArray4Texture() { - throw new Error(`abstract method call`); - } - getMainResultSubKernelArray4Texture() { - throw new Error(`abstract method call`); - } - getMainResultGraphical() { - throw new Error(`abstract method call`); - } - getMainResultMemoryOptimizedFloats() { - throw new Error(`abstract method call`); - } - getMainResultPackedPixels() { - throw new Error(`abstract method call`); - } - - getMainResultString() { - if (this.graphical) { - return this.getMainResultGraphical(); - } else if (this.precision === 'single') { - if (this.optimizeFloatMemory) { - return this.getMainResultMemoryOptimizedFloats(); - } - return this.getMainResultTexture(); - } else { - return this.getMainResultPackedPixels(); + astDebuggerStatement(arrNode, retArr) { + retArr.push('debugger;'); + return retArr; } } - getMainResultNumberTexture() { - return utils.linesToString(this.getMainResultKernelNumberTexture()) + - utils.linesToString(this.getMainResultSubKernelNumberTexture()); - } - - getMainResultArray2Texture() { - return utils.linesToString(this.getMainResultKernelArray2Texture()) + - utils.linesToString(this.getMainResultSubKernelArray2Texture()); - } - - getMainResultArray3Texture() { - return utils.linesToString(this.getMainResultKernelArray3Texture()) + - utils.linesToString(this.getMainResultSubKernelArray3Texture()); - } - - getMainResultArray4Texture() { - return utils.linesToString(this.getMainResultKernelArray4Texture()) + - utils.linesToString(this.getMainResultSubKernelArray4Texture()); - } - - getFloatTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp float;\n'; - case 'performance': - return 'precision highp float;\n'; - case 'balanced': - default: - return 'precision mediump float;\n'; + function constantsToString(constants, types) { + const results = []; + for (const name in types) { + if (!types.hasOwnProperty(name)) continue; + const type = types[name]; + const constant = constants[name]; + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + results.push(`${name}:${constant}`); + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); + break; + } } + return `{ ${ results.join() } }`; } - - getIntTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp int;\n'; - case 'performance': - return 'precision highp int;\n'; - case 'balanced': - default: - return 'precision mediump int;\n'; + function cpuKernelString(cpuKernel, name) { + const header = []; + const thisProperties = []; + const beforeReturn = []; + const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString()); + header.push( + ' const { context, canvas, constants: incomingConstants } = settings;', + ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`, + ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`, + ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`, + ); + thisProperties.push( + ' constants: _constants,', + ' context,', + ' output,', + ' thread: {x: 0, y: 0, z: 0},', + ); + if (cpuKernel.graphical) { + header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`); + header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`); + const colorFn = utils$1.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), { + thisLookup: (propertyName) => { + switch (propertyName) { + case '_colorData': + return '_colorData'; + case '_imageData': + return '_imageData'; + case 'output': + return 'output'; + case 'thread': + return 'this.thread'; + } + return JSON.stringify(cpuKernel[propertyName]); + }, + findDependency: (object, name) => { + return null; + } + }); + const getPixelsFn = utils$1.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), { + thisLookup: (propertyName) => { + switch (propertyName) { + case '_colorData': + return '_colorData'; + case '_imageData': + return '_imageData'; + case 'output': + return 'output'; + case 'thread': + return 'this.thread'; + } + return JSON.stringify(cpuKernel[propertyName]); + }, + findDependency: () => { + return null; + } + }); + thisProperties.push( + ' _imageData,', + ' _colorData,', + ` color: ${colorFn},`, + ); + beforeReturn.push( + ` kernel.getPixels = ${getPixelsFn};` + ); } + const constantTypes = []; + const constantKeys = Object.keys(cpuKernel.constantTypes); + for (let i = 0; i < constantKeys.length; i++) { + constantTypes.push(cpuKernel.constantTypes[constantKeys]); + } + if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) { + const flattenedImageTo3DArray = utils$1.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), { + doNotDefine: ['canvas'], + findDependency: (object, name) => { + if (object === 'this') { + return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString(); + } + return null; + }, + thisLookup: (propertyName) => { + switch (propertyName) { + case 'canvas': + return; + case 'context': + return 'context'; + } + } + }); + beforeReturn.push(flattenedImageTo3DArray); + thisProperties.push(` _mediaTo2DArray,`); + thisProperties.push(` _imageTo3DArray,`); + } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) { + const flattenedImageTo2DArray = utils$1.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), { + findDependency: (object, name) => { + return null; + }, + thisLookup: (propertyName) => { + switch (propertyName) { + case 'canvas': + return 'settings.canvas'; + case 'context': + return 'settings.context'; + } + throw new Error('unhandled thisLookup'); + } + }); + beforeReturn.push(flattenedImageTo2DArray); + thisProperties.push(` _mediaTo2DArray,`); + } + return `function(settings) { +${ header.join('\n') } + for (const p in _constantTypes) { + if (!_constantTypes.hasOwnProperty(p)) continue; + const type = _constantTypes[p]; + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + if (incomingConstants.hasOwnProperty(p)) { + console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); + } + continue; + } + if (!incomingConstants.hasOwnProperty(p)) { + throw new Error('constant ' + p + ' not found'); + } + _constants[p] = incomingConstants[p]; + } + const kernel = (function() { +${cpuKernel._kernelString} + }) + .apply({ ${thisProperties.join('\n')} }); + ${ beforeReturn.join('\n') } + return kernel; +}`; } - getSampler2DTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2D;\n'; - case 'performance': - return 'precision highp sampler2D;\n'; - case 'balanced': - default: - return 'precision mediump sampler2D;\n'; + class CPUKernel extends Kernel { + static getFeatures() { + return this.features; } - } - - getSampler2DArrayTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2DArray;\n'; - case 'performance': - return 'precision highp sampler2DArray;\n'; - case 'balanced': - default: - return 'precision mediump sampler2DArray;\n'; + static get features() { + return Object.freeze({ + kernelMap: true, + isIntegerDivisionAccurate: true + }); } - } - - renderTexture() { - return new this.TextureConstructor({ - texture: this.outputTexture, - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - readPackedPixelsToUint8Array() { - if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"'); - const { - texSize, - context: gl - } = this; - const result = new Uint8Array(texSize[0] * texSize[1] * 4); - gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result); - return result; - } - - readPackedPixelsToFloat32Array() { - return new Float32Array(this.readPackedPixelsToUint8Array().buffer); - } - - readFloatPixelsToFloat32Array() { - if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); - const { - texSize, - context: gl - } = this; - const w = texSize[0]; - const h = texSize[1]; - const result = new Float32Array(w * h * 4); - gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); - return result; - } - - readMemoryOptimizedFloatPixelsToFloat32Array() { - if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); - const { - texSize, - context: gl - } = this; - const w = texSize[0]; - const h = texSize[1]; - const result = new Float32Array(w * h * 4); - gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); - return result; - } - - getPixels(flip) { - const { - context: gl, - output - } = this; - const [width, height] = output; - const pixels = new Uint8Array(width * height * 4); - gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer); - } - - renderKernelsToArrays() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }).toArray(); + static get isSupported() { + return true; } - return result; - } - - renderKernelsToTextures() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); + static isContextMatch(context) { + return false; } - return result; - } - - setOutput(output) { - super.setOutput(output); - if (this.program) { - this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - const { context: gl } = this; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - this.updateMaxTexSize(); - this.framebuffer.width = this.texSize[0]; - this.framebuffer.height = this.texSize[1]; - this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - this.canvas.width = this.maxTexSize[0]; - this.canvas.height = this.maxTexSize[1]; - this._setupOutputTexture(); - if (this.subKernels && this.subKernels.length > 0) { - this._setupSubOutputTextures(); + static get mode() { + return 'cpu'; + } + static nativeFunctionArguments() { + return null; + } + static nativeFunctionReturnType() { + return null; + } + static combineKernels(combinedKernel) { + return combinedKernel; + } + constructor(source, settings) { + super(source, settings); + this.mergeSettings(source.settings || settings); + this._imageData = null; + this._colorData = null; + this._kernelString = null; + this.thread = { + x: 0, + y: 0, + z: 0 + }; + this.translatedSources = null; + } + initCanvas() { + if (typeof document !== 'undefined') { + return document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + return new OffscreenCanvas(0, 0); } } - return this; - } - renderValues() { - return this.formatValues( - this.transferValues(), - this.output[0], - this.output[1], - this.output[2] - ); - } -} - -const renderStrategy = Object.freeze({ - PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), - PackedPixelToFloat: Symbol('PackedPixelToFloat'), - PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), - PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), - PackedTexture: Symbol('PackedTexture'), - FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), - FloatPixelToFloat: Symbol('FloatPixelToFloat'), - FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), - FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), - FloatPixelToArray2: Symbol('FloatPixelToArray2'), - FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), - FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), - FloatPixelToArray3: Symbol('FloatPixelToArray3'), - FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), - FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), - FloatPixelToArray4: Symbol('FloatPixelToArray4'), - FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), - FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), - FloatTexture: Symbol('FloatTexture'), - MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), -}); - -const typeMap = { - int: 'Integer', - float: 'Number', - vec2: 'Array(2)', - vec3: 'Array(3)', - vec4: 'Array(4)', -}; - -module.exports = { - GLKernel, - renderStrategy -}; -},{"../../texture":111,"../../utils":112,"../kernel":35,"./texture/array-2-float":16,"./texture/array-2-float-2d":14,"./texture/array-2-float-3d":15,"./texture/array-3-float":19,"./texture/array-3-float-2d":17,"./texture/array-3-float-3d":18,"./texture/array-4-float":22,"./texture/array-4-float-2d":20,"./texture/array-4-float-3d":21,"./texture/float":25,"./texture/float-2d":23,"./texture/float-3d":24,"./texture/graphical":26,"./texture/memory-optimized":29,"./texture/memory-optimized-2d":27,"./texture/memory-optimized-3d":28,"./texture/unsigned":32,"./texture/unsigned-2d":30,"./texture/unsigned-3d":31}],14:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray2Float2D -}; -},{"../../../utils":112,"./float":25}],15:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray2Float3D -}; -},{"../../../utils":112,"./float":25}],16:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray2Float -}; -},{"../../../utils":112,"./float":25}],17:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray3Float2D -}; -},{"../../../utils":112,"./float":25}],18:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray3Float3D -}; -},{"../../../utils":112,"./float":25}],19:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erectArray3(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureArray3Float -}; -},{"../../../utils":112,"./float":25}],20:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray4Float2D -}; -},{"../../../utils":112,"./float":25}],21:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray4Float3D -}; -},{"../../../utils":112,"./float":25}],22:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erectArray4(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureArray4Float -}; -},{"../../../utils":112,"./float":25}],23:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureFloat2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - toArray() { - return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureFloat2D -}; -},{"../../../utils":112,"./float":25}],24:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureFloat3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - toArray() { - return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureFloat3D -}; -},{"../../../utils":112,"./float":25}],25:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureFloat extends Texture { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Float32Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); - return result; - } - renderValues() { - return this.renderRawOutput(); - } - toArray() { - return utils.erectFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureFloat -}; -},{"../../../texture":111,"../../../utils":112}],26:[function(require,module,exports){ -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureGraphical extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return this.renderValues(); - } -} - -module.exports = { - GLTextureGraphical -}; -},{"./unsigned":32}],27:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureMemoryOptimized2D -}; -},{"../../../utils":112,"./float":25}],28:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureMemoryOptimized3D -}; -},{"../../../utils":112,"./float":25}],29:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureMemoryOptimized -}; -},{"../../../utils":112,"./float":25}],30:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureUnsigned2D extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - toArray() { - return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureUnsigned2D -}; -},{"../../../utils":112,"./unsigned":32}],31:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureUnsigned3D extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - toArray() { - return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureUnsigned3D -}; -},{"../../../utils":112,"./unsigned":32}],32:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureUnsigned extends Texture { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Uint8Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result); - return result; - } - renderValues() { - return new Float32Array(this.renderRawOutput().buffer); - } - toArray() { - return utils.erectPackedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureUnsigned -}; -},{"../../../texture":111,"../../../utils":112}],33:[function(require,module,exports){ -const getContext = require('gl'); -const { WebGLKernel } = require('../web-gl/kernel'); -const { glKernelString } = require('../gl/kernel-string'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; -let features = null; - -class HeadlessGLKernel extends WebGLKernel { - static get isSupported() { - if (isSupported !== null) return isSupported; - this.setupFeatureChecks(); - isSupported = testContext !== null; - return isSupported; - } - - static setupFeatureChecks() { - testCanvas = null; - testExtensions = null; - if (typeof getContext !== 'function') return; - try { - testContext = getContext(2, 2, { - preserveDrawingBuffer: true - }); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - STACKGL_resize_drawingbuffer: testContext.getExtension('STACKGL_resize_drawingbuffer'), - STACKGL_destroy_context: testContext.getExtension('STACKGL_destroy_context'), - OES_texture_float: testContext.getExtension('OES_texture_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), - }; - features = this.getFeatures(); - } catch (e) { - console.warn(e); + initContext() { + if (!this.canvas) return null; + return this.canvas.getContext('2d'); } - } - - static isContextMatch(context) { - try { - return context.getParameter(context.RENDERER) === 'ANGLE'; - } catch (e) { - return false; + initPlugins(settings) { + return []; + } + validateSettings(args) { + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + const argType = utils$1.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils$1.getDimensions(argType); + } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { + this.output = args[0].output; + } else { + throw new Error('Auto output not supported for input type: ' + argType); + } + } + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); + } + } + this.checkOutput(); + } + translateSource() { + this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = '; + if (this.subKernels) { + const followingReturnStatement = []; + for (let i = 0; i < this.subKernels.length; i++) { + const { + name + } = this.subKernels[i]; + followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`); + } + this.followingReturnStatement = followingReturnStatement.join(''); + } + const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); + this.translatedSources = functionBuilder.getPrototypes('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + } + build() { + this.setupConstants(); + this.setupArguments(arguments); + this.validateSettings(arguments); + this.translateSource(); + if (this.graphical) { + const { + canvas, + output + } = this; + if (!canvas) { + throw new Error('no canvas available for using graphical output'); + } + const width = output[0]; + const height = output[1] || 1; + canvas.width = width; + canvas.height = height; + this._imageData = this.context.createImageData(width, height); + this._colorData = new Uint8ClampedArray(width * height * 4); + } + const kernelString = this.getKernelString(); + this.kernelString = kernelString; + if (this.debug) { + console.log('Function output:'); + console.log(kernelString); + } + try { + this.run = new Function([], kernelString).bind(this)(); + } catch (e) { + console.error('An error occurred compiling the javascript: ', e); + } + } + color(r, g, b, a) { + if (typeof a === 'undefined') { + a = 1; + } + r = Math.floor(r * 255); + g = Math.floor(g * 255); + b = Math.floor(b * 255); + a = Math.floor(a * 255); + const width = this.output[0]; + const height = this.output[1]; + const x = this.thread.x; + const y = height - this.thread.y - 1; + const index = x + y * width; + this._colorData[index * 4 + 0] = r; + this._colorData[index * 4 + 1] = g; + this._colorData[index * 4 + 2] = b; + this._colorData[index * 4 + 3] = a; + } + getKernelString() { + if (this._kernelString !== null) return this._kernelString; + let kernelThreadString = null; + let { + translatedSources + } = this; + if (translatedSources.length > 1) { + translatedSources = translatedSources.filter(fn => { + if (/^function/.test(fn)) return fn; + kernelThreadString = fn; + return false; + }); + } else { + kernelThreadString = translatedSources.shift(); + } + return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() }; + ${ this.injectedNative || '' } + const _this = this; + ${ this._processConstants() } + return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { + ${ this._processArguments() } + ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) } + ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' } + };`; + } + toString() { + return cpuKernelString(this); + } + _getLoopMaxString() { + return ( + this.loopMaxIterations ? + ` ${ parseInt(this.loopMaxIterations) };` : + ' 1000;' + ); + } + _processConstants() { + if (!this.constants) return ''; + const result = []; + for (let p in this.constants) { + const type = this.constantTypes[p]; + switch (type) { + case 'HTMLImage': + case 'HTMLVideo': + result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`); + break; + case 'HTMLImageArray': + result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`); + break; + case 'Input': + result.push(` const constants_${p} = this.constants.${p}.value;\n`); + break; + default: + result.push(` const constants_${p} = this.constants.${p};\n`); + } + } + return result.join(''); + } + _processArguments() { + const result = []; + for (let i = 0; i < this.argumentTypes.length; i++) { + const variableName = `user_${this.argumentNames[i]}`; + switch (this.argumentTypes[i]) { + case 'HTMLImage': + case 'HTMLVideo': + result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`); + break; + case 'HTMLImageArray': + result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`); + break; + case 'Input': + result.push(` ${variableName} = ${variableName}.value;\n`); + break; + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'NumberTexture': + case 'MemoryOptimizedNumberTexture': + result.push(` + if (${variableName}.toArray) { + if (!_this.textureCache) { + _this.textureCache = []; + _this.arrayCache = []; + } + const textureIndex = _this.textureCache.indexOf(${variableName}); + if (textureIndex !== -1) { + ${variableName} = _this.arrayCache[textureIndex]; + } else { + _this.textureCache.push(${variableName}); + ${variableName} = ${variableName}.toArray(); + _this.arrayCache.push(${variableName}); + } + }`); + break; + } + } + return result.join(''); + } + _mediaTo2DArray(media) { + const canvas = this.canvas; + const width = media.width > 0 ? media.width : media.videoWidth; + const height = media.height > 0 ? media.height : media.videoHeight; + if (canvas.width < width) { + canvas.width = width; + } + if (canvas.height < height) { + canvas.height = height; + } + const ctx = this.context; + ctx.drawImage(media, 0, 0, width, height); + const pixelsData = ctx.getImageData(0, 0, width, height).data; + const imageArray = new Array(height); + let index = 0; + for (let y = height - 1; y >= 0; y--) { + const row = imageArray[y] = new Array(width); + for (let x = 0; x < width; x++) { + const pixel = new Float32Array(4); + pixel[0] = pixelsData[index++] / 255; + pixel[1] = pixelsData[index++] / 255; + pixel[2] = pixelsData[index++] / 255; + pixel[3] = pixelsData[index++] / 255; + row[x] = pixel; + } + } + return imageArray; + } + getPixels(flip) { + const [width, height] = this.output; + return flip ? utils$1.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0); + } + _imageTo3DArray(images) { + const imagesArray = new Array(images.length); + for (let i = 0; i < images.length; i++) { + imagesArray[i] = this._mediaTo2DArray(images[i]); + } + return imagesArray; + } + _resultKernelBody(kernelString) { + switch (this.output.length) { + case 1: + return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); + case 2: + return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); + case 3: + return this._resultKernel3DLoop(kernelString) + this._kernelOutput(); + default: + throw new Error('unsupported size kernel'); + } + } + _graphicalKernelBody(kernelThreadString) { + switch (this.output.length) { + case 2: + return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput(); + default: + throw new Error('unsupported size kernel'); + } + } + _graphicalOutput() { + return ` + this._imageData.data.set(this._colorData); + this.context.putImageData(this._imageData, 0, 0); + return;` + } + _getKernelResultTypeConstructorString() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return 'Float32Array'; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return 'Array'; + default: + if (this.graphical) { + return 'Float32Array'; + } + throw new Error(`unhandled returnType ${ this.returnType }`); + } + } + _resultKernel1DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const result = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + this.thread.y = 0; + this.thread.z = 0; + ${ kernelString } + }`; + } + _resultKernel2DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const result = new Array(outputY); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + const resultX = result[y] = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + }`; + } + _graphicalKernel2DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + }`; + } + _resultKernel3DLoop(kernelString) { + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const outputZ = _this.output[2]; + const result = new Array(outputZ); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let z = 0; z < outputZ; z++) { + this.thread.z = z; + const resultY = result[z] = new Array(outputY); + ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.y = y; + const resultX = resultY[y] = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + } + }`; + } + _kernelOutput() { + if (!this.subKernels) { + return '\n return result;'; + } + return `\n return { + result: result, + ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') } + };`; + } + _mapSubKernels(fn) { + return this.subKernels === null ? [''] : + this.subKernels.map(fn); + } + destroy(removeCanvasReference) { + if (removeCanvasReference) { + delete this.canvas; + } + } + static destroyContext(context) {} + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON(); + return json; + } + setOutput(output) { + super.setOutput(output); + const [width, height] = this.output; + if (this.graphical) { + this._imageData = this.context.createImageData(width, height); + this._colorData = new Uint8ClampedArray(width * height * 4); + } } } - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - static getIsTextureFloat() { - return Boolean(testExtensions.OES_texture_float); - } - - static getIsDrawBuffers() { - return Boolean(testExtensions.WEBGL_draw_buffers); - } - - static getChannelCount() { - return testExtensions.WEBGL_draw_buffers ? - testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : - 1; - } - - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); - } - - static get testCanvas() { - return testCanvas; - } - - static get testContext() { - return testContext; - } - - static get features() { - return features; + class GLTextureFloat extends Texture { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Float32Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); + return result; + } + renderValues() { + return this.renderRawOutput(); + } + toArray() { + return utils$1.erectFloat(this.renderValues(), this.output[0]); + } } - initCanvas() { - return {}; + class GLTextureArray2Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erectArray2(this.renderValues(), this.output[0], this.output[1]); + } } - initContext() { - const context = getContext(2, 2, { - preserveDrawingBuffer: true - }); - return context; + class GLTextureArray2Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); + } } - initExtensions() { - this.extensions = { - STACKGL_resize_drawingbuffer: this.context.getExtension('STACKGL_resize_drawingbuffer'), - STACKGL_destroy_context: this.context.getExtension('STACKGL_destroy_context'), - OES_texture_float: this.context.getExtension('OES_texture_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), - }; + class GLTextureArray2Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils$1.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - build() { - super.build.apply(this, arguments); - if (!this.fallbackRequested) { - this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); + class GLTextureArray3Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erectArray3(this.renderValues(), this.output[0]); } } - destroyExtensions() { - this.extensions.STACKGL_resize_drawingbuffer = null; - this.extensions.STACKGL_destroy_context = null; - this.extensions.OES_texture_float = null; - this.extensions.OES_texture_float_linear = null; - this.extensions.OES_element_index_uint = null; - this.extensions.WEBGL_draw_buffers = null; + class GLTextureArray3Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); + } } - static destroyContext(context) { - const extension = context.getExtension('STACKGL_destroy_context'); - if (extension && extension.destroy) { - extension.destroy(); + class GLTextureArray3Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils$1.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); } } - toString() { - const setupContextString = `const gl = context || require('gl')(1, 1);\n`; - const destroyContextString = ` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n`; - return glKernelString(this.constructor, arguments, this, setupContextString, destroyContextString); + class GLTextureArray4Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erectArray4(this.renderValues(), this.output[0]); + } } - setOutput(output) { - super.setOutput(output); - if (this.graphical && this.extensions.STACKGL_resize_drawingbuffer) { - this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); + class GLTextureArray4Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); } } -} -module.exports = { - HeadlessGLKernel -}; -},{"../gl/kernel-string":12,"../web-gl/kernel":68,"gl":2}],34:[function(require,module,exports){ -class KernelValue { - constructor(value, settings) { - const { - name, - kernel, - context, - checkContext, - onRequestContextHandle, - onUpdateValueMismatch, - origin, - strictIntegers, - type, - tactic, - } = settings; - if (!name) { - throw new Error('name not set'); + class GLTextureArray4Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils$1.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); } - if (!type) { - throw new Error('type not set'); - } - if (!origin) { - throw new Error('origin not set'); - } - if (!tactic) { - throw new Error('tactic not set'); - } - if (origin !== 'user' && origin !== 'constants') { - throw new Error(`origin must be "user" or "constants" value is "${ origin }"`); - } - if (!onRequestContextHandle) { - throw new Error('onRequestContextHandle is not set'); - } - this.name = name; - this.origin = origin; - this.tactic = tactic; - this.id = `${this.origin}_${name}`; - this.varName = origin === 'constants' ? `constants.${name}` : name; - this.kernel = kernel; - this.strictIntegers = strictIntegers; - this.type = value.type || type; - this.size = value.size || null; - this.index = null; - this.context = context; - this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true; - this.contextHandle = null; - this.onRequestContextHandle = onRequestContextHandle; - this.onUpdateValueMismatch = onUpdateValueMismatch; - this.forceUploadEachRun = null; } - getSource() { - throw new Error(`"getSource" not defined on ${ this.constructor.name }`); + class GLTextureFloat2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils$1.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); + } } - updateValue(value) { - throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); + class GLTextureFloat3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils$1.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } -} - -module.exports = { - KernelValue -}; -},{}],35:[function(require,module,exports){ -const { utils } = require('../utils'); -const { Input } = require('../input'); -class Kernel { - static get isSupported() { - throw new Error(`"isSupported" not implemented on ${ this.name }`); + class GLTextureMemoryOptimized extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); + } } - static isContextMatch(context) { - throw new Error(`"isContextMatch" not implemented on ${ this.name }`); + class GLTextureMemoryOptimized2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); + } } - static getFeatures() { - throw new Error(`"getFeatures" not implemented on ${ this.name }`); + class GLTextureMemoryOptimized3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils$1.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - static destroyContext(context) { - throw new Error(`"destroyContext" called on ${ this.name }`); + class GLTextureUnsigned extends Texture { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Uint8Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result); + return result; + } + renderValues() { + return new Float32Array(this.renderRawOutput().buffer); + } + toArray() { + return utils$1.erectPackedFloat(this.renderValues(), this.output[0]); + } } - static nativeFunctionArguments() { - throw new Error(`"nativeFunctionArguments" called on ${ this.name }`); + class GLTextureUnsigned2D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils$1.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); + } } - static nativeFunctionReturnType() { - throw new Error(`"nativeFunctionReturnType" called on ${ this.name }`); + class GLTextureUnsigned3D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils$1.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } } - static combineKernels() { - throw new Error(`"combineKernels" called on ${ this.name }`); + class GLTextureGraphical extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return this.renderValues(); + } } - constructor(source, settings) { - if (typeof source !== 'object') { - if (typeof source !== 'string') { - throw new Error('source not a string'); - } - if (!utils.isFunctionString(source)) { - throw new Error('source not a function string'); - } + class GLKernel extends Kernel { + static get mode() { + return 'gpu'; } - this.useLegacyEncoder = false; - this.fallbackRequested = false; - this.onRequestFallback = null; - - this.argumentNames = typeof source === 'string' ? utils.getArgumentNamesFromString(source) : null; - this.argumentTypes = null; - this.argumentSizes = null; - this.argumentBitRatios = null; - this.kernelArguments = null; - this.kernelConstants = null; - this.forceUploadKernelConstants = null; - - - this.source = source; - - this.output = null; - - this.debug = false; - - this.graphical = false; - - this.loopMaxIterations = 0; - - this.constants = null; - this.constantTypes = null; - this.constantBitRatios = null; - this.dynamicArguments = false; - this.dynamicOutput = false; - - this.canvas = null; - - this.context = null; - - this.checkContext = null; - - this.gpu = null; - - this.functions = null; - - this.nativeFunctions = null; - - this.injectedNative = null; - - this.subKernels = null; - - this.validate = true; - - this.immutable = false; - - this.pipeline = false; - - this.precision = null; - - this.tactic = 'balanced'; - - this.plugins = null; - - this.returnType = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.optimizeFloatMemory = null; - this.strictIntegers = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - } - - mergeSettings(settings) { - for (let p in settings) { - if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue; - switch (p) { - case 'output': - if (!Array.isArray(settings.output)) { - this.setOutput(settings.output); - continue; + static getIsFloatRead() { + const kernelString = `function kernelFunction() { + return 1; + }`; + const kernel = new this(kernelString, { + context: this.testContext, + canvas: this.testCanvas, + validate: false, + output: [1], + precision: 'single', + returnType: 'Number', + tactic: 'speed', + }); + kernel.build(); + kernel.run(); + const result = kernel.renderOutput(); + kernel.destroy(true); + return result[0] === 1; + } + static getIsIntegerDivisionAccurate() { + function kernelFunction(v1, v2) { + return v1[this.thread.x] / v2[this.thread.x]; + } + const kernel = new this(kernelFunction.toString(), { + context: this.testContext, + canvas: this.testCanvas, + validate: false, + output: [2], + returnType: 'Number', + precision: 'unsigned', + tactic: 'speed', + }); + const args = [ + [6, 6030401], + [3, 3991] + ]; + kernel.build.apply(kernel, args); + kernel.run.apply(kernel, args); + const result = kernel.renderOutput(); + kernel.destroy(true); + return result[0] === 2 && result[1] === 1511; + } + static get testCanvas() { + throw new Error(`"testCanvas" not defined on ${ this.name }`); + } + static get testContext() { + throw new Error(`"testContext" not defined on ${ this.name }`); + } + static get features() { + throw new Error(`"features" not defined on ${ this.name }`); + } + static setupFeatureChecks() { + throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); + } + setFixIntegerDivisionAccuracy(fix) { + this.fixIntegerDivisionAccuracy = fix; + return this; + } + setPrecision(flag) { + this.precision = flag; + return this; + } + setFloatTextures(flag) { + utils$1.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory'); + this.floatTextures = flag; + return this; + } + static nativeFunctionArguments(source) { + const argumentTypes = []; + const argumentNames = []; + const states = []; + const isStartingVariableName = /^[a-zA-Z_]/; + const isVariableChar = /[a-zA-Z_0-9]/; + let i = 0; + let argumentName = null; + let argumentType = null; + while (i < source.length) { + const char = source[i]; + const nextChar = source[i + 1]; + const state = states.length > 0 ? states[states.length - 1] : null; + if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') { + states.push('MULTI_LINE_COMMENT'); + i += 2; + continue; + } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') { + states.pop(); + i += 2; + continue; + } + else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') { + states.push('COMMENT'); + i += 2; + continue; + } else if (state === 'COMMENT' && char === '\n') { + states.pop(); + i++; + continue; + } + else if (state === null && char === '(') { + states.push('FUNCTION_ARGUMENTS'); + i++; + continue; + } else if (state === 'FUNCTION_ARGUMENTS') { + if (char === ')') { + states.pop(); + break; } - break; - case 'functions': - if (typeof settings.functions[0] === 'function') { - this.functions = settings.functions.map(source => utils.functionToIFunction(source)); + if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'float'; + argumentName = ''; + i += 6; + continue; + } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'int'; + argumentName = ''; + i += 4; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec2'; + argumentName = ''; + i += 5; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec3'; + argumentName = ''; + i += 5; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec4'; + argumentName = ''; + i += 5; continue; } - break; - case 'graphical': - if (settings[p] && !settings.hasOwnProperty('precision')) { - this.precision = 'unsigned'; + } + else if (state === 'DECLARE_VARIABLE') { + if (argumentName === '') { + if (char === ' ') { + i++; + continue; + } + if (!isStartingVariableName.test(char)) { + throw new Error('variable name is not expected string'); + } + } + argumentName += char; + if (!isVariableChar.test(nextChar)) { + states.pop(); + argumentNames.push(argumentName); + argumentTypes.push(typeMap$1[argumentType]); } - this[p] = settings[p]; - continue; - } - this[p] = settings[p]; - } - - if (!this.canvas) this.canvas = this.initCanvas(); - if (!this.context) this.context = this.initContext(); - if (!this.plugins) this.plugins = this.initPlugins(settings); - } - build() { - throw new Error(`"build" not defined on ${ this.constructor.name }`); - } - - run() { - throw new Error(`"run" not defined on ${ this.constructor.name }`) - } - - initCanvas() { - throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`); - } - - initContext() { - throw new Error(`"initContext" not defined on ${ this.constructor.name }`); - } - - initPlugins(settings) { - throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`); - } - - setupArguments(args) { - this.kernelArguments = []; - if (!this.argumentTypes) { - if (!this.argumentTypes) { - this.argumentTypes = []; - for (let i = 0; i < args.length; i++) { - const argType = utils.getVariableType(args[i], this.strictIntegers); - const type = argType === 'Integer' ? 'Number' : argType; - this.argumentTypes.push(type); - this.kernelArguments.push({ - type - }); } + i++; } - } else { - for (let i = 0; i < this.argumentTypes.length; i++) { - this.kernelArguments.push({ - type: this.argumentTypes[i] - }); + if (states.length > 0) { + throw new Error('GLSL function was not parsable'); } + return { + argumentNames, + argumentTypes, + }; } - - this.argumentSizes = new Array(args.length); - this.argumentBitRatios = new Int32Array(args.length); - - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - this.argumentSizes[i] = arg.constructor === Input ? arg.size : null; - this.argumentBitRatios[i] = this.getBitRatio(arg); - } - - if (this.argumentNames.length !== args.length) { - throw new Error(`arguments are miss-aligned`); - } - } - - setupConstants() { - this.kernelConstants = []; - let needsConstantTypes = this.constantTypes === null; - if (needsConstantTypes) { - this.constantTypes = {}; - } - this.constantBitRatios = {}; - if (this.constants) { - for (let name in this.constants) { - if (needsConstantTypes) { - const type = utils.getVariableType(this.constants[name], this.strictIntegers); - this.constantTypes[name] = type; - this.kernelConstants.push({ - name, - type - }); - } else { - this.kernelConstants.push({ - name, - type: this.constantTypes[name] - }); - } - this.constantBitRatios[name] = this.getBitRatio(this.constants[name]); - } + static nativeFunctionReturnType(source) { + return typeMap$1[source.match(/int|float|vec[2-4]/)[0]]; } - } - - setOptimizeFloatMemory(flag) { - this.optimizeFloatMemory = flag; - return this; - } - - setOutput(output) { - if (output.hasOwnProperty('x')) { - if (output.hasOwnProperty('y')) { - if (output.hasOwnProperty('z')) { - this.output = [output.x, output.y, output.z]; - } else { - this.output = [output.x, output.y]; - } + static combineKernels(combinedKernel, lastKernel) { + combinedKernel.apply(null, arguments); + const { + texSize, + context, + threadDim + } = lastKernel.texSize; + let result; + if (lastKernel.precision === 'single') { + const w = texSize[0]; + const h = Math.ceil(texSize[1] / 4); + result = new Float32Array(w * h * 4 * 4); + context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result); } else { - this.output = [output.x]; + const bytes = new Uint8Array(texSize[0] * texSize[1] * 4); + context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes); + result = new Float32Array(bytes.buffer); } - } else { - this.output = output; - } - return this; - } - - setDebug(flag) { - this.debug = flag; - return this; - } - - setGraphical(flag) { - this.graphical = flag; - this.precision = 'unsigned'; - return this; - } - - setLoopMaxIterations(max) { - this.loopMaxIterations = max; - return this; - } - - setConstants(constants) { - this.constants = constants; - return this; - } - - setConstantTypes(constantTypes) { - this.constantTypes = constantTypes; - return this; - } - - setFunctions(functions) { - if (typeof functions[0] === 'function') { - this.functions = functions.map(source => utils.functionToIFunction(source)); - } else { - this.functions = functions; - } - return this; - } - - setNativeFunctions(nativeFunctions) { - this.nativeFunctions = nativeFunctions; - return this; - } - - setInjectedNative(injectedNative) { - this.injectedNative = injectedNative; - return this; - } - - setPipeline(flag) { - this.pipeline = flag; - return this; - } - - setPrecision(flag) { - this.precision = flag; - return this; - } - - setOutputToTexture(flag) { - utils.warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); - this.pipeline = flag; - return this; - } - - setImmutable(flag) { - this.immutable = flag; - return this; - } - - setCanvas(canvas) { - this.canvas = canvas; - return this; - } - - setStrictIntegers(flag) { - this.strictIntegers = flag; - return this; - } - - setDynamicOutput(flag) { - this.dynamicOutput = flag; - return this; - } - - setHardcodeConstants(flag) { - utils.warnDeprecated('method', 'setHardcodeConstants'); - this.setDynamicOutput(flag); - this.setDynamicArguments(flag); - return this; - } - - setDynamicArguments(flag) { - this.dynamicArguments = flag; - return this; - } - - setUseLegacyEncoder(flag) { - this.useLegacyEncoder = flag; - return this; - } - - setWarnVarUsage(flag) { - this.warnVarUsage = flag; - return this; - } - - getCanvas() { - utils.warnDeprecated('method', 'getCanvas'); - return this.canvas; - } - - getWebGl() { - utils.warnDeprecated('method', 'getWebGl'); - return this.context; - } - - setContext(context) { - this.context = context; - return this; - } - - setArgumentTypes(argumentTypes) { - if (Array.isArray(argumentTypes)) { - this.argumentTypes = argumentTypes; - } else { - this.argumentTypes = []; - for (const p in argumentTypes) { - const argumentIndex = this.argumentNames.indexOf(p); - if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); - this.argumentTypes[argumentIndex] = argumentTypes[p]; + result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]); + if (lastKernel.output.length === 1) { + return result; + } else if (lastKernel.output.length === 2) { + return utils$1.splitArray(result, lastKernel.output[0]); + } else if (lastKernel.output.length === 3) { + const cube = utils$1.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); + return cube.map(function(x) { + return utils$1.splitArray(x, lastKernel.output[0]); + }); } } - return this; - } - - setTactic(tactic) { - this.tactic = tactic; - return this; - } - - requestFallback(args) { - if (!this.onRequestFallback) { - throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); - } - this.fallbackRequested = true; - return this.onRequestFallback(args); - } - - validateSettings() { - throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`); - } - - addSubKernel(subKernel) { - if (this.subKernels === null) { - this.subKernels = []; - } - if (!subKernel.source) throw new Error('subKernel missing "source" property'); - if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property'); - if (!subKernel.name) throw new Error('subKernel missing "name" property'); - this.subKernels.push(subKernel); - return this; - } - - destroy(removeCanvasReferences) { - throw new Error(`"destroy" called on ${ this.constructor.name }`); - } - - getBitRatio(value) { - if (this.precision === 'single') { - return 4; - } else if (Array.isArray(value[0])) { - return this.getBitRatio(value[0]); - } else if (value.constructor === Input) { - return this.getBitRatio(value.value); - } - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - return 1; - case Uint16Array: - case Int16Array: - return 2; - case Float32Array: - case Int32Array: - default: - return 4; - } - } - - getPixels() { - throw new Error(`"getPixels" called on ${ this.constructor.name }`); - } - - checkOutput() { - if (!this.output || !utils.isArray(this.output)) throw new Error('kernel.output not an array'); - if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value'); - for (let i = 0; i < this.output.length; i++) { - if (isNaN(this.output[i]) || this.output[i] < 1) { - throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`); + constructor(source, settings) { + super(source, settings); + this.transferValues = null; + this.formatValues = null; + this.TextureConstructor = null; + this.renderOutput = null; + this.renderRawOutput = null; + this.texSize = null; + this.translatedSource = null; + this.renderStrategy = null; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + } + checkTextureSize() { + const { features } = this.constructor; + if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) { + throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`); + } + } + translateSource() { + throw new Error(`"translateSource" not defined on ${this.constructor.name}`); + } + pickRenderStrategy(args) { + if (this.graphical) { + this.renderRawOutput = this.readPackedPixelsToUint8Array; + this.transferValues = (pixels) => pixels; + this.TextureConstructor = GLTextureGraphical; + return null; } - } - } - - toJSON() { - const settings = { - output: this.output, - threadDim: this.threadDim, - pipeline: this.pipeline, - argumentNames: this.argumentNames, - argumentsTypes: this.argumentTypes, - constants: this.constants, - pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null, - returnType: this.returnType, - }; - return { - settings - }; - } -} - -module.exports = { - Kernel -}; -},{"../input":108,"../utils":112}],36:[function(require,module,exports){ -const fragmentShader = `__HEADER__; -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -const int LOOP_MAX = __LOOP_MAX__; - -__PLUGINS__; -__CONSTANTS__; - -varying vec2 vTexCoord; - -vec4 round(vec4 x) { - return floor(x + 0.5); -} - -float round(float x) { - return floor(x + 0.5); -} - -const int BIT_COUNT = 32; -int modi(int x, int y) { - return x - y * (x / y); -} - -int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; -} -int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; -} -int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; - } - } - return result; -} -int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; -} -int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); -} - -int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); -} - -int integerMod(int x, int y) { - return x - (y * int(x / y)); -} - -__DIVIDE_WITH_INTEGER_CHECK__; - -// Here be dragons! -// DO NOT OPTIMIZE THIS CODE -// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE -// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME -const vec2 MAGIC_VEC = vec2(1.0, -256.0); -const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); -const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 -float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; -} - -float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; - if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; - return 0.0; -} - -float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - if (channel == 0) return texel.r * 255.0; - if (channel == 1) return texel.g * 255.0; - if (channel == 2) return texel.b * 255.0; - if (channel == 3) return texel.a * 255.0; - return 0.0; -} - -vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; -} - -// https://github.com/gpujs/gpu.js/wiki/Encoder-details -vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; -} -// Dragons end here - -int index; -ivec3 threadId; - -ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); -} - -float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return decode32(texel); -} - -float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); -} - -float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); -} - -float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return texel.r; - if (channel == 1) return texel.g; - if (channel == 2) return texel.b; - if (channel == 3) return texel.a; - return 0.0; -} - -vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture2D(tex, st / vec2(texSize)); -} - -float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; -} - -vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); -} - -vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); -} - -vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); -} - -vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); - } - } -} - -vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); -} - -vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); -} - -vec4 actualColor; -void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); -} - -void color(float r, float g, float b) { - color(r,g,b,1.0); -} - -void color(sampler2D image) { - actualColor = texture2D(image, vTexCoord); -} - -__INJECTED_NATIVE__; -__MAIN_CONSTANTS__; -__MAIN_ARGUMENTS__; -__KERNEL__; - -void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; -}`; - -module.exports = { - fragmentShader -}; -},{}],37:[function(require,module,exports){ -const { utils } = require('../../utils'); -const { FunctionNode } = require('../function-node'); -const jsMathPrefix = 'Math.'; -const localPrefix = 'this.'; - -class WebGLFunctionNode extends FunctionNode { - constructor(source, settings) { - super(source, settings); - if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { - this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; - } - } - - astFunction(ast, retArr) { - if (this.isRootKernel) { - retArr.push('void'); - } else { - let lastReturn = null; - if (!this.returnType) { - const lastReturn = this.findLastReturn(); - if (lastReturn) { - this.returnType = this.getType(ast.body); - if (this.returnType === 'LiteralInteger') { - this.returnType = 'Number'; + if (this.precision === 'unsigned') { + this.renderRawOutput = this.readPackedPixelsToUint8Array; + this.transferValues = this.readPackedPixelsToFloat32Array; + if (this.pipeline) { + this.renderOutput = this.renderTexture; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToTextures; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureUnsigned3D; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + return null; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); + } + } else { + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToArrays; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + this.renderOutput = this.renderValues; + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureUnsigned3D; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + this.formatValues = utils$1.erect3DPackedFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + this.formatValues = utils$1.erect2DPackedFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + this.formatValues = utils$1.erectPackedFloat; + return null; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); } } - } - - const { returnType } = this; - if (!returnType) { - retArr.push('void'); - } else { - const type = typeMap[returnType]; - if (!type) { - throw new Error(`unknown type ${returnType}`); - } - retArr.push(type); - } - } - retArr.push(' '); - retArr.push(this.name); - retArr.push('('); - - if (!this.isRootKernel) { - for (let i = 0; i < this.argumentNames.length; ++i) { - const argumentName = this.argumentNames[i]; - - if (i > 0) { - retArr.push(', '); - } - let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; - if (!argumentType) { - throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast); - } - if (argumentType === 'LiteralInteger') { - this.argumentTypes[i] = argumentType = 'Number'; + } else if (this.precision === 'single') { + this.renderRawOutput = this.readFloatPixelsToFloat32Array; + this.transferValues = this.readFloatPixelsToFloat32Array; + if (this.pipeline) { + this.renderStrategy = renderStrategy.FloatTexture; + this.renderOutput = this.renderTexture; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToTextures; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.optimizeFloatMemory) { + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + return null; + } + } else { + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureFloat3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + return null; + } + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + return null; + } + } } - const type = typeMap[argumentType]; - if (!type) { - throw this.astErrorOutput('Unexpected expression', ast); + this.renderOutput = this.renderValues; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToArrays; } - - if (type === 'sampler2D' || type === 'sampler2DArray') { - retArr.push(`${type} user_${argumentName},ivec2 user_${argumentName}Size,ivec3 user_${argumentName}Dim`); + if (this.optimizeFloatMemory) { + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized3D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; + this.formatValues = utils$1.erectMemoryOptimized3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; + this.formatValues = utils$1.erectMemoryOptimized2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; + this.formatValues = utils$1.erectMemoryOptimizedFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils$1.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils$1.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils$1.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils$1.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils$1.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils$1.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils$1.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils$1.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils$1.erectArray4; + return null; + } + } } else { - retArr.push(`${type} user_${argumentName}`); + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureFloat3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; + this.formatValues = utils$1.erect3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; + this.formatValues = utils$1.erect2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + this.renderStrategy = renderStrategy.FloatPixelToFloat; + this.formatValues = utils$1.erectFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils$1.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils$1.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils$1.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils$1.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils$1.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils$1.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils$1.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils$1.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils$1.erectArray4; + return null; + } + } } + } else { + throw new Error(`unhandled precision of "${this.precision}"`); } + throw new Error(`unhandled return type "${this.returnType}"`); } - - retArr.push(') {\n'); - - for (let i = 0; i < ast.body.body.length; ++i) { - this.astGeneric(ast.body.body[i], retArr); - retArr.push('\n'); + getKernelString() { + throw new Error(`abstract method call`); } - - retArr.push('}\n'); - return retArr; - } - - astReturnStatement(ast, retArr) { - if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast); - this.pushState('skip-literal-correction'); - const type = this.getType(ast.argument); - this.popState('skip-literal-correction'); - - const result = []; - - if (!this.returnType) { - if (type === 'LiteralInteger' || type === 'Integer') { - this.returnType = 'Number'; - } else { - this.returnType = type; + getMainResultTexture() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Integer': + case 'Number': + return this.getMainResultNumberTexture(); + case 'Array(2)': + return this.getMainResultArray2Texture(); + case 'Array(3)': + return this.getMainResultArray3Texture(); + case 'Array(4)': + return this.getMainResultArray4Texture(); + default: + throw new Error(`unhandled returnType type ${ this.returnType }`); } } - - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Float': - switch (type) { - case 'Integer': - result.push('float('); - this.astGeneric(ast.argument, result); - result.push(')'); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.argument, result); - - if (this.getType(ast) === 'Integer') { - result.unshift('float('); - result.push(')'); - } - break; - default: - this.astGeneric(ast.argument, result); - } - break; - case 'Integer': - switch (type) { - case 'Float': - case 'Number': - this.castValueToInteger(ast.argument, result); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.argument, result); - break; - default: - this.astGeneric(ast.argument, result); - } - break; - case 'Array(4)': - case 'Array(3)': - case 'Array(2)': - case 'Input': - this.astGeneric(ast.argument, result); - break; - default: - throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + getMainResultKernelNumberTexture() { + throw new Error(`abstract method call`); } - - if (this.isRootKernel) { - retArr.push(`kernelResult = ${ result.join('') };`); - retArr.push('return;'); - } else if (this.isSubKernel) { - retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`); - retArr.push(`return subKernelResult_${ this.name };`); - } else { - retArr.push(`return ${ result.join('') };`); + getMainResultSubKernelNumberTexture() { + throw new Error(`abstract method call`); } - return retArr; - } - - astLiteral(ast, retArr) { - if (isNaN(ast.value)) { - throw this.astErrorOutput( - 'Non-numeric literal not supported : ' + ast.value, - ast - ); + getMainResultKernelArray2Texture() { + throw new Error(`abstract method call`); } - - const key = `${ast.start},${ast.end}`; - if (Number.isInteger(ast.value)) { - if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) { - this.literalTypes[key] = 'Integer'; - retArr.push(`${ast.value}`); - } else if (this.isState('casting-to-float') || this.isState('building-float')) { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}.0`); + getMainResultSubKernelArray2Texture() { + throw new Error(`abstract method call`); + } + getMainResultKernelArray3Texture() { + throw new Error(`abstract method call`); + } + getMainResultSubKernelArray3Texture() { + throw new Error(`abstract method call`); + } + getMainResultKernelArray4Texture() { + throw new Error(`abstract method call`); + } + getMainResultSubKernelArray4Texture() { + throw new Error(`abstract method call`); + } + getMainResultGraphical() { + throw new Error(`abstract method call`); + } + getMainResultMemoryOptimizedFloats() { + throw new Error(`abstract method call`); + } + getMainResultPackedPixels() { + throw new Error(`abstract method call`); + } + getMainResultString() { + if (this.graphical) { + return this.getMainResultGraphical(); + } else if (this.precision === 'single') { + if (this.optimizeFloatMemory) { + return this.getMainResultMemoryOptimizedFloats(); + } + return this.getMainResultTexture(); } else { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}.0`); + return this.getMainResultPackedPixels(); } - } else if (this.isState('casting-to-integer') || this.isState('building-integer')) { - this.literalTypes[key] = 'Integer'; - retArr.push(Math.round(ast.value)); - } else { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}`); } - return retArr; - } - - astBinaryExpression(ast, retArr) { - if (this.checkAndUpconvertOperator(ast, retArr)) { - return retArr; + getMainResultNumberTexture() { + return utils$1.linesToString(this.getMainResultKernelNumberTexture()) + + utils$1.linesToString(this.getMainResultSubKernelNumberTexture()); } - - if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { - retArr.push('div_with_int_check('); - this.pushState('building-float'); - switch (this.getType(ast.left)) { - case 'Integer': - this.castValueToFloat(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.left, retArr); - break; + getMainResultArray2Texture() { + return utils$1.linesToString(this.getMainResultKernelArray2Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray2Texture()); + } + getMainResultArray3Texture() { + return utils$1.linesToString(this.getMainResultKernelArray3Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray3Texture()); + } + getMainResultArray4Texture() { + return utils$1.linesToString(this.getMainResultKernelArray4Texture()) + + utils$1.linesToString(this.getMainResultSubKernelArray4Texture()); + } + getFloatTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp float;\n'; + case 'performance': + return 'precision highp float;\n'; + case 'balanced': default: - this.astGeneric(ast.left, retArr); + return 'precision mediump float;\n'; } - retArr.push(', '); - switch (this.getType(ast.right)) { + } + getIntTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp int;\n'; + case 'performance': + return 'precision highp int;\n'; + case 'balanced': + default: + return 'precision mediump int;\n'; + } + } + getSampler2DTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2D;\n'; + case 'performance': + return 'precision highp sampler2D;\n'; + case 'balanced': + default: + return 'precision mediump sampler2D;\n'; + } + } + getSampler2DArrayTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2DArray;\n'; + case 'performance': + return 'precision highp sampler2DArray;\n'; + case 'balanced': + default: + return 'precision mediump sampler2DArray;\n'; + } + } + renderTexture() { + return new this.TextureConstructor({ + texture: this.outputTexture, + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + readPackedPixelsToUint8Array() { + if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"'); + const { + texSize, + context: gl + } = this; + const result = new Uint8Array(texSize[0] * texSize[1] * 4); + gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result); + return result; + } + readPackedPixelsToFloat32Array() { + return new Float32Array(this.readPackedPixelsToUint8Array().buffer); + } + readFloatPixelsToFloat32Array() { + if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); + const { + texSize, + context: gl + } = this; + const w = texSize[0]; + const h = texSize[1]; + const result = new Float32Array(w * h * 4); + gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); + return result; + } + readMemoryOptimizedFloatPixelsToFloat32Array() { + if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); + const { + texSize, + context: gl + } = this; + const w = texSize[0]; + const h = texSize[1]; + const result = new Float32Array(w * h * 4); + gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); + return result; + } + getPixels(flip) { + const { + context: gl, + output + } = this; + const [width, height] = output; + const pixels = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + return new Uint8ClampedArray((flip ? pixels : utils$1.flipPixels(pixels, width, height)).buffer); + } + renderKernelsToArrays() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }).toArray(); + } + return result; + } + renderKernelsToTextures() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + return result; + } + setOutput(output) { + super.setOutput(output); + if (this.program) { + this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + const { context: gl } = this; + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.updateMaxTexSize(); + this.framebuffer.width = this.texSize[0]; + this.framebuffer.height = this.texSize[1]; + this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + this.canvas.width = this.maxTexSize[0]; + this.canvas.height = this.maxTexSize[1]; + this._setupOutputTexture(); + if (this.subKernels && this.subKernels.length > 0) { + this._setupSubOutputTextures(); + } + } + return this; + } + renderValues() { + return this.formatValues( + this.transferValues(), + this.output[0], + this.output[1], + this.output[2] + ); + } + } + const renderStrategy = Object.freeze({ + PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), + PackedPixelToFloat: Symbol('PackedPixelToFloat'), + PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), + PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), + PackedTexture: Symbol('PackedTexture'), + FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), + FloatPixelToFloat: Symbol('FloatPixelToFloat'), + FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), + FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), + FloatPixelToArray2: Symbol('FloatPixelToArray2'), + FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), + FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), + FloatPixelToArray3: Symbol('FloatPixelToArray3'), + FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), + FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), + FloatPixelToArray4: Symbol('FloatPixelToArray4'), + FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), + FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), + FloatTexture: Symbol('FloatTexture'), + MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), + }); + const typeMap$1 = { + int: 'Integer', + float: 'Number', + vec2: 'Array(2)', + vec3: 'Array(3)', + vec4: 'Array(4)', + }; + + class WebGLFunctionNode extends FunctionNode { + constructor(source, settings) { + super(source, settings); + if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { + this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; + } + } + astFunction(ast, retArr) { + if (this.isRootKernel) { + retArr.push('void'); + } else { + if (!this.returnType) { + const lastReturn = this.findLastReturn(); + if (lastReturn) { + this.returnType = this.getType(ast.body); + if (this.returnType === 'LiteralInteger') { + this.returnType = 'Number'; + } + } + } + const { returnType } = this; + if (!returnType) { + retArr.push('void'); + } else { + const type = typeMap$2[returnType]; + if (!type) { + throw new Error(`unknown type ${returnType}`); + } + retArr.push(type); + } + } + retArr.push(' '); + retArr.push(this.name); + retArr.push('('); + if (!this.isRootKernel) { + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + if (i > 0) { + retArr.push(', '); + } + let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; + if (!argumentType) { + throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast); + } + if (argumentType === 'LiteralInteger') { + this.argumentTypes[i] = argumentType = 'Number'; + } + const type = typeMap$2[argumentType]; + if (!type) { + throw this.astErrorOutput('Unexpected expression', ast); + } + retArr.push(type); + retArr.push(' '); + retArr.push('user_'); + retArr.push(argumentName); + } + } + retArr.push(') {\n'); + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); + } + retArr.push('}\n'); + return retArr; + } + astReturnStatement(ast, retArr) { + if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast); + this.pushState('skip-literal-correction'); + const type = this.getType(ast.argument); + this.popState('skip-literal-correction'); + const result = []; + if (!this.returnType) { + if (type === 'LiteralInteger' || type === 'Integer') { + this.returnType = 'Number'; + } else { + this.returnType = type; + } + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Float': + switch (type) { + case 'Integer': + result.push('float('); + this.astGeneric(ast.argument, result); + result.push(')'); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.argument, result); + if (this.getType(ast) === 'Integer') { + result.unshift('float('); + result.push(')'); + } + break; + default: + this.astGeneric(ast.argument, result); + } + break; case 'Integer': - this.castValueToFloat(ast.right, retArr); + switch (type) { + case 'Float': + case 'Number': + this.castValueToInteger(ast.argument, result); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, result); + break; + default: + this.astGeneric(ast.argument, result); + } break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.right, retArr); + case 'Array(4)': + case 'Array(3)': + case 'Array(2)': + case 'Input': + this.astGeneric(ast.argument, result); break; default: - this.astGeneric(ast.right, retArr); + throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + } + if (this.isRootKernel) { + retArr.push(`kernelResult = ${ result.join('') };`); + retArr.push('return;'); + } else if (this.isSubKernel) { + retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`); + retArr.push(`return subKernelResult_${ this.name };`); + } else { + retArr.push(`return ${ result.join('') };`); } - this.popState('building-float'); - retArr.push(')'); return retArr; } - - retArr.push('('); - const leftType = this.getType(ast.left) || 'Number'; - const rightType = this.getType(ast.right) || 'Number'; - if (!leftType || !rightType) { - throw this.astErrorOutput(`Unhandled binary expression`, ast); - } - const key = leftType + ' & ' + rightType; - switch (key) { - case 'Integer & Integer': - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-integer'); - break; - case 'Number & Float': - case 'Float & Number': - case 'Float & Float': - case 'Number & Number': + astLiteral(ast, retArr) { + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + const key = `${ast.start},${ast.end}`; + if (Number.isInteger(ast.value)) { + if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) { + this.literalTypes[key] = 'Integer'; + retArr.push(`${ast.value}`); + } else if (this.isState('casting-to-float') || this.isState('building-float')) { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}.0`); + } else { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}.0`); + } + } else if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.literalTypes[key] = 'Integer'; + retArr.push(Math.round(ast.value)); + } else { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}`); + } + return retArr; + } + astBinaryExpression(ast, retArr) { + if (this.checkAndUpconvertOperator(ast, retArr)) { + return retArr; + } + if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { + retArr.push('div_with_int_check('); this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); + switch (this.getType(ast.left)) { + case 'Integer': + this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(', '); + switch (this.getType(ast.right)) { + case 'Integer': + this.castValueToFloat(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } this.popState('building-float'); - break; - case 'LiteralInteger & LiteralInteger': - if (this.isState('casting-to-integer') || this.isState('building-integer')) { + retArr.push(')'); + return retArr; + } + retArr.push('('); + const leftType = this.getType(ast.left) || 'Number'; + const rightType = this.getType(ast.right) || 'Number'; + if (!leftType || !rightType) { + throw this.astErrorOutput(`Unhandled binary expression`, ast); + } + const key = leftType + ' & ' + rightType; + switch (key) { + case 'Integer & Integer': this.pushState('building-integer'); this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); this.astGeneric(ast.right, retArr); this.popState('building-integer'); - } else { + break; + case 'Number & Float': + case 'Float & Number': + case 'Float & Float': + case 'Number & Number': this.pushState('building-float'); - this.castLiteralToFloat(ast.left, retArr); + this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); + this.astGeneric(ast.right, retArr); this.popState('building-float'); - } - break; - - case 'Integer & Float': - case 'Integer & Number': - if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') { - if (!Number.isInteger(ast.right.value)) { - this.pushState('building-float'); - this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger & LiteralInteger': + if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); this.astGeneric(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); this.popState('building-float'); - break; } - } - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.pushState('casting-to-integer'); - if (ast.right.type === 'Literal') { - const literalResult = []; - this.astGeneric(ast.right, literalResult); - const literalType = this.getType(ast.right); - if (literalType === 'Integer') { - retArr.push(literalResult.join('')); + break; + case 'Integer & Float': + case 'Integer & Number': + if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') { + if (!Number.isInteger(ast.right.value)) { + this.pushState('building-float'); + this.castValueToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-float'); + break; + } + } + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState('casting-to-integer'); + if (ast.right.type === 'Literal') { + const literalResult = []; + this.astGeneric(ast.right, literalResult); + const literalType = this.getType(ast.right); + if (literalType === 'Integer') { + retArr.push(literalResult.join('')); + } else { + throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + } } else { - throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + retArr.push('int('); + this.astGeneric(ast.right, retArr); + retArr.push(')'); } - } else { - retArr.push('int('); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - } - this.popState('casting-to-integer'); - this.popState('building-integer'); - break; - case 'Integer & LiteralInteger': - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToInteger(ast.right, retArr); - this.popState('building-integer'); - break; - - case 'Number & Integer': - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToFloat(ast.right, retArr); - this.popState('building-float'); - break; - case 'Float & LiteralInteger': - case 'Number & LiteralInteger': - if (this.isState('in-for-loop-test')) { + this.popState('casting-to-integer'); + this.popState('building-integer'); + break; + case 'Integer & LiteralInteger': this.pushState('building-integer'); - retArr.push('int('); this.astGeneric(ast.left, retArr); - retArr.push(')'); retArr.push(operatorMap[ast.operator] || ast.operator); this.castLiteralToInteger(ast.right, retArr); this.popState('building-integer'); - } else { + break; + case 'Number & Integer': this.pushState('building-float'); this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); + this.castValueToFloat(ast.right, retArr); this.popState('building-float'); - } - break; - case 'LiteralInteger & Float': - case 'LiteralInteger & Number': - if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) { + break; + case 'Float & LiteralInteger': + case 'Number & LiteralInteger': + if (this.isState('in-for-loop-test')) { + this.pushState('building-integer'); + retArr.push('int('); + this.astGeneric(ast.left, retArr); + retArr.push(')'); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Float': + case 'LiteralInteger & Number': + if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) { + this.pushState('building-integer'); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToInteger(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState('casting-to-float'); + this.astGeneric(ast.right, retArr); + this.popState('casting-to-float'); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Integer': this.pushState('building-integer'); this.castLiteralToInteger(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToInteger(ast.right, retArr); + this.astGeneric(ast.right, retArr); this.popState('building-integer'); - } else { - this.pushState('building-float'); + break; + case 'Boolean & Boolean': + this.pushState('building-boolean'); this.astGeneric(ast.left, retArr); retArr.push(operatorMap[ast.operator] || ast.operator); - this.pushState('casting-to-float'); this.astGeneric(ast.right, retArr); - this.popState('casting-to-float'); - this.popState('building-float'); - } - break; - case 'LiteralInteger & Integer': - this.pushState('building-integer'); - this.castLiteralToInteger(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-integer'); - break; - - case 'Boolean & Boolean': - this.pushState('building-boolean'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-boolean'); - break; - - case 'Float & Integer': - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToFloat(ast.right, retArr); - this.popState('building-float'); - break; - - default: - throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); - } - retArr.push(')'); - - return retArr; - } - - checkAndUpconvertOperator(ast, retArr) { - const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); - if (bitwiseResult) { - return bitwiseResult; - } - const upconvertableOperators = { - '%': 'mod', - '**': 'pow', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - switch (this.getType(ast.left)) { - case 'Integer': - this.castValueToFloat(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.left, retArr); - break; - default: - this.astGeneric(ast.left, retArr); - } - retArr.push(','); - switch (this.getType(ast.right)) { - case 'Integer': - this.castValueToFloat(ast.right, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.right, retArr); - break; - default: - this.astGeneric(ast.right, retArr); - } - retArr.push(')'); - return retArr; - } - - checkAndUpconvertBitwiseOperators(ast, retArr) { - const upconvertableOperators = { - '&': 'bitwiseAnd', - '|': 'bitwiseOr', - '^': 'bitwiseXOR', - '<<': 'bitwiseZeroFillLeftShift', - '>>': 'bitwiseSignedRightShift', - '>>>': 'bitwiseZeroFillRightShift', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - const leftType = this.getType(ast.left); - switch (leftType) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.left, retArr); - break; - default: - this.astGeneric(ast.left, retArr); - } - retArr.push(','); - const rightType = this.getType(ast.right); - switch (rightType) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.right, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.right, retArr); - break; - default: - this.astGeneric(ast.right, retArr); - } - retArr.push(')'); - return retArr; - } - - checkAndUpconvertBitwiseUnary(ast, retArr) { - const upconvertableOperators = { - '~': 'bitwiseNot', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - switch (this.getType(ast.argument)) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.argument, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.argument, retArr); - break; - default: - this.astGeneric(ast.argument, retArr); - } - retArr.push(')'); - return retArr; - } - - castLiteralToInteger(ast, retArr) { - this.pushState('casting-to-integer'); - this.astGeneric(ast, retArr); - this.popState('casting-to-integer'); - return retArr; - } - - castLiteralToFloat(ast, retArr) { - this.pushState('casting-to-float'); - this.astGeneric(ast, retArr); - this.popState('casting-to-float'); - return retArr; - } - - castValueToInteger(ast, retArr) { - this.pushState('casting-to-integer'); - retArr.push('int('); - this.astGeneric(ast, retArr); - retArr.push(')'); - this.popState('casting-to-integer'); - return retArr; - } - - castValueToFloat(ast, retArr) { - this.pushState('casting-to-float'); - retArr.push('float('); - this.astGeneric(ast, retArr); - retArr.push(')'); - this.popState('casting-to-float'); - return retArr; - } - - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); - } - - const type = this.getType(idtNode); - - if (idtNode.name === 'Infinity') { - retArr.push('3.402823466e+38'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${idtNode.name}`); - } - } else { - retArr.push(`user_${idtNode.name}`); - } - - return retArr; - } - - astForStatement(forNode, retArr) { - if (forNode.type !== 'ForStatement') { - throw this.astErrorOutput('Invalid for statement', forNode); - } - - const initArr = []; - const testArr = []; - const updateArr = []; - const bodyArr = []; - let isSafe = null; - - if (forNode.init) { - this.pushState('in-for-loop-init'); - this.astGeneric(forNode.init, initArr); - const { declarations } = forNode.init; - for (let i = 0; i < declarations.length; i++) { - if (declarations[i].init && declarations[i].init.type !== 'Literal') { - isSafe = false; - } - } - if (isSafe) { - for (let i = 0; i < initArr.length; i++) { - if (initArr[i].includes && initArr[i].includes(',')) { - isSafe = false; - } - } - } - this.popState('in-for-loop-init'); - } else { - isSafe = false; - } - - if (forNode.test) { - this.pushState('in-for-loop-test'); - this.astGeneric(forNode.test, testArr); - this.popState('in-for-loop-test'); - } else { - isSafe = false; - } - - if (forNode.update) { - this.astGeneric(forNode.update, updateArr); - } else { - isSafe = false; - } - - if (forNode.body) { - this.pushState('loop-body'); - this.astGeneric(forNode.body, bodyArr); - this.popState('loop-body'); - } - - if (isSafe === null) { - isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); - } - - if (isSafe) { - retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); - retArr.push(bodyArr.join('')); - retArr.push('}\n'); - } else { - const iVariableName = this.getInternalVariableName('safeI'); - if (initArr.length > 0) { - retArr.push(initArr.join(''), ';\n'); - } - retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) { - retArr.push(`if (!${testArr.join('')}) break;\n`); - } - retArr.push(bodyArr.join('')); - retArr.push(`\n${updateArr.join('')};`); - retArr.push('}\n'); - } - return retArr; - } - - astWhileStatement(whileNode, retArr) { - if (whileNode.type !== 'WhileStatement') { - throw this.astErrorOutput('Invalid while statement', whileNode); - } - - const iVariableName = this.getInternalVariableName('safeI'); - retArr.push(`for (int ${iVariableName}=0;${iVariableName} i + 1) { - movingDefaultToEnd = true; - this.astGeneric(cases[i].consequent, defaultResult); - continue; - } else { - retArr.push(' else {\n'); - } - } else { - if (i === 0 || !pastFirstIf) { - pastFirstIf = true; - retArr.push(`if (${varName} == `); - } else { - if (fallingThrough) { - retArr.push(`${varName} == `); - fallingThrough = false; - } else { - retArr.push(` else if (${varName} == `); - } - } - if (type === 'Integer') { - const testType = this.getType(cases[i].test); - switch (testType) { - case 'Number': - case 'Float': - this.castValueToInteger(cases[i].test, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(cases[i].test, retArr); - break; - } - } else if (type === 'Float') { - const testType = this.getType(cases[i].test); - switch (testType) { - case 'LiteralInteger': - this.castLiteralToFloat(cases[i].test, retArr); - break; - case 'Integer': - this.castValueToFloat(cases[i].test, retArr); - break; - } - } else { - throw new Error('unhanlded'); - } - if (!cases[i].consequent || cases[i].consequent.length === 0) { - fallingThrough = true; - retArr.push(' || '); - continue; - } - retArr.push(`) {\n`); - } - this.astGeneric(cases[i].consequent, retArr); - retArr.push('\n}'); - } - if (movingDefaultToEnd) { - retArr.push(' else {'); - retArr.push(defaultResult.join('')); - retArr.push('}'); - } - return retArr; - } - - astThisExpression(tNode, retArr) { - retArr.push('this'); - return retArr; - } - - astMemberExpression(mNode, retArr) { - const { - property, - name, - signature, - origin, - type, - xProperty, - yProperty, - zProperty - } = this.getMemberExpressionDetails(mNode); - switch (signature) { - case 'value.thread.value': - case 'this.thread.value': - if (name !== 'x' && name !== 'y' && name !== 'z') { - throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode); - } - retArr.push(`threadId.${name}`); - return retArr; - case 'this.output.value': - if (this.dynamicOutput) { - switch (name) { - case 'x': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.x)'); - } else { - retArr.push('uOutputDim.x'); - } - break; - case 'y': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.y)'); - } else { - retArr.push('uOutputDim.y'); - } - break; - case 'z': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.z)'); - } else { - retArr.push('uOutputDim.z'); - } - break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - } else { - switch (name) { - case 'x': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[0]); - } else { - retArr.push(this.output[0], '.0'); - } - break; - case 'y': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[1]); - } else { - retArr.push(this.output[1], '.0'); - } - break; - case 'z': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[2]); - } else { - retArr.push(this.output[2], '.0'); - } - break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - } - return retArr; - case 'value': - throw this.astErrorOutput('Unexpected expression', mNode); - case 'value[]': - case 'value[][]': - case 'value[][][]': - case 'value[][][][]': - case 'value.value': - if (origin === 'Math') { - retArr.push(Math[name]); - return retArr; - } - switch (property) { - case 'r': - retArr.push(`user_${ name }.r`); - return retArr; - case 'g': - retArr.push(`user_${ name }.g`); - return retArr; - case 'b': - retArr.push(`user_${ name }.b`); - return retArr; - case 'a': - retArr.push(`user_${ name }.a`); - return retArr; - } - break; - case 'this.constants.value': - if (typeof xProperty === 'undefined') { - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - retArr.push(`constants_${ name }`); - return retArr; - } - } - case 'this.constants.value[]': - case 'this.constants.value[][]': - case 'this.constants.value[][][]': - case 'this.constants.value[][][][]': + this.popState('building-boolean'); break; - case 'fn()[]': - this.astCallExpression(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(property)); - retArr.push(']'); - return retArr; - case '[][]': - this.astArrayExpression(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(property)); - retArr.push(']'); - return retArr; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - - if (mNode.computed === false) { - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - retArr.push(`${origin}_${name}`); - return retArr; - } - } - - const markupName = `${origin}_${name}`; - - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - this.astGeneric(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(xProperty)); - retArr.push(']'); - break; - case 'HTMLImageArray': - retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(1)': - retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(2)': - case 'Array2D(2)': - case 'Array3D(2)': - retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(2)': - retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(3)': - case 'Array2D(3)': - case 'Array3D(3)': - retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(3)': - retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(4)': - case 'Array2D(4)': - case 'Array3D(4)': - retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(4)': - case 'HTMLImage': - case 'HTMLVideo': - retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'NumberTexture': - case 'Array': - case 'Array2D': - case 'Array3D': - case 'Array4D': - case 'Input': - case 'Number': - case 'Float': - case 'Integer': - if (this.precision === 'single') { - retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - } else { - const bitRatio = (origin === 'user' ? - this.lookupFunctionArgumentBitRatio(this.name, name) : - this.constantBitRatios[name] - ); - switch (bitRatio) { - case 1: - retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - case 2: - retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - case 4: - case 0: - retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - default: - throw new Error(`unhandled bit ratio of ${bitRatio}`); - } - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - } - break; - case 'MemoryOptimizedNumberTexture': - retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - default: - throw new Error(`unhandled member expression "${ type }"`); - } - return retArr; - } - - astCallExpression(ast, retArr) { - if (!ast.callee) { - throw this.astErrorOutput('Unknown CallExpression', ast); - } - - let functionName = null; - const isMathFunction = this.isAstMathFunction(ast); - - if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) { - functionName = ast.callee.property.name; - } - else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) { - functionName = ast.callee.expressions[1].property.name; - } else { - functionName = ast.callee.name; - } - - if (!functionName) { - throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); - } - - if (functionName === 'atan2') { - functionName = 'atan'; - } - - if (this.calledFunctions.indexOf(functionName) < 0) { - this.calledFunctions.push(functionName); - } - - if (functionName === 'random' && this.plugins && this.plugins.length > 0) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) { - retArr.push(plugin.functionReplace); - return retArr; - } - } - } - - if (this.onFunctionCall) { - this.onFunctionCall(this.name, functionName, ast.arguments); - } - - retArr.push(functionName); - - retArr.push('('); - - if (isMathFunction) { - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - const argumentType = this.getType(argument); - if (i > 0) { - retArr.push(', '); - } - - switch (argumentType) { - case 'Integer': - this.castValueToFloat(argument, retArr); - break; - default: - this.astGeneric(argument, retArr); - break; - } - } - } else { - const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - let targetType = targetTypes[i]; - if (i > 0) { - retArr.push(', '); - } - const argumentType = this.getType(argument); - if (!targetType) { - this.triggerImplyArgumentType(functionName, i, argumentType, this); - targetType = argumentType; - } - switch (argumentType) { - case 'Number': - case 'Float': - if (targetType === 'Integer') { - retArr.push('int('); - this.astGeneric(argument, retArr); - retArr.push(')'); - continue; - } else if (targetType === 'Number' || targetType === 'Float') { - this.astGeneric(argument, retArr); - continue; - } else if (targetType === 'LiteralInteger') { - this.castLiteralToFloat(argument, retArr); - continue; - } - break; - case 'Integer': - if (targetType === 'Number' || targetType === 'Float') { - retArr.push('float('); - this.astGeneric(argument, retArr); - retArr.push(')'); - continue; - } else if (targetType === 'Integer') { - this.astGeneric(argument, retArr); - continue; - } - break; - case 'LiteralInteger': - if (targetType === 'Integer') { - this.castLiteralToInteger(argument, retArr); - continue; - } else if (targetType === 'Number' || targetType === 'Float') { - this.castLiteralToFloat(argument, retArr); - continue; - } else if (targetType === 'LiteralInteger') { - this.astGeneric(argument, retArr); - continue; - } - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - if (targetType === argumentType) { - if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name}`); - continue; - } - break; - case 'HTMLImage': - case 'HTMLImageArray': - case 'HTMLVideo': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'Array': - case 'Input': - if (targetType === argumentType) { - if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); - continue; - } - break; - } - throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); - } - } - retArr.push(')'); - - return retArr; - } - - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('vec' + arrLen + '('); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - const subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr) - } - retArr.push(')'); - - return retArr; - } - - memberExpressionXYZ(x, y, z, retArr) { - if (z) { - retArr.push(this.memberExpressionPropertyMarkup(z), ', '); - } else { - retArr.push('0, '); - } - if (y) { - retArr.push(this.memberExpressionPropertyMarkup(y), ', '); - } else { - retArr.push('0, '); - } - retArr.push(this.memberExpressionPropertyMarkup(x)); - return retArr; - } - - memberExpressionPropertyMarkup(property) { - if (!property) { - throw new Error('Property not set'); - } - const type = this.getType(property); - const result = []; - switch (type) { - case 'Number': - case 'Float': - this.castValueToInteger(property, result); - break; - case 'LiteralInteger': - this.castLiteralToInteger(property, result); - break; - default: - this.astGeneric(property, result); - } - return result.join(''); - } -} - -const typeMap = { - 'Array': 'sampler2D', - 'Array(2)': 'vec2', - 'Array(3)': 'vec3', - 'Array(4)': 'vec4', - 'Array2D': 'sampler2D', - 'Array3D': 'sampler2D', - 'Boolean': 'bool', - 'Float': 'float', - 'Input': 'sampler2D', - 'Integer': 'int', - 'Number': 'float', - 'LiteralInteger': 'float', - 'NumberTexture': 'sampler2D', - 'MemoryOptimizedNumberTexture': 'sampler2D', - 'ArrayTexture(1)': 'sampler2D', - 'ArrayTexture(2)': 'sampler2D', - 'ArrayTexture(3)': 'sampler2D', - 'ArrayTexture(4)': 'sampler2D', - 'HTMLVideo': 'sampler2D', - 'HTMLImage': 'sampler2D', - 'HTMLImageArray': 'sampler2DArray', -}; - -const operatorMap = { - '===': '==', - '!==': '!=' -}; - -module.exports = { - WebGLFunctionNode -}; -},{"../../utils":112,"../function-node":10}],38:[function(require,module,exports){ -const { WebGLKernelValueBoolean } = require('./kernel-value/boolean'); -const { WebGLKernelValueFloat } = require('./kernel-value/float'); -const { WebGLKernelValueInteger } = require('./kernel-value/integer'); - -const { WebGLKernelValueHTMLImage } = require('./kernel-value/html-image'); -const { WebGLKernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image'); - -const { WebGLKernelValueHTMLVideo } = require('./kernel-value/html-video'); -const { WebGLKernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video'); - -const { WebGLKernelValueSingleInput } = require('./kernel-value/single-input'); -const { WebGLKernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input'); - -const { WebGLKernelValueUnsignedInput } = require('./kernel-value/unsigned-input'); -const { WebGLKernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input'); - -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture'); -const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture'); - -const { WebGLKernelValueNumberTexture } = require('./kernel-value/number-texture'); -const { WebGLKernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture'); - -const { WebGLKernelValueSingleArray } = require('./kernel-value/single-array'); -const { WebGLKernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array'); - -const { WebGLKernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i'); -const { WebGLKernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i'); - -const { WebGLKernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i'); -const { WebGLKernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i'); - -const { WebGLKernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i'); -const { WebGLKernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i'); - -const { WebGLKernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGLKernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGLKernelValueSingleArray4 } = require('./kernel-value/single-array4'); - -const { WebGLKernelValueUnsignedArray } = require('./kernel-value/unsigned-array'); -const { WebGLKernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array'); - -const kernelValueMaps = { - unsigned: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGLKernelValueDynamicUnsignedInput, - 'NumberTexture': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGLKernelValueUnsignedInput, - 'NumberTexture': WebGLKernelValueNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI, - 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI, - 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI, - 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI, - 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI, - 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI, - 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI, - 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI, - 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI, - 'Input': WebGLKernelValueDynamicSingleInput, - 'NumberTexture': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - 'Array1D(2)': WebGLKernelValueSingleArray1DI, - 'Array1D(3)': WebGLKernelValueSingleArray1DI, - 'Array1D(4)': WebGLKernelValueSingleArray1DI, - 'Array2D(2)': WebGLKernelValueSingleArray2DI, - 'Array2D(3)': WebGLKernelValueSingleArray2DI, - 'Array2D(4)': WebGLKernelValueSingleArray2DI, - 'Array3D(2)': WebGLKernelValueSingleArray3DI, - 'Array3D(3)': WebGLKernelValueSingleArray3DI, - 'Array3D(4)': WebGLKernelValueSingleArray3DI, - 'Input': WebGLKernelValueSingleInput, - 'NumberTexture': WebGLKernelValueNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, -}; - -function lookupKernelValueType(type, dynamic, precision, value) { - if (!type) { - throw new Error('type missing'); - } - if (!dynamic) { - throw new Error('dynamic missing'); - } - if (!precision) { - throw new Error('precision missing'); - } - if (value.type) { - type = value.type; - } - const types = kernelValueMaps[precision][dynamic]; - if (types[type] === false) { - return null; - } else if (types[type] === undefined) { - throw new Error(`Could not find a KernelValue for ${ type }`); - } - return types[type]; -} - -module.exports = { - lookupKernelValueType, - kernelValueMaps, -}; -},{"./kernel-value/boolean":39,"./kernel-value/dynamic-html-image":40,"./kernel-value/dynamic-html-video":41,"./kernel-value/dynamic-memory-optimized-number-texture":42,"./kernel-value/dynamic-number-texture":43,"./kernel-value/dynamic-single-array":44,"./kernel-value/dynamic-single-array1d-i":45,"./kernel-value/dynamic-single-array2d-i":46,"./kernel-value/dynamic-single-array3d-i":47,"./kernel-value/dynamic-single-input":48,"./kernel-value/dynamic-unsigned-array":49,"./kernel-value/dynamic-unsigned-input":50,"./kernel-value/float":51,"./kernel-value/html-image":52,"./kernel-value/html-video":53,"./kernel-value/integer":55,"./kernel-value/memory-optimized-number-texture":56,"./kernel-value/number-texture":57,"./kernel-value/single-array":58,"./kernel-value/single-array1d-i":59,"./kernel-value/single-array2":60,"./kernel-value/single-array2d-i":61,"./kernel-value/single-array3":62,"./kernel-value/single-array3d-i":63,"./kernel-value/single-array4":64,"./kernel-value/single-input":65,"./kernel-value/unsigned-array":66,"./kernel-value/unsigned-input":67}],39:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueBoolean extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const bool ${this.id} = ${value};\n`; - } - return `uniform bool ${this.id};\n`; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueBoolean -}; -},{"../../../utils":112,"./index":54}],40:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.textureSize = [width, height]; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicHTMLImage -}; -},{"../../../utils":112,"./html-image":52}],41:[function(require,module,exports){ -const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} - -module.exports = { - WebGLKernelValueDynamicHTMLVideo -}; -},{"./dynamic-html-image":40}],42:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./memory-optimized-number-texture'); - -class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(inputTexture) { - this.checkSize(inputTexture.size[0], inputTexture.size[1]); - this.dimensions = inputTexture.dimensions; - this.textureSize = inputTexture.size; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(inputTexture); - } -} - -module.exports = { - WebGLKernelValueDynamicMemoryOptimizedNumberTexture -}; -},{"../../../utils":112,"./memory-optimized-number-texture":56}],43:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueNumberTexture } = require('./number-texture'); - -class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = value.dimensions; - this.checkSize(value.size[0], value.size[1]); - this.textureSize = value.size; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicNumberTexture -}; -},{"../../../utils":112,"./number-texture":57}],44:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray } = require('./single-array'); - -class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray -}; -},{"../../../utils":112,"./single-array":58}],45:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray1DI } = require('./single-array1d-i'); - -class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray1DI -}; -},{"../../../utils":112,"./single-array1d-i":59}],46:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray2DI } = require('./single-array2d-i'); - -class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray2DI -}; -},{"../../../utils":112,"./single-array2d-i":61}],47:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray3DI } = require('./single-array3d-i'); - -class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray3DI -}; -},{"../../../utils":112,"./single-array3d-i":63}],48:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleInput } = require('./single-input'); - -class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleInput -}; -},{"../../../utils":112,"./single-input":65}],49:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedArray } = require('./unsigned-array'); - -class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - const Type = this.getTransferArrayType(value); - this.preUploadValue = new Type(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicUnsignedArray -}; -},{"../../../utils":112,"./unsigned-array":66}],50:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedInput } = require('./unsigned-input'); - -class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - const Type = this.getTransferArrayType(value.value); - this.preUploadValue = new Type(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicUnsignedInput -}; -},{"../../../utils":112,"./unsigned-input":67}],51:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueFloat extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - getSource(value) { - if (this.origin === 'constants') { - if (Number.isInteger(value)) { - return `const float ${this.id} = ${value}.0;\n`; - } - return `const float ${this.id} = ${value};\n`; - } - return `uniform float ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1f(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueFloat -}; -},{"../../../utils":112,"./index":54}],52:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueHTMLImage extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.requestTexture(); - this.textureSize = [width, height]; - this.uploadValue = value; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputImage) { - if (inputImage.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueHTMLImage -}; -},{"../../../utils":112,"./index":54}],53:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} - -module.exports = { - WebGLKernelValueHTMLVideo -}; -},{"../../../utils":112,"./html-image":52}],54:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { Input } = require('../../../input'); -const { KernelValue } = require('../../kernel-value'); - -class WebGLKernelValue extends KernelValue { - constructor(value, settings) { - super(value, settings); - this.dimensionsId = null; - this.sizeId = null; - this.initialValueConstructor = value.constructor; - this.onRequestTexture = settings.onRequestTexture; - this.onRequestIndex = settings.onRequestIndex; - this.uploadValue = null; - this.textureSize = null; - this.bitRatio = null; - } - - checkSize(width, height) { - if (!this.kernel.validate) return; - const { maxTextureSize } = this.kernel.constructor.features; - if (width > maxTextureSize || height > maxTextureSize) { - if (width > height) { - throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); - } else { - throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); - } - } - } - - requestTexture() { - this.texture = this.onRequestTexture(); - this.setupTexture(); - } - - setupTexture() { - this.contextHandle = this.onRequestContextHandle(); - this.index = this.onRequestIndex(); - this.dimensionsId = this.id + 'Dim'; - this.sizeId = this.id + 'Size'; - } - - getTransferArrayType(value) { - if (Array.isArray(value[0])) { - return this.getTransferArrayType(value[0]); - } - switch (value.constructor) { - case Array: - case Int32Array: - case Int16Array: - case Int8Array: - return Float32Array; - case Uint8ClampedArray: - case Uint8Array: - case Uint16Array: - case Uint32Array: - case Float32Array: - case Float64Array: - return value.constructor; - } - console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros'); - return value.constructor; - } - formatArrayTransfer(value, length, Type) { - if (utils.isArray(value[0]) || this.optimizeFloatMemory) { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } else { - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - case Uint16Array: - case Int16Array: - case Float32Array: - case Int32Array: { - const valuesFlat = new(Type || value.constructor)(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - default: { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - } - } - } - - getBitRatio(value) { - if (Array.isArray(value[0])) { - return this.getBitRatio(value[0]); - } else if (value.constructor === Input) { - return this.getBitRatio(value.value); - } - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - return 1; - case Uint16Array: - case Int16Array: - return 2; - case Float32Array: - case Int32Array: - default: - return 4; - } - } - - getStringValueHandler() { - throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); - } - - getVariablePrecisionString() { - switch (this.tactic) { - case 'speed': - return 'lowp'; - case 'performance': - return 'highp'; - case 'balanced': - default: - return 'mediump'; - } - } -} - -module.exports = { - WebGLKernelValue -}; -},{"../../../input":108,"../../../utils":112,"../../kernel-value":34}],55:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueInteger extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - getSource(value) { - if (this.origin === 'constants') { - return `const int ${this.id} = ${ parseInt(value) };\n`; - } - return `uniform int ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueInteger -}; -},{"../../../utils":112,"./index":54}],56:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - this.dimensions = value.dimensions; - this.textureSize = value.size; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputTexture) { - if (inputTexture.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type }) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueMemoryOptimizedNumberTexture -}; -},{"../../../utils":112,"./index":54}],57:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - const { size: textureSize, dimensions } = value; - this.bitRatio = this.getBitRatio(value); - this.dimensions = dimensions; - this.textureSize = textureSize; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputTexture) { - if (inputTexture.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type}) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueNumberTexture -}; -},{"../../../utils":112,"./index":54}],58:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray -}; -},{"../../../utils":112,"./index":54}],59:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], 1, 1]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten2dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray1DI -}; -},{"../../../utils":112,"./index":54}],60:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`; - } - return `uniform vec2 ${this.id};\n`; - } - - getStringValueHandler() { - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform2fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray2 -}; -},{"../../../utils":112,"./index":54}],61:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten3dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray2DI -}; -},{"../../../utils":112,"./index":54}],62:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`; - } - return `uniform vec3 ${this.id};\n`; - } - - getStringValueHandler() { - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform3fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray3 -}; -},{"../../../utils":112,"./index":54}],63:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten4dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray3DI -}; -},{"../../../utils":112,"./index":54}],64:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray4 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`; - } - return `uniform vec4 ${this.id};\n`; - } - - getStringValueHandler() { - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform4fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray4 -}; -},{"../../../utils":112,"./index":54}],65:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}.value, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(input) { - if (input.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleInput -}; -},{"../../../utils":112,"./index":54}],66:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = this.getBitRatio(value); - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - this.TranserArrayType = this.getTransferArrayType(value); - this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - } - - getStringValueHandler() { - return utils.linesToString([ - `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, - `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, - `flattenTo(${this.varName}, preUploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.preUploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueUnsignedArray -}; -},{"../../../utils":112,"./index":54}],67:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = this.getBitRatio(value); - const [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - this.TranserArrayType = this.getTransferArrayType(value.value); - this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - } - - getStringValueHandler() { - return utils.linesToString([ - `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, - `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, - `flattenTo(${this.varName}.value, preUploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(input) { - if (input.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.preUploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueUnsignedInput -}; -},{"../../../utils":112,"./index":54}],68:[function(require,module,exports){ -const { GLKernel } = require('../gl/kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { WebGLFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const triangleNoise = require('../../plugins/triangle-noise'); -const { fragmentShader } = require('./fragment-shader'); -const { vertexShader } = require('./vertex-shader'); -const { glKernelString } = require('../gl/kernel-string'); -const { lookupKernelValueType } = require('./kernel-value-maps'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; -let features = null; - -const plugins = [triangleNoise]; -const canvases = []; -const maxTexSizes = {}; - - -class WebGLKernel extends GLKernel { - static get isSupported() { - if (isSupported !== null) { - return isSupported; - } - this.setupFeatureChecks(); - isSupported = this.isContextMatch(testContext); - return isSupported; - } - - static setupFeatureChecks() { - if (typeof document !== 'undefined') { - testCanvas = document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - testCanvas = new OffscreenCanvas(0, 0); - } - if (!testCanvas) return; - testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - OES_texture_float: testContext.getExtension('OES_texture_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), - }; - features = this.getFeatures(); - } - - static isContextMatch(context) { - if (typeof WebGLRenderingContext !== 'undefined') { - return context instanceof WebGLRenderingContext; - } - return false; - } - - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - static getIsTextureFloat() { - return Boolean(testExtensions.OES_texture_float); - } - - static getIsDrawBuffers() { - return Boolean(testExtensions.WEBGL_draw_buffers); - } - - static getChannelCount() { - return testExtensions.WEBGL_draw_buffers ? - testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : - 1; - } - - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); - } - - static lookupKernelValueType(type, dynamic, precision, value) { - return lookupKernelValueType(type, dynamic, precision, value); - } - - static get testCanvas() { - return testCanvas; - } - - static get testContext() { - return testContext; - } - - static get features() { - return features; - } - - static get fragmentShader() { - return fragmentShader; - } - - static get vertexShader() { - return vertexShader; - } - - constructor(source, settings) { - super(source, settings); - this.program = null; - this.pipeline = settings.pipeline; - this.endianness = utils.systemEndianness(); - this.extensions = {}; - this.subKernelOutputTextures = null; - this.kernelArguments = null; - this.argumentTextureCount = 0; - this.constantTextureCount = 0; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - this.fragShader = null; - this.vertShader = null; - this.drawBuffersMap = null; - this.outputTexture = null; - - this.maxTexSize = null; - this.switchingKernels = false; - this.onRequestSwitchKernel = null; - - this.mergeSettings(source.settings || settings); - - this.threadDim = null; - this.framebuffer = null; - this.buffer = null; - this.textureCache = {}; - this.programUniformLocationCache = {}; - this.uniform1fCache = {}; - this.uniform1iCache = {}; - this.uniform2fCache = {}; - this.uniform2fvCache = {}; - this.uniform2ivCache = {}; - this.uniform3fvCache = {}; - this.uniform3ivCache = {}; - this.uniform4fvCache = {}; - this.uniform4ivCache = {}; - } - - initCanvas() { - if (typeof document !== 'undefined') { - const canvas = document.createElement('canvas'); - canvas.width = 2; - canvas.height = 2; - return canvas; - } else if (typeof OffscreenCanvas !== 'undefined') { - return new OffscreenCanvas(0, 0); - } - } - - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings); - } - - initPlugins(settings) { - const pluginsToUse = []; - const { source } = this; - if (typeof source === 'string') { - for (let i = 0; i < plugins.length; i++) { - const plugin = plugins[i]; - if (source.match(plugin.functionMatch)) { - pluginsToUse.push(plugin); - } - } - } else if (typeof source === 'object') { - if (settings.pluginNames) { - for (let i = 0; i < plugins.length; i++) { - const plugin = plugins[i]; - const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name); - if (usePlugin) { - pluginsToUse.push(plugin); - } - } - } - } - return pluginsToUse; - } - - initExtensions() { - this.extensions = { - OES_texture_float: this.context.getExtension('OES_texture_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), - WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'), - }; - } - - validateSettings(args) { - if (!this.validate) { - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - return; - } - - const { features } = this.constructor; - - if (this.optimizeFloatMemory === true && !features.isTextureFloat) { - throw new Error('Float textures are not supported'); - } else if (this.precision === 'single' && !features.isFloatRead) { - throw new Error('Single precision not supported'); - } else if (!this.graphical && this.precision === null && features.isTextureFloat) { - this.precision = features.isFloatRead ? 'single' : 'unsigned'; - } - - if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) { - throw new Error('could not instantiate draw buffers extension'); - } - - if (this.fixIntegerDivisionAccuracy === null) { - this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; - } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { - this.fixIntegerDivisionAccuracy = false; - } - - this.checkOutput(); - - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); - } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { - this.output = args[0].output; - } else { - throw new Error('Auto output not supported for input type: ' + argType); + case 'Float & Integer': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState('building-float'); + break; + default: + throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); } + retArr.push(')'); + return retArr; } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + checkAndUpconvertOperator(ast, retArr) { + const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); + if (bitwiseResult) { + return bitwiseResult; } - - if (this.precision === 'precision') { - this.precision = 'unsigned'; - console.warn('Cannot use graphical mode and single precision at the same time'); + const upconvertableOperators = { + '%': 'mod', + '**': 'pow', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + switch (this.getType(ast.left)) { + case 'Integer': + this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); } - - this.texSize = utils.clone(this.output); - return; - } else if (this.precision === null && features.isTextureFloat) { - this.precision = 'single'; - } - - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - - this.checkTextureSize(); - } - - updateMaxTexSize() { - const { texSize, canvas } = this; - if (this.maxTexSize === null) { - let canvasIndex = canvases.indexOf(canvas); - if (canvasIndex === -1) { - canvasIndex = canvases.length; - canvases.push(canvas); - maxTexSizes[canvasIndex] = [texSize[0], texSize[1]]; + retArr.push(','); + switch (this.getType(ast.right)) { + case 'Integer': + this.castValueToFloat(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); } - this.maxTexSize = maxTexSizes[canvasIndex]; - } - if (this.maxTexSize[0] < texSize[0]) { - this.maxTexSize[0] = texSize[0]; - } - if (this.maxTexSize[1] < texSize[1]) { - this.maxTexSize[1] = texSize[1]; - } - } - - _oldtranslateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - - const translatedSource = functionBuilder.getPrototypeString('kernel'); - - if (!this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + retArr.push(')'); + return retArr; } - - let requiredChannels = 0; - const returnTypes = functionBuilder.getReturnTypes(); - for (let i = 0; i < returnTypes.length; i++) { - switch (returnTypes[i]) { + checkAndUpconvertBitwiseOperators(ast, retArr) { + const upconvertableOperators = { + '&': 'bitwiseAnd', + '|': 'bitwiseOr', + '^': 'bitwiseXOR', + '<<': 'bitwiseZeroFillLeftShift', + '>>': 'bitwiseSignedRightShift', + '>>>': 'bitwiseZeroFillRightShift', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + const leftType = this.getType(ast.left); + switch (leftType) { + case 'Number': case 'Float': + this.castValueToInteger(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(','); + const rightType = this.getType(ast.right); + switch (rightType) { case 'Number': - case 'Integer': - requiredChannels++; + case 'Float': + this.castValueToInteger(ast.right, retArr); break; - case 'Array(2)': - requiredChannels += 2; + case 'LiteralInteger': + this.castLiteralToInteger(ast.right, retArr); break; - case 'Array(3)': - requiredChannels += 3; + default: + this.astGeneric(ast.right, retArr); + } + retArr.push(')'); + return retArr; + } + checkAndUpconvertBitwiseUnary(ast, retArr) { + const upconvertableOperators = { + '~': 'bitwiseNot', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + switch (this.getType(ast.argument)) { + case 'Number': + case 'Float': + this.castValueToInteger(ast.argument, retArr); break; - case 'Array(4)': - requiredChannels += 4; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, retArr); break; + default: + this.astGeneric(ast.argument, retArr); } + retArr.push(')'); + return retArr; } - - if (features && requiredChannels > features.channelCount) { - throw new Error('Too many channels!'); + castLiteralToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + this.astGeneric(ast, retArr); + this.popState('casting-to-integer'); + return retArr; } - - return this.translatedSource = translatedSource; - } - - setupArguments(args) { - this.kernelArguments = []; - this.argumentTextureCount = 0; - const needsArgumentTypes = this.argumentTypes === null; - if (needsArgumentTypes) { - this.argumentTypes = []; + castLiteralToFloat(ast, retArr) { + this.pushState('casting-to-float'); + this.astGeneric(ast, retArr); + this.popState('casting-to-float'); + return retArr; } - this.argumentSizes = []; - this.argumentBitRatios = []; - - if (args.length < this.argumentNames.length) { - throw new Error('not enough arguments for kernel'); - } else if (args.length > this.argumentNames.length) { - throw new Error('too many arguments for kernel'); + castValueToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + retArr.push('int('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-integer'); + return retArr; } - - const { context: gl } = this; - let textureIndexes = 0; - for (let index = 0; index < args.length; index++) { - const value = args[index]; - const name = this.argumentNames[index]; - let type; - if (needsArgumentTypes) { - type = utils.getVariableType(value, this.strictIntegers); - this.argumentTypes.push(type); - } else { - type = this.argumentTypes[index]; - } - const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]); - if (KernelValue === null) { - return this.requestFallback(args); + castValueToFloat(ast, retArr) { + this.pushState('casting-to-float'); + retArr.push('float('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-float'); + return retArr; + } + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); } - const kernelArgument = new KernelValue(value, { - name, - type, - tactic: this.tactic, - origin: 'user', - context: gl, - checkContext: this.checkContext, - kernel: this, - strictIntegers: this.strictIntegers, - onRequestTexture: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onUpdateValueMismatch: () => { - this.switchingKernels = true; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + const type = this.getType(idtNode); + if (idtNode.name === 'Infinity') { + retArr.push('3.402823466e+38'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); + } else { + retArr.push(`user_${idtNode.name}`); } - }); - this.kernelArguments.push(kernelArgument); - this.argumentSizes.push(kernelArgument.textureSize); - this.argumentBitRatios[index] = kernelArgument.bitRatio; - } - } - - setupConstants(args) { - const { context: gl } = this; - this.kernelConstants = []; - this.forceUploadKernelConstants = []; - let needsConstantTypes = this.constantTypes === null; - if (needsConstantTypes) { - this.constantTypes = {}; + } else { + retArr.push(`user_${idtNode.name}`); + } + return retArr; } - this.constantBitRatios = {}; - let textureIndexes = 0; - for (const name in this.constants) { - const value = this.constants[name]; - let type; - if (needsConstantTypes) { - type = utils.getVariableType(value, this.strictIntegers); - this.constantTypes[name] = type; + astForStatement(forNode, retArr) { + if (forNode.type !== 'ForStatement') { + throw this.astErrorOutput('Invalid for statement', forNode); + } + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + if (forNode.init) { + this.pushState('in-for-loop-init'); + this.astGeneric(forNode.init, initArr); + const { declarations } = forNode.init; + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init && declarations[i].init.type !== 'Literal') { + isSafe = false; + } + } + if (isSafe) { + for (let i = 0; i < initArr.length; i++) { + if (initArr[i].includes && initArr[i].includes(',')) { + isSafe = false; + } + } + } + this.popState('in-for-loop-init'); } else { - type = this.constantTypes[name]; + isSafe = false; } - const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value); - if (KernelValue === null) { - return this.requestFallback(args); + if (forNode.test) { + this.pushState('in-for-loop-test'); + this.astGeneric(forNode.test, testArr); + this.popState('in-for-loop-test'); + } else { + isSafe = false; } - const kernelValue = new KernelValue(value, { - name, - type, - tactic: this.tactic, - origin: 'constants', - context: this.context, - checkContext: this.checkContext, - kernel: this, - strictIntegers: this.strictIntegers, - onRequestTexture: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount++; - } - }); - this.constantBitRatios[name] = kernelValue.bitRatio; - this.kernelConstants.push(kernelValue); - if (kernelValue.forceUploadEachRun) { - this.forceUploadKernelConstants.push(kernelValue); + if (forNode.update) { + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; } - } - } - - build() { - this.initExtensions(); - this.validateSettings(arguments); - this.setupConstants(arguments); - if (this.fallbackRequested) return; - this.setupArguments(arguments); - if (this.fallbackRequested) return; - this.updateMaxTexSize(); - this.translateSource(); - const failureResult = this.pickRenderStrategy(arguments); - if (failureResult) { - return failureResult; - } - const { texSize, context: gl, canvas } = this; - gl.enable(gl.SCISSOR_TEST); - if (this.pipeline && this.precision === 'single') { - gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - canvas.width = this.maxTexSize[0]; - canvas.height = this.maxTexSize[1]; - } else { - gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - canvas.width = this.maxTexSize[0]; - canvas.height = this.maxTexSize[1]; - } - const threadDim = this.threadDim = Array.from(this.output); - while (threadDim.length < 3) { - threadDim.push(1); - } - - const compiledVertexShader = this.getVertexShader(arguments); - const vertShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertShader, compiledVertexShader); - gl.compileShader(vertShader); - this.vertShader = vertShader; - - const compiledFragmentShader = this.getFragmentShader(arguments); - const fragShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragShader, compiledFragmentShader); - gl.compileShader(fragShader); - this.fragShader = fragShader; - - if (this.debug) { - console.log('GLSL Shader Output:'); - console.log(compiledFragmentShader); - } - - if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) { - throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader)); - } - if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) { - throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader)); - } - - const program = this.program = gl.createProgram(); - gl.attachShader(program, vertShader); - gl.attachShader(program, fragShader); - gl.linkProgram(program); - this.framebuffer = gl.createFramebuffer(); - this.framebuffer.width = texSize[0]; - this.framebuffer.height = texSize[1]; - - const vertices = new Float32Array([-1, -1, - 1, -1, -1, 1, - 1, 1 - ]); - const texCoords = new Float32Array([ - 0, 0, - 1, 0, - 0, 1, - 1, 1 - ]); - - const texCoordOffset = vertices.byteLength; - - let buffer = this.buffer; - if (!buffer) { - buffer = this.buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW); - } else { - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - } - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); - gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords); - - const aPosLoc = gl.getAttribLocation(this.program, 'aPos'); - gl.enableVertexAttribArray(aPosLoc); - gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0); - const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord'); - gl.enableVertexAttribArray(aTexCoordLoc); - gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - - let i = 0; - gl.useProgram(this.program); - for (let p in this.constants) { - this.kernelConstants[i++].updateValue(this.constants[p]); - } - - if (!this.immutable) { - this._setupOutputTexture(); - if ( - this.subKernels !== null && - this.subKernels.length > 0 - ) { - this._setupSubOutputTextures(); + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); } - } - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - - if (this.subKernels && this.subKernels.length > 0) { - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (!subKernel.returnType) { - subKernel.returnType = functionBuilder.getSubKernelResultType(i); - } + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); } - } - } - - run() { - const { kernelArguments, forceUploadKernelConstants } = this; - const texSize = this.texSize; - const gl = this.context; - - gl.useProgram(this.program); - gl.scissor(0, 0, texSize[0], texSize[1]); - - if (this.dynamicOutput) { - this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); - this.setUniform2iv('uTexSize', texSize); - } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.switchingKernels = false; - for (let i = 0; i < forceUploadKernelConstants.length; i++) { - const constant = forceUploadKernelConstants[i]; - constant.updateValue(this.constants[constant.name]); - if (this.switchingKernels) return; - } - for (let i = 0; i < kernelArguments.length; i++) { - kernelArguments[i].updateValue(arguments[i]); - if (this.switchingKernels) return; - } - - if (this.plugins) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.onBeforeRun) { - plugin.onBeforeRun(this); + if (isSafe) { + retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); + retArr.push(bodyArr.join('')); + retArr.push('}\n'); + } else { + const iVariableName = this.getInternalVariableName('safeI'); + if (initArr.length > 0) { + retArr.push(initArr.join(''), ';\n'); } - } - } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); + retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) { + retArr.push(`if (!${testArr.join('')}) break;\n`); } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); + retArr.push(bodyArr.join('')); + retArr.push(`\n${updateArr.join('')};`); + retArr.push('}\n'); } - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return; - } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.immutable) { - this._setupOutputTexture(); + return retArr; } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput('Invalid while statement', whileNode); } - this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + const iVariableName = this.getInternalVariableName('safeI'); + retArr.push(`for (int ${iVariableName}=0;${iVariableName} plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n'); - } - - _getConstantsString() { - const result = []; - const { threadDim, texSize } = this; - if (this.dynamicOutput) { - result.push( - 'uniform ivec3 uOutputDim', - 'uniform ivec2 uTexSize' - ); - } else { - result.push( - `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`, - `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})` - ); - } - return utils.linesToString(result); - } - - _getTextureCoordinate() { - const subKernels = this.subKernels; - if (subKernels === null || subKernels.length < 1) { - return 'varying vec2 vTexCoord;\n'; - } else { - return 'out vec2 vTexCoord;\n'; - } - } - - _getDecode32EndiannessString() { - return ( - this.endianness === 'LE' ? - '' : - ' texel.rgba = texel.abgr;\n' - ); - } - - _getEncode32EndiannessString() { - return ( - this.endianness === 'LE' ? - '' : - ' texel.rgba = texel.abgr;\n' - ); - } - - _getDivideWithIntegerCheckString() { - return this.fixIntegerDivisionAccuracy ? - `float div_with_int_check(float x, float y) { - if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { - return float(int(x)/int(y)); - } - return x / y; -}` : - ''; - } - - _getMainArgumentsString(args) { - const results = []; - const { argumentNames } = this; - for (let i = 0; i < argumentNames.length; i++) { - results.push(this.kernelArguments[i].getSource(args[i])); - } - return results.join(''); - } - - _getInjectedNative() { - return this.injectedNative || ''; - } - - _getMainConstantsString() { - const result = []; - const { constants } = this; - if (constants) { - let i = 0; - for (const name in constants) { - result.push(this.kernelConstants[i++].getSource(this.constants[name])); + if (cases.length === 1 && !cases[0].test) { + this.astGeneric(cases[0].consequent, retArr); + return retArr; } - } - return result.join(''); - } - - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; + let fallingThrough = false; + let defaultResult = []; + let movingDefaultToEnd = false; + let pastFirstIf = false; + for (let i = 0; i < cases.length; i++) { + if (!cases[i].test) { + if (cases.length > i + 1) { + movingDefaultToEnd = true; + this.astGeneric(cases[i].consequent, defaultResult); + continue; + } else { + retArr.push(' else {\n'); + } } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); + if (i === 0 || !pastFirstIf) { + pastFirstIf = true; + retArr.push(`if (${varName} == `); + } else { + if (fallingThrough) { + retArr.push(`${varName} == `); + fallingThrough = false; + } else { + retArr.push(` else if (${varName} == `); + } + } + if (type === 'Integer') { + const testType = this.getType(cases[i].test); + switch (testType) { + case 'Number': + case 'Float': + this.castValueToInteger(cases[i].test, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(cases[i].test, retArr); + break; + } + } else if (type === 'Float') { + const testType = this.getType(cases[i].test); + switch (testType) { + case 'LiteralInteger': + this.castLiteralToFloat(cases[i].test, retArr); + break; + case 'Integer': + this.castValueToFloat(cases[i].test, retArr); + break; + } + } else { + throw new Error('unhanlded'); + } + if (!cases[i].consequent || cases[i].consequent.length === 0) { + fallingThrough = true; + retArr.push(' || '); + continue; + } + retArr.push(`) {\n`); } + this.astGeneric(cases[i].consequent, retArr); + retArr.push('\n}'); + } + if (movingDefaultToEnd) { + retArr.push(' else {'); + retArr.push(defaultResult.join('')); + retArr.push('}'); + } + return retArr; } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration - ); - switch (this.returnType) { + astThisExpression(tNode, retArr) { + retArr.push('this'); + return retArr; + } + astMemberExpression(mNode, retArr) { + const { + property, + name, + signature, + origin, + type, + xProperty, + yProperty, + zProperty + } = this.getMemberExpressionDetails(mNode); + switch (signature) { + case 'value.thread.value': + case 'this.thread.value': + if (name !== 'x' && name !== 'y' && name !== 'z') { + throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode); + } + retArr.push(`threadId.${name}`); + return retArr; + case 'this.output.value': + if (this.dynamicOutput) { + switch (name) { + case 'x': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.x)'); + } else { + retArr.push('uOutputDim.x'); + } + break; + case 'y': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.y)'); + } else { + retArr.push('uOutputDim.y'); + } + break; + case 'z': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.z)'); + } else { + retArr.push('uOutputDim.z'); + } + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + } else { + switch (name) { + case 'x': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[0]); + } else { + retArr.push(this.output[0], '.0'); + } + break; + case 'y': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[1]); + } else { + retArr.push(this.output[1], '.0'); + } + break; + case 'z': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[2]); + } else { + retArr.push(this.output[2], '.0'); + } + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + } + return retArr; + case 'value': + throw this.astErrorOutput('Unexpected expression', mNode); + case 'value[]': + case 'value[][]': + case 'value[][][]': + case 'value[][][][]': + case 'value.value': + if (origin === 'Math') { + retArr.push(Math[name]); + return retArr; + } + switch (property) { + case 'r': + retArr.push(`user_${ name }.r`); + return retArr; + case 'g': + retArr.push(`user_${ name }.g`); + return retArr; + case 'b': + retArr.push(`user_${ name }.b`); + return retArr; + case 'a': + retArr.push(`user_${ name }.a`); + return retArr; + } + break; + case 'this.constants.value': + if (typeof xProperty === 'undefined') { + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + retArr.push(`constants_${ name }`); + return retArr; + } + } + case 'this.constants.value[]': + case 'this.constants.value[][]': + case 'this.constants.value[][][]': + case 'this.constants.value[][][][]': + break; + case 'fn()[]': + this.astCallExpression(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push(']'); + return retArr; + case '[][]': + this.astArrayExpression(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push(']'); + return retArr; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + if (mNode.computed === false) { + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + retArr.push(`${origin}_${name}`); + return retArr; + } + } + const markupName = `${origin}_${name}`; + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + this.astGeneric(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(xProperty)); + retArr.push(']'); + break; + case 'HTMLImageArray': + retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(1)': + retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(2)': + case 'Array2D(2)': + case 'Array3D(2)': + retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(2)': + retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(3)': + case 'Array2D(3)': + case 'Array3D(3)': + retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(3)': + retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(4)': + case 'Array2D(4)': + case 'Array3D(4)': + retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(4)': + case 'HTMLImage': + case 'HTMLVideo': + retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'NumberTexture': + case 'Array': + case 'Array2D': + case 'Array3D': + case 'Array4D': + case 'Input': case 'Number': case 'Float': case 'Integer': - for (let i = 0; i < subKernels.length; i++) { - const subKernel = subKernels[i]; - result.push( - subKernel.returnType === 'Integer' ? - `int subKernelResult_${ subKernel.name } = 0` : - `float subKernelResult_${ subKernel.name } = 0.0` - ); - } - break; - case 'Array(2)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec2 subKernelResult_${ subKernels[i].name }` - ); - } - break; - case 'Array(3)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec3 subKernelResult_${ subKernels[i].name }` + if (this.precision === 'single') { + retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + } else { + const bitRatio = (origin === 'user' ? + this.lookupFunctionArgumentBitRatio(this.name, name) : + this.constantBitRatios[name] ); + switch (bitRatio) { + case 1: + retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + case 2: + retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + case 4: + case 0: + retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + default: + throw new Error(`unhandled bit ratio of ${bitRatio}`); + } + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); } break; - case 'Array(4)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec4 subKernelResult_${ subKernels[i].name }` - ); - } + case 'MemoryOptimizedNumberTexture': + retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); break; + default: + throw new Error(`unhandled member expression "${ type }"`); } - } else { - result.push( - kernelResultDeclaration - ); - } - - return utils.linesToString(result) + this.translatedSource; - } - - getMainResultGraphical() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragColor = actualColor', - ]); - } - - getMainResultPackedPixels() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return this.getMainResultKernelPackedPixels() + - this.getMainResultSubKernelPackedPixels(); - default: - throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); + return retArr; } - } - - getMainResultKernelPackedPixels() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` - ]); - } - - getMainResultSubKernelPackedPixels() { - const result = []; - if (!this.subKernels) return ''; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` - ); + astCallExpression(ast, retArr) { + if (!ast.callee) { + throw this.astErrorOutput('Unknown CallExpression', ast); + } + let functionName = null; + const isMathFunction = this.isAstMathFunction(ast); + if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) { + functionName = ast.callee.property.name; + } + else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) { + functionName = ast.callee.expressions[1].property.name; } else { - result.push( - ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` - ); + functionName = ast.callee.name; } - } - return utils.linesToString(result); - } - - getMainResultMemoryOptimizedFloats() { - const result = [ - ' index *= 4', - ]; - - switch (this.returnType) { - case 'Number': - case 'Integer': - case 'Float': - const channels = ['r', 'g', 'b', 'a']; - for (let i = 0; i < channels.length; i++) { - const channel = channels[i]; - this.getMainResultKernelMemoryOptimizedFloats(result, channel); - this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); - if (i + 1 < channels.length) { - result.push(' index += 1'); + if (!functionName) { + throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); + } + if (functionName === 'atan2') { + functionName = 'atan'; + } + if (this.calledFunctions.indexOf(functionName) < 0) { + this.calledFunctions.push(functionName); + } + if (functionName === 'random' && this.plugins && this.plugins.length > 0) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) { + retArr.push(plugin.functionReplace); + return retArr; + } + } + } + if (this.onFunctionCall) { + this.onFunctionCall(this.name, functionName, ast.arguments); + } + retArr.push(functionName); + retArr.push('('); + if (isMathFunction) { + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + const argumentType = this.getType(argument); + if (i > 0) { + retArr.push(', '); + } + switch (argumentType) { + case 'Integer': + this.castValueToFloat(argument, retArr); + break; + default: + this.astGeneric(argument, retArr); + break; } } - break; - default: - throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); - } - - return utils.linesToString(result); - } - - getMainResultKernelMemoryOptimizedFloats(result, channel) { - result.push( - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` gl_FragData[0].${channel} = kernelResult`, - ); - } - - getMainResultSubKernelMemoryOptimizedFloats(result, channel) { - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`, - ); } else { - result.push( - ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`, - ); + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + let targetType = targetTypes[i]; + if (i > 0) { + retArr.push(', '); + } + const argumentType = this.getType(argument); + if (!targetType) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); + targetType = argumentType; + } + switch (argumentType) { + case 'Number': + case 'Float': + if (targetType === 'Integer') { + retArr.push('int('); + this.astGeneric(argument, retArr); + retArr.push(')'); + continue; + } else if (targetType === 'Number' || targetType === 'Float') { + this.astGeneric(argument, retArr); + continue; + } else if (targetType === 'LiteralInteger') { + this.castLiteralToFloat(argument, retArr); + continue; + } + break; + case 'Integer': + if (targetType === 'Number' || targetType === 'Float') { + retArr.push('float('); + this.astGeneric(argument, retArr); + retArr.push(')'); + continue; + } else if (targetType === 'Integer') { + this.astGeneric(argument, retArr); + continue; + } + break; + case 'LiteralInteger': + if (targetType === 'Integer') { + this.castLiteralToInteger(argument, retArr); + continue; + } else if (targetType === 'Number' || targetType === 'Float') { + this.castLiteralToFloat(argument, retArr); + continue; + } else if (targetType === 'LiteralInteger') { + this.astGeneric(argument, retArr); + continue; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + if (targetType === argumentType) { + if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name}`); + continue; + } + break; + case 'HTMLImage': + case 'HTMLImageArray': + case 'HTMLVideo': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'Array': + case 'Input': + if (targetType === argumentType) { + if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); + continue; + } + break; + } + throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); + } } + retArr.push(')'); + return retArr; } - } - - getMainResultKernelNumberTexture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult', - ]; - } - - getMainResultSubKernelNumberTexture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`, - ); + astArrayExpression(arrNode, retArr) { + const arrLen = arrNode.elements.length; + retArr.push('vec' + arrLen + '('); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + this.astGeneric(subNode, retArr); + } + retArr.push(')'); + return retArr; + } + memberExpressionXYZ(x, y, z, retArr) { + if (z) { + retArr.push(this.memberExpressionPropertyMarkup(z), ', '); } else { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`, - ); + retArr.push('0, '); + } + if (y) { + retArr.push(this.memberExpressionPropertyMarkup(y), ', '); + } else { + retArr.push('0, '); } + retArr.push(this.memberExpressionPropertyMarkup(x)); + return retArr; } - return result; - } - - getMainResultKernelArray2Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult[0]', - ' gl_FragData[0][1] = kernelResult[1]', - ]; - } + memberExpressionPropertyMarkup(property) { + if (!property) { + throw new Error('Property not set'); + } + const type = this.getType(property); + const result = []; + switch (type) { + case 'Number': + case 'Float': + this.castValueToInteger(property, result); + break; + case 'LiteralInteger': + this.castLiteralToInteger(property, result); + break; + default: + this.astGeneric(property, result); + } + return result.join(''); + } + } + const typeMap$2 = { + 'Array': 'sampler2D', + 'Array(2)': 'vec2', + 'Array(3)': 'vec3', + 'Array(4)': 'vec4', + 'Array2D': 'sampler2D', + 'Array3D': 'sampler2D', + 'Boolean': 'bool', + 'Float': 'float', + 'Input': 'sampler2D', + 'Integer': 'int', + 'Number': 'float', + 'LiteralInteger': 'float', + 'NumberTexture': 'sampler2D', + 'MemoryOptimizedNumberTexture': 'sampler2D', + 'ArrayTexture(1)': 'sampler2D', + 'ArrayTexture(2)': 'sampler2D', + 'ArrayTexture(3)': 'sampler2D', + 'ArrayTexture(4)': 'sampler2D', + 'HTMLVideo': 'sampler2D', + 'HTMLImage': 'sampler2D', + 'HTMLImageArray': 'sampler2DArray', + }; + const operatorMap = { + '===': '==', + '!==': '!=' + }; - getMainResultSubKernelArray2Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ); - } - return result; - } + const source = ` + +uniform highp float triangle_noise_seed; +highp float triangle_noise_shift = 0.000001; + +//https://www.shadertoy.com/view/4t2SDh +//note: uniformly distributed, normalized rand, [0;1[ +float nrand( vec2 n ) +{ + return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); +} +//note: remaps v to [0;1] in interval [a;b] +float remap( float a, float b, float v ) +{ + return clamp( (v-a) / (b-a), 0.0, 1.0 ); +} + +float n4rand( vec2 n ) +{ + float t = fract( triangle_noise_seed + triangle_noise_shift ); + float nrnd0 = nrand( n + 0.07*t ); + float nrnd1 = nrand( n + 0.11*t ); + float nrnd2 = nrand( n + 0.13*t ); + float nrnd3 = nrand( n + 0.17*t ); + float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; + triangle_noise_shift = result + 0.000001; + return result; +}`; + const name$1 = 'triangle-noise-noise'; + const functionMatch = 'Math.random()'; + const functionReplace = 'n4rand(vTexCoord)'; + const functionReturnType = 'Number'; + const onBeforeRun = (kernel) => { + kernel.setUniform1f('triangle_noise_seed', Math.random()); + }; + var triangleNoise = { + name: name$1, + onBeforeRun, + functionMatch, + functionReplace, + functionReturnType, + source + }; - getMainResultKernelArray3Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult[0]', - ' gl_FragData[0][1] = kernelResult[1]', - ' gl_FragData[0][2] = kernelResult[2]', - ]; - } + const fragmentShader = `__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +varying vec2 vTexCoord; + +vec4 round(vec4 x) { + return floor(x + 0.5); +} + +float round(float x) { + return floor(x + 0.5); +} + +const int BIT_COUNT = 32; +int modi(int x, int y) { + return x - y * (x / y); +} + +int bitwiseOr(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseXOR(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseAnd(int a, int b) { + int result = 0; + int n = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 && b > 0)) { + break; + } + } + return result; +} +int bitwiseNot(int a) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if (modi(a, 2) == 0) { + result += n; + } + a = a / 2; + n = n * 2; + } + return result; +} +int bitwiseZeroFillLeftShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n *= 2; + } + + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +int bitwiseSignedRightShift(int num, int shifts) { + return int(floor(float(num) / pow(2.0, float(shifts)))); +} + +int bitwiseZeroFillRightShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n /= 2; + } + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +vec2 integerMod(vec2 x, float y) { + vec2 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec3 integerMod(vec3 x, float y) { + vec3 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec4 integerMod(vec4 x, vec4 y) { + vec4 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +float integerMod(float x, float y) { + float res = floor(mod(x, y)); + return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); +} + +int integerMod(int x, int y) { + return x - (y * int(x / y)); +} + +__DIVIDE_WITH_INTEGER_CHECK__; + +// Here be dragons! +// DO NOT OPTIMIZE THIS CODE +// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE +// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME +const vec2 MAGIC_VEC = vec2(1.0, -256.0); +const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); +const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 +float decode32(vec4 texel) { + __DECODE32_ENDIANNESS__; + texel *= 255.0; + vec2 gte128; + gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; + gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; + float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); + float res = exp2(round(exponent)); + texel.b = texel.b - 128.0 * gte128.x; + res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; + res *= gte128.y * -2.0 + 1.0; + return res; +} + +float decode16(vec4 texel, int index) { + int channel = integerMod(index, 2); + if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; + if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; + return 0.0; +} + +float decode8(vec4 texel, int index) { + int channel = integerMod(index, 4); + if (channel == 0) return texel.r * 255.0; + if (channel == 1) return texel.g * 255.0; + if (channel == 2) return texel.b * 255.0; + if (channel == 3) return texel.a * 255.0; + return 0.0; +} + +vec4 legacyEncode32(float f) { + float F = abs(f); + float sign = f < 0.0 ? 1.0 : 0.0; + float exponent = floor(log2(F)); + float mantissa = (exp2(-exponent) * F); + // exponent += floor(log2(mantissa)); + vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; + texel.rg = integerMod(texel.rg, 256.0); + texel.b = integerMod(texel.b, 128.0); + texel.a = exponent*0.5 + 63.5; + texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; + texel = floor(texel); + texel *= 0.003921569; // 1/255 + __ENCODE32_ENDIANNESS__; + return texel; +} + +// https://github.com/gpujs/gpu.js/wiki/Encoder-details +vec4 encode32(float value) { + if (value == 0.0) return vec4(0, 0, 0, 0); + + float exponent; + float mantissa; + vec4 result; + float sgn; + + sgn = step(0.0, -value); + value = abs(value); + + exponent = floor(log2(value)); + + mantissa = value*pow(2.0, -exponent)-1.0; + exponent = exponent+127.0; + result = vec4(0,0,0,0); + + result.a = floor(exponent/2.0); + exponent = exponent - result.a*2.0; + result.a = result.a + 128.0*sgn; + + result.b = floor(mantissa * 128.0); + mantissa = mantissa - result.b / 128.0; + result.b = result.b + exponent*128.0; + + result.g = floor(mantissa*32768.0); + mantissa = mantissa - result.g/32768.0; + + result.r = floor(mantissa*8388608.0); + return result/255.0; +} +// Dragons end here + +int index; +ivec3 threadId; + +ivec3 indexTo3D(int idx, ivec3 texDim) { + int z = int(idx / (texDim.x * texDim.y)); + idx -= z * int(texDim.x * texDim.y); + int y = int(idx / texDim.x); + int x = int(integerMod(idx, texDim.x)); + return ivec3(x, y, z); +} + +float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + return decode32(texel); +} + +float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x * 2; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); + return decode16(texel, index); +} + +float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x * 4; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); + return decode8(texel, index); +} + +float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 4); + index = index / 4; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + if (channel == 0) return texel.r; + if (channel == 1) return texel.g; + if (channel == 2) return texel.b; + if (channel == 3) return texel.a; + return 0.0; +} + +vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture2D(tex, st / vec2(texSize)); +} + +float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return result[0]; +} + +vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec2(result[0], result[1]); +} + +vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int channel = integerMod(index, 2); + index = index / 2; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + if (channel == 0) return vec2(texel.r, texel.g); + if (channel == 1) return vec2(texel.b, texel.a); + return vec2(0.0, 0.0); +} + +vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec3(result[0], result[1], result[2]); +} + +vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); + int vectorIndex = fieldIndex / 4; + int vectorOffset = fieldIndex - vectorIndex * 4; + int readY = vectorIndex / texSize.x; + int readX = vectorIndex - readY * texSize.x; + vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); + + if (vectorOffset == 0) { + return tex1.xyz; + } else if (vectorOffset == 1) { + return tex1.yzw; + } else { + readX++; + if (readX >= texSize.x) { + readX = 0; + readY++; + } + vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); + if (vectorOffset == 2) { + return vec3(tex1.z, tex1.w, tex2.x); + } else { + return vec3(tex1.w, tex2.x, tex2.y); + } + } +} + +vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + return getImage2D(tex, texSize, texDim, z, y, x); +} + +vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + return vec4(texel.r, texel.g, texel.b, texel.a); +} + +vec4 actualColor; +void color(float r, float g, float b, float a) { + actualColor = vec4(r,g,b,a); +} + +void color(float r, float g, float b) { + color(r,g,b,1.0); +} + +void color(sampler2D image) { + actualColor = texture2D(image, vTexCoord); +} + +__INJECTED_NATIVE__; +__MAIN_CONSTANTS__; +__MAIN_ARGUMENTS__; +__KERNEL__; + +void main(void) { + index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; + __MAIN_RESULT__; +}`; - getMainResultSubKernelArray3Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ); - } - return result; - } + const vertexShader = `__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +attribute vec2 aPos; +attribute vec2 aTexCoord; + +varying vec2 vTexCoord; +uniform vec2 ratio; + +void main(void) { + gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); + vTexCoord = aTexCoord; +}`; - getMainResultKernelArray4Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0] = kernelResult', - ]; + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; } - getMainResultSubKernelArray4Texture() { - const result = []; - if (!this.subKernels) return result; - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`, - ); - } else { - result.push( - ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`, - ); + var glWiretap_1 = createCommonjsModule(function (module) { + function glWiretap(gl, options = {}) { + const { + contextName = 'gl', + throwGetError, + useTrackablePrimitives, + readPixelsFile, + recording = [], + variables = {}, + onReadPixels, + onUnrecognizedArgumentLookup, + } = options; + const proxy = new Proxy(gl, { get: listen }); + const contextVariables = []; + const entityNames = {}; + let imageCount = 0; + let indent = ''; + let readPixelsVariableName; + return proxy; + function listen(obj, property) { + switch (property) { + case 'addComment': return addComment; + case 'checkThrowError': return checkThrowError; + case 'getReadPixelsVariableName': return readPixelsVariableName; + case 'insertVariable': return insertVariable; + case 'reset': return reset; + case 'setIndent': return setIndent; + case 'toString': return toString; + case 'getContextVariableName': return getContextVariableName; + } + if (typeof gl[property] === 'function') { + return function() { + switch (property) { + case 'getError': + if (throwGetError) { + recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`); + } else { + recording.push(`${indent}${contextName}.getError();`); + } + return gl.getError(); + case 'getExtension': { + const variableName = `${contextName}Variables${contextVariables.length}`; + recording.push(`${indent}const ${variableName} = ${contextName}.getExtension('${arguments[0]}');`); + const extension = gl.getExtension(arguments[0]); + if (extension && typeof extension === 'object') { + const tappedExtension = glExtensionWiretap(extension, { + getEntity, + useTrackablePrimitives, + recording, + contextName: variableName, + contextVariables, + variables, + indent, + onUnrecognizedArgumentLookup, + }); + contextVariables.push(tappedExtension); + return tappedExtension; + } else { + contextVariables.push(null); + } + return extension; + } + case 'readPixels': + const i = contextVariables.indexOf(arguments[6]); + let targetVariableName; + if (i === -1) { + const variableName = getVariableName(arguments[6]); + if (variableName) { + targetVariableName = variableName; + recording.push(`${indent}${variableName}`); + } else { + targetVariableName = `${contextName}Variable${contextVariables.length}`; + contextVariables.push(arguments[6]); + recording.push(`${indent}const ${targetVariableName} = new ${arguments[6].constructor.name}(${arguments[6].length});`); + } + } else { + targetVariableName = `${contextName}Variable${i}`; + } + readPixelsVariableName = targetVariableName; + const argumentAsStrings = [ + arguments[0], + arguments[1], + arguments[2], + arguments[3], + getEntity(arguments[4]), + getEntity(arguments[5]), + targetVariableName + ]; + recording.push(`${indent}${contextName}.readPixels(${argumentAsStrings.join(', ')});`); + if (readPixelsFile) { + writePPM(arguments[2], arguments[3]); + } + if (onReadPixels) { + onReadPixels(targetVariableName, argumentAsStrings); + } + return gl.readPixels.apply(gl, arguments); + case 'drawBuffers': + recording.push(`${indent}${contextName}.drawBuffers([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup } )}]);`); + return gl.drawBuffers(arguments[0]); } + let result = gl[property].apply(gl, arguments); + switch (typeof result) { + case 'undefined': + recording.push(`${indent}${methodCallToString(property, arguments)};`); + return; + case 'number': + case 'boolean': + if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + contextVariables.push(result = trackablePrimitive(result)); + break; + } + default: + if (result === null) { + recording.push(`${methodCallToString(property, arguments)};`); + } else { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + } + contextVariables.push(result); + } + return result; } - break; - case 'Array(2)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ); - } - break; - case 'Array(3)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ); - } - break; - case 'Array(4)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`, - ); - } - break; - } - - return result; - } - - replaceArtifacts(src, map) { - return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => { - if (map.hasOwnProperty(artifact)) { - return map[artifact]; } - throw `unhandled artifact ${artifact}`; - }); - } - - getFragmentShader(args) { - if (this.compiledFragmentShader !== null) { - return this.compiledFragmentShader; + entityNames[gl[property]] = property; + return gl[property]; } - return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args)); - } - - getVertexShader(args) { - if (this.compiledVertexShader !== null) { - return this.compiledVertexShader; + function toString() { + return recording.join('\n'); } - return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args)); - } - - toString() { - const setupContextString = utils.linesToString([ - `const gl = context`, - ]); - return glKernelString(this.constructor, arguments, this, setupContextString); - } - - destroy(removeCanvasReferences) { - if (this.outputTexture) { - this.context.deleteTexture(this.outputTexture); + function reset() { + while (recording.length > 0) { + recording.pop(); + } } - if (this.buffer) { - this.context.deleteBuffer(this.buffer); + function insertVariable(name, value) { + variables[name] = value; } - if (this.framebuffer) { - this.context.deleteFramebuffer(this.framebuffer); + function getEntity(value) { + const name = entityNames[value]; + if (name) { + return contextName + '.' + name; + } + return value; } - if (this.vertShader) { - this.context.deleteShader(this.vertShader); + function setIndent(spaces) { + indent = ' '.repeat(spaces); } - if (this.fragShader) { - this.context.deleteShader(this.fragShader); + function addVariable(value, source) { + const variableName = `${contextName}Variable${contextVariables.length}`; + recording.push(`${indent}const ${variableName} = ${source};`); + contextVariables.push(value); + return variableName; } - if (this.program) { - this.context.deleteProgram(this.program); + function writePPM(width, height) { + const sourceVariable = `${contextName}Variable${contextVariables.length}`; + const imageVariable = `imageDatum${imageCount}`; + recording.push(`${indent}let ${imageVariable} = ["P3\\n# ${readPixelsFile}.ppm\\n", ${width}, ' ', ${height}, "\\n255\\n"].join("");`); + recording.push(`${indent}for (let i = 0; i < ${imageVariable}.length; i += 4) {`); + recording.push(`${indent} ${imageVariable} += ${sourceVariable}[i] + ' ' + ${sourceVariable}[i + 1] + ' ' + ${sourceVariable}[i + 2] + ' ';`); + recording.push(`${indent}}`); + recording.push(`${indent}if (typeof require !== "undefined") {`); + recording.push(`${indent} require('fs').writeFileSync('./${readPixelsFile}.ppm', ${imageVariable});`); + recording.push(`${indent}}`); + imageCount++; + } + function addComment(value) { + recording.push(`${indent}// ${value}`); + } + function checkThrowError() { + recording.push(`${indent}(() => { +${indent}const error = ${contextName}.getError(); +${indent}if (error !== ${contextName}.NONE) { +${indent} const names = Object.getOwnPropertyNames(gl); +${indent} for (let i = 0; i < names.length; i++) { +${indent} const name = names[i]; +${indent} if (${contextName}[name] === error) { +${indent} throw new Error('${contextName} threw ' + name); +${indent} } +${indent} } +${indent}} +${indent}})();`); } - - const keys = Object.keys(this.textureCache); - - for (let i = 0; i < keys.length; i++) { - const name = keys[i]; - this.context.deleteTexture(this.textureCache[name]); + function methodCallToString(method, args) { + return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; } - - if (this.subKernelOutputTextures) { - for (let i = 0; i < this.subKernelOutputTextures.length; i++) { - this.context.deleteTexture(this.subKernelOutputTextures[i]); + function getVariableName(value) { + if (variables) { + for (const name in variables) { + if (variables[name] === value) { + return name; + } + } } + return null; } - if (removeCanvasReferences) { - const idx = canvases.indexOf(this.canvas); - if (idx >= 0) { - canvases[idx] = null; - maxTexSizes[idx] = null; + function getContextVariableName(value) { + const i = contextVariables.indexOf(value); + if (i !== -1) { + return `${contextName}Variable${i}`; } - } - this.destroyExtensions(); - delete this.context; - delete this.canvas; - } - - destroyExtensions() { - this.extensions.OES_texture_float = null; - this.extensions.OES_texture_float_linear = null; - this.extensions.OES_element_index_uint = null; - this.extensions.WEBGL_draw_buffers = null; - } - - static destroyContext(context) { - const extension = context.getExtension('WEBGL_lose_context'); - if (extension) { - extension.loseContext(); + return null; } } - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); - return json; - } -} - -module.exports = { - WebGLKernel -}; -},{"../../plugins/triangle-noise":110,"../../utils":112,"../function-builder":9,"../gl/kernel":13,"../gl/kernel-string":12,"./fragment-shader":36,"./function-node":37,"./kernel-value-maps":38,"./vertex-shader":69}],69:[function(require,module,exports){ -const vertexShader = `__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -attribute vec2 aPos; -attribute vec2 aTexCoord; - -varying vec2 vTexCoord; -uniform vec2 ratio; - -void main(void) { - gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); - vTexCoord = aTexCoord; -}`; - -module.exports = { - vertexShader -}; -},{}],70:[function(require,module,exports){ -const fragmentShader = `#version 300 es -__HEADER__; -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; -__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; - -const int LOOP_MAX = __LOOP_MAX__; - -__PLUGINS__; -__CONSTANTS__; - -in vec2 vTexCoord; - -const int BIT_COUNT = 32; -int modi(int x, int y) { - return x - y * (x / y); -} - -int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; + function glExtensionWiretap(extension, options) { + const proxy = new Proxy(extension, { get: listen }); + const extensionEntityNames = {}; + const { + contextName, + contextVariables, + getEntity, + useTrackablePrimitives, + recording, + variables, + indent, + onUnrecognizedArgumentLookup, + } = options; + return proxy; + function listen(obj, property) { + if (typeof obj[property] === 'function') { + return function() { + switch (property) { + case 'drawBuffersWEBGL': + recording.push(`${indent}${contextName}.drawBuffersWEBGL([${argumentsToString(arguments[0], { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })}]);`); + return extension.drawBuffersWEBGL(arguments[0]); + } + let result = extension[property].apply(extension, arguments); + switch (typeof result) { + case 'undefined': + recording.push(`${indent}${methodCallToString(property, arguments)};`); + return; + case 'number': + case 'boolean': + if (useTrackablePrimitives && contextVariables.indexOf(trackablePrimitive(result)) === -1) { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + contextVariables.push(result = trackablePrimitive(result)); + } else { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + contextVariables.push(result); + } + break; + default: + if (result === null) { + recording.push(`${methodCallToString(property, arguments)};`); + } else { + recording.push(`${indent}const ${contextName}Variable${contextVariables.length} = ${methodCallToString(property, arguments)};`); + } + contextVariables.push(result); + } + return result; + }; + } + extensionEntityNames[extension[property]] = property; + return extension[property]; } - } - return result; -} -int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; + function getExtensionEntity(value) { + if (extensionEntityNames.hasOwnProperty(value)) { + return `${contextName}.${extensionEntityNames[value]}`; + } + return getEntity(value); } - } - return result; -} -int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; + function methodCallToString(method, args) { + return `${contextName}.${method}(${argumentsToString(args, { contextName, contextVariables, getEntity: getExtensionEntity, addVariable, variables, onUnrecognizedArgumentLookup })})`; } - } - return result; -} -int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; -} -int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; + function addVariable(value, source) { + const variableName = `${contextName}Variable${contextVariables.length}`; + contextVariables.push(value); + recording.push(`${indent}const ${variableName} = ${source};`); + return variableName; } - n *= 2; } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); -} - -int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; + function argumentsToString(args, options) { + const { variables, onUnrecognizedArgumentLookup } = options; + return (Array.from(args).map((arg) => { + const variableName = getVariableName(arg); + if (variableName) { + return variableName; + } + return argumentToString(arg, options); + }).join(', ')); + function getVariableName(value) { + if (variables) { + for (const name in variables) { + if (!variables.hasOwnProperty(name)) continue; + if (variables[name] === value) { + return name; + } + } + } + if (onUnrecognizedArgumentLookup) { + return onUnrecognizedArgumentLookup(value); + } + return null; } - maxBytes *= 2; } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; + function argumentToString(arg, options) { + const { contextName, contextVariables, getEntity, addVariable, onUnrecognizedArgumentLookup } = options; + if (typeof arg === 'undefined') { + return 'undefined'; } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); -} - -int integerMod(int x, int y) { - return x - (y * int(x/y)); -} - -__DIVIDE_WITH_INTEGER_CHECK__; - -// Here be dragons! -// DO NOT OPTIMIZE THIS CODE -// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE -// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME -const vec2 MAGIC_VEC = vec2(1.0, -256.0); -const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); -const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 -float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; -} - -float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; -} - -float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - return texel[channel] * 255.0; -} - -vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; -} - -// https://github.com/gpujs/gpu.js/wiki/Encoder-details -vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; -} -// Dragons end here - -int index; -ivec3 threadId; - -ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); -} - -float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return decode32(texel); -} - -float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); -} - -float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); -} - -float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - index = index / 4; - vec4 texel = texture(tex, st / vec2(texSize)); - return texel[channel]; -} - -vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, st / vec2(texSize)); -} - -vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, vec3(st / vec2(texSize), z)); -} - -float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; -} - -vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); -} - -vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); -} - -vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); -} - -vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); + if (arg === null) { + return 'null'; } - } -} - -vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); -} - -vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); -} - -vec4 actualColor; -void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); -} - -void color(float r, float g, float b) { - color(r,g,b,1.0); -} - -__INJECTED_NATIVE__; -__MAIN_CONSTANTS__; -__MAIN_ARGUMENTS__; -__KERNEL__; - -void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; -}`; - -module.exports = { - fragmentShader -}; -},{}],71:[function(require,module,exports){ -const { WebGLFunctionNode } = require('../web-gl/function-node'); - -class WebGL2FunctionNode extends WebGLFunctionNode { - - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput( - 'IdentifierExpression - not an Identifier', - idtNode - ); + const i = contextVariables.indexOf(arg); + if (i > -1) { + return `${contextName}Variable${i}`; } - - const type = this.getType(idtNode); - - if (idtNode.name === 'Infinity') { - retArr.push('intBitsToFloat(2139095039)'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${idtNode.name}`); - } - } else { - retArr.push(`user_${idtNode.name}`); + switch (arg.constructor.name) { + case 'String': + const hasLines = /\n/.test(arg); + const hasSingleQuotes = /'/.test(arg); + const hasDoubleQuotes = /"/.test(arg); + if (hasLines) { + return '`' + arg + '`'; + } else if (hasSingleQuotes && !hasDoubleQuotes) { + return '"' + arg + '"'; + } else if (!hasSingleQuotes && hasDoubleQuotes) { + return "'" + arg + "'"; + } else { + return '\'' + arg + '\''; + } + case 'Number': return getEntity(arg); + case 'Boolean': return getEntity(arg); + case 'Array': + return addVariable(arg, `new ${arg.constructor.name}([${Array.from(arg).join(',')}])`); + case 'Float32Array': + case 'Uint8Array': + case 'Uint16Array': + case 'Int32Array': + return addVariable(arg, `new ${arg.constructor.name}(${JSON.stringify(Array.from(arg))})`); + default: + if (onUnrecognizedArgumentLookup) { + const instantiationString = onUnrecognizedArgumentLookup(arg); + if (instantiationString) { + return instantiationString; + } + } + throw new Error(`unrecognized argument type ${arg.constructor.name}`); } - - return retArr; - } -} - -module.exports = { - WebGL2FunctionNode -}; -},{"../web-gl/function-node":37}],72:[function(require,module,exports){ -const { WebGL2KernelValueBoolean } = require('./kernel-value/boolean'); -const { WebGL2KernelValueFloat } = require('./kernel-value/float'); -const { WebGL2KernelValueInteger } = require('./kernel-value/integer'); - -const { WebGL2KernelValueHTMLImage } = require('./kernel-value/html-image'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image'); - -const { WebGL2KernelValueHTMLImageArray } = require('./kernel-value/html-image-array'); -const { WebGL2KernelValueDynamicHTMLImageArray } = require('./kernel-value/dynamic-html-image-array'); - -const { WebGL2KernelValueHTMLVideo } = require('./kernel-value/html-video'); -const { WebGL2KernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video'); - -const { WebGL2KernelValueSingleInput } = require('./kernel-value/single-input'); -const { WebGL2KernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input'); - -const { WebGL2KernelValueUnsignedInput } = require('./kernel-value/unsigned-input'); -const { WebGL2KernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input'); - -const { WebGL2KernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture'); -const { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture'); - -const { WebGL2KernelValueNumberTexture } = require('./kernel-value/number-texture'); -const { WebGL2KernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture'); - -const { WebGL2KernelValueSingleArray } = require('./kernel-value/single-array'); -const { WebGL2KernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array'); - -const { WebGL2KernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i'); -const { WebGL2KernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i'); - -const { WebGL2KernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i'); -const { WebGL2KernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i'); - -const { WebGL2KernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i'); -const { WebGL2KernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i'); - -const { WebGL2KernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGL2KernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGL2KernelValueSingleArray4 } = require('./kernel-value/single-array4'); - -const { WebGL2KernelValueUnsignedArray } = require('./kernel-value/unsigned-array'); -const { WebGL2KernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array'); - -const kernelValueMaps = { - unsigned: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGL2KernelValueDynamicUnsignedInput, - 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGL2KernelValueUnsignedInput, - 'NumberTexture': WebGL2KernelValueNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI, - 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI, - 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI, - 'Input': WebGL2KernelValueDynamicSingleInput, - 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - 'Array1D(2)': WebGL2KernelValueSingleArray1DI, - 'Array1D(3)': WebGL2KernelValueSingleArray1DI, - 'Array1D(4)': WebGL2KernelValueSingleArray1DI, - 'Array2D(2)': WebGL2KernelValueSingleArray2DI, - 'Array2D(3)': WebGL2KernelValueSingleArray2DI, - 'Array2D(4)': WebGL2KernelValueSingleArray2DI, - 'Array3D(2)': WebGL2KernelValueSingleArray3DI, - 'Array3D(3)': WebGL2KernelValueSingleArray3DI, - 'Array3D(4)': WebGL2KernelValueSingleArray3DI, - 'Input': WebGL2KernelValueSingleInput, - 'NumberTexture': WebGL2KernelValueNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, -}; - -function lookupKernelValueType(type, dynamic, precision, value) { - if (!type) { - throw new Error('type missing'); - } - if (!dynamic) { - throw new Error('dynamic missing'); - } - if (!precision) { - throw new Error('precision missing'); - } - if (value.type) { - type = value.type; - } - const types = kernelValueMaps[precision][dynamic]; - if (types[type] === false) { - return null; - } else if (types[type] === undefined) { - throw new Error(`Could not find a KernelValue for ${ type }`); - } - return types[type]; -} - -module.exports = { - kernelValueMaps, - lookupKernelValueType -}; -},{"./kernel-value/boolean":73,"./kernel-value/dynamic-html-image":75,"./kernel-value/dynamic-html-image-array":74,"./kernel-value/dynamic-html-video":76,"./kernel-value/dynamic-memory-optimized-number-texture":77,"./kernel-value/dynamic-number-texture":78,"./kernel-value/dynamic-single-array":79,"./kernel-value/dynamic-single-array1d-i":80,"./kernel-value/dynamic-single-array2d-i":81,"./kernel-value/dynamic-single-array3d-i":82,"./kernel-value/dynamic-single-input":83,"./kernel-value/dynamic-unsigned-array":84,"./kernel-value/dynamic-unsigned-input":85,"./kernel-value/float":86,"./kernel-value/html-image":88,"./kernel-value/html-image-array":87,"./kernel-value/html-video":89,"./kernel-value/integer":90,"./kernel-value/memory-optimized-number-texture":91,"./kernel-value/number-texture":92,"./kernel-value/single-array":93,"./kernel-value/single-array1d-i":94,"./kernel-value/single-array2":95,"./kernel-value/single-array2d-i":96,"./kernel-value/single-array3":97,"./kernel-value/single-array3d-i":98,"./kernel-value/single-array4":99,"./kernel-value/single-input":100,"./kernel-value/unsigned-array":101,"./kernel-value/unsigned-input":102}],73:[function(require,module,exports){ -const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean'); - -class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - -module.exports = { - WebGL2KernelValueBoolean -}; -},{"../../web-gl/kernel-value/boolean":39}],74:[function(require,module,exports){ -const { WebGL2KernelValueHTMLImageArray } = require('./html-image-array'); - -class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2DArray ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(images) { - const { width, height } = images[0]; - this.checkSize(width, height); - this.dimensions = [width, height, images.length]; - this.textureSize = [width, height]; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(images); - } -} - -module.exports = { - WebGL2KernelValueDynamicHTMLImageArray -}; -},{"./html-image-array":87}],75:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicHTMLImage } = require('../../web-gl/kernel-value/dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicHTMLImage -}; -},{"../../../utils":112,"../../web-gl/kernel-value/dynamic-html-image":40}],76:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} - -module.exports = { - WebGL2KernelValueDynamicHTMLVideo -}; -},{"../../../utils":112,"./dynamic-html-image":75}],77:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/dynamic-memory-optimized-number-texture'); - -class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicMemoryOptimizedNumberTexture -}; -},{"../../../utils":112,"../../web-gl/kernel-value/dynamic-memory-optimized-number-texture":42}],78:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicNumberTexture } = require('../../web-gl/kernel-value/dynamic-number-texture'); - -class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicNumberTexture -}; -},{"../../../utils":112,"../../web-gl/kernel-value/dynamic-number-texture":43}],79:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray } = require('../../web-gl2/kernel-value/single-array'); - -class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray -}; -},{"../../../utils":112,"../../web-gl2/kernel-value/single-array":93}],80:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray1DI } = require('../../web-gl2/kernel-value/single-array1d-i'); - -class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray1DI -}; -},{"../../../utils":112,"../../web-gl2/kernel-value/single-array1d-i":94}],81:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray2DI } = require('../../web-gl2/kernel-value/single-array2d-i'); - -class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray2DI -}; -},{"../../../utils":112,"../../web-gl2/kernel-value/single-array2d-i":96}],82:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray3DI } = require('../../web-gl2/kernel-value/single-array3d-i'); - -class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray3DI -}; -},{"../../../utils":112,"../../web-gl2/kernel-value/single-array3d-i":98}],83:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleInput } = require('../../web-gl2/kernel-value/single-input'); - -class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleInput -}; -},{"../../../utils":112,"../../web-gl2/kernel-value/single-input":100}],84:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicUnsignedArray } = require('../../web-gl/kernel-value/dynamic-unsigned-array'); - -class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicUnsignedArray -}; -},{"../../../utils":112,"../../web-gl/kernel-value/dynamic-unsigned-array":49}],85:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicUnsignedInput } = require('../../web-gl/kernel-value/dynamic-unsigned-input'); - -class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicUnsignedInput -}; -},{"../../../utils":112,"../../web-gl/kernel-value/dynamic-unsigned-input":50}],86:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueFloat } = require('../../web-gl/kernel-value/float'); - -class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - -module.exports = { - WebGL2KernelValueFloat -}; -},{"../../../utils":112,"../../web-gl/kernel-value/float":51}],87:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('../../web-gl/kernel-value/index'); - -class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.checkSize(value[0].width, value[0].height); - this.requestTexture(); - this.dimensions = [value[0].width, value[0].height, value.length]; - this.textureSize = [value[0].width, value[0].height]; + function trackablePrimitive(value) { + return new value.constructor(value); } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; + { + module.exports = { glWiretap, glExtensionWiretap }; } - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2DArray ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); + if (typeof window !== 'undefined') { + glWiretap.glExtensionWiretap = glExtensionWiretap; + window.glWiretap = glWiretap; } - - updateValue(images) { - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - gl.texImage3D( - gl.TEXTURE_2D_ARRAY, - 0, - gl.RGBA, - images[0].width, - images[0].height, - images.length, - 0, - gl.RGBA, - gl.UNSIGNED_BYTE, - null - ); - for (let i = 0; i < images.length; i++) { - const xOffset = 0; - const yOffset = 0; - const imageDepth = 1; - gl.texSubImage3D( - gl.TEXTURE_2D_ARRAY, - 0, - xOffset, - yOffset, - i, - images[i].width, - images[i].height, - imageDepth, - gl.RGBA, - gl.UNSIGNED_BYTE, - this.uploadValue = images[i] + }); + var glWiretap_2 = glWiretap_1.glWiretap; + var glWiretap_3 = glWiretap_1.glExtensionWiretap; + + function toStringWithoutUtils(fn) { + return fn.toString() + .replace('=>', '') + .replace(/^function /, '') + .replace(/utils[.]/g, '/*utils.*/'); + } + function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { + args = args ? Array.from(args).map(arg => { + switch (typeof arg) { + case 'boolean': + return new Boolean(arg); + case 'number': + return new Number(arg); + default: + return arg; + } + }) : null; + const postResult = []; + const context = glWiretap_2(originKernel.context, { + useTrackablePrimitives: true, + onReadPixels: (targetName) => { + if (kernel.subKernels) { + if (!subKernelsResultVariableSetup) { + postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`); + subKernelsResultVariableSetup = true; + } else { + const property = kernel.subKernels[subKernelsResultIndex++].property; + postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`); + } + if (subKernelsResultIndex === kernel.subKernels.length) { + postResult.push(' return result;'); + } + return; + } + if (targetName) { + postResult.push(` return ${getRenderString(targetName, kernel)};`); + } else { + postResult.push(` return null;`); + } + }, + onUnrecognizedArgumentLookup: (argument) => { + const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context); + if (argumentName) { + return argumentName; + } + const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context); + if (constantName) { + return constantName; + } + return null; + } + }); + let subKernelsResultVariableSetup = false; + let subKernelsResultIndex = 0; + const { + source, + canvas, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + kernelArguments, + kernelConstants, + } = originKernel; + const kernel = new Kernel(source, { + canvas, + context, + checkContext: false, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + }); + let result = []; + context.setIndent(2); + kernel.build.apply(kernel, args); + result.push(context.toString()); + context.reset(); + kernel.kernelArguments.forEach((kernelArgument, i) => { + switch (kernelArgument.type) { + case 'Integer': + case 'Boolean': + case 'Number': + case 'Float': + case 'Array': + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + case 'HTMLImage': + case 'HTMLVideo': + context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); + break; + case 'HTMLImageArray': + for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) { + const arg = args[i]; + context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]); + } + break; + case 'Input': + context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); + break; + case 'MemoryOptimizedNumberTexture': + case 'NumberTexture': + case 'Array1D(2)': + case 'Array1D(3)': + case 'Array1D(4)': + case 'Array2D(2)': + case 'Array2D(3)': + case 'Array2D(4)': + case 'Array3D(2)': + case 'Array3D(3)': + case 'Array3D(4)': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture); + break; + default: + throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`); + } + }); + result.push('/** start of injected functions **/'); + result.push(`function ${toStringWithoutUtils(utils$1.flattenTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten2dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten3dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.flatten4dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils$1.isArray)}`); + if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) { + result.push( + ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};` ); } - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueHTMLImageArray -}; -},{"../../../utils":112,"../../web-gl/kernel-value/index":54}],88:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('../../web-gl/kernel-value/html-image'); - -class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueHTMLImage -}; -},{"../../../utils":112,"../../web-gl/kernel-value/html-image":52}],89:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueHTMLImage } = require('./html-image'); - -class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} - -module.exports = { - WebGL2KernelValueHTMLVideo -}; -},{"../../../utils":112,"./html-image":88}],90:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueInteger } = require('../../web-gl/kernel-value/integer'); - -class WebGL2KernelValueInteger extends WebGLKernelValueInteger { - getSource(value) { - const variablePrecision = this.getVariablePrecisionString(); - if (this.origin === 'constants') { - return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`; + result.push('/** end of injected functions **/'); + result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`); + context.setIndent(4); + kernel.run.apply(kernel, args); + if (kernel.renderKernels) { + kernel.renderKernels(); + } else if (kernel.renderOutput) { + kernel.renderOutput(); + } + result.push(' /** start setup uploads for kernel values **/'); + kernel.kernelArguments.forEach(kernelArgument => { + result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n ')); + }); + result.push(' /** end setup uploads for kernel values **/'); + result.push(context.toString()); + if (kernel.renderOutput === kernel.renderTexture) { + context.reset(); + const results = kernel.renderKernels(); + const textureName = context.getContextVariableName(kernel.outputTexture); + result.push(` return { + result: { + texture: ${ textureName }, + type: '${ results.result.type }', + toArray: ${ getToArrayString(results.result, textureName) } + },`); + const { subKernels, subKernelOutputTextures } = kernel; + for (let i = 0; i < subKernels.length; i++) { + const texture = subKernelOutputTextures[i]; + const subKernel = subKernels[i]; + const subKernelResult = results[subKernel.property]; + const subKernelTextureName = context.getContextVariableName(texture); + result.push(` + ${subKernel.property}: { + texture: ${ subKernelTextureName }, + type: '${ subKernelResult.type }', + toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } + },`); + } + result.push(` };`); + } + result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`); + result.push(postResult.join('\n')); + result.push(' };'); + if (kernel.graphical) { + result.push(getGetPixelsString(kernel)); + result.push(` innerKernel.getPixels = getPixels;`); } - return `uniform ${ variablePrecision } int ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGL2KernelValueInteger -}; -},{"../../../utils":112,"../../web-gl/kernel-value/integer":55}],91:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/memory-optimized-number-texture'); - -class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { - getSource() { - const { id, sizeId, textureSize, dimensionsId, dimensions } = this; - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform sampler2D ${id}`, - `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, - `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueMemoryOptimizedNumberTexture -}; -},{"../../../utils":112,"../../web-gl/kernel-value/memory-optimized-number-texture":56}],92:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueNumberTexture } = require('../../web-gl/kernel-value/number-texture'); - -class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture { - getSource() { - const { id, sizeId, textureSize, dimensionsId, dimensions } = this; - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${id}`, - `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, - `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueNumberTexture -}; -},{"../../../utils":112,"../../web-gl/kernel-value/number-texture":57}],93:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray } = require('../../web-gl/kernel-value/single-array'); - -class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleArray -}; -},{"../../../utils":112,"../../web-gl/kernel-value/single-array":58}],94:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray1DI } = require('../../web-gl/kernel-value/single-array1d-i'); - -class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleArray1DI -}; -},{"../../../utils":112,"../../web-gl/kernel-value/single-array1d-i":59}],95:[function(require,module,exports){ -const { WebGLKernelValueSingleArray2 } = require('../../web-gl/kernel-value/single-array2'); - -class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} - -module.exports = { - WebGL2KernelValueSingleArray2 -}; -},{"../../web-gl/kernel-value/single-array2":60}],96:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray2DI } = require('../../web-gl/kernel-value/single-array2d-i'); - -class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleArray2DI -}; -},{"../../../utils":112,"../../web-gl/kernel-value/single-array2d-i":61}],97:[function(require,module,exports){ -const { WebGLKernelValueSingleArray3 } = require('../../web-gl/kernel-value/single-array3'); - -class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} - -module.exports = { - WebGL2KernelValueSingleArray3 -}; -},{"../../web-gl/kernel-value/single-array3":62}],98:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray3DI } = require('../../web-gl/kernel-value/single-array3d-i'); - -class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleArray3DI -}; -},{"../../../utils":112,"../../web-gl/kernel-value/single-array3d-i":63}],99:[function(require,module,exports){ -const { WebGLKernelValueSingleArray4 } = require('../../web-gl/kernel-value/single-array4'); - -class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} - -module.exports = { - WebGL2KernelValueSingleArray4 -}; -},{"../../web-gl/kernel-value/single-array4":64}],100:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleInput } = require('../../web-gl/kernel-value/single-input'); - -class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(input) { - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleInput -}; -},{"../../../utils":112,"../../web-gl/kernel-value/single-input":65}],101:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedArray } = require('../../web-gl/kernel-value/unsigned-array'); - -class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueUnsignedArray -}; -},{"../../../utils":112,"../../web-gl/kernel-value/unsigned-array":66}],102:[function(require,module,exports){ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedInput } = require('../../web-gl/kernel-value/unsigned-input'); - -class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); + result.push(' return innerKernel;'); + let constantsUpload = []; + kernelConstants.forEach((kernelConstant) => { + constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`); + }); + return `function kernel(settings) { + const { context, constants } = settings; + ${constantsUpload.join('')} + ${setupContextString ? setupContextString : ''} +${result.join('\n')} +}`; } -} - -module.exports = { - WebGL2KernelValueUnsignedInput -}; -},{"../../../utils":112,"../../web-gl/kernel-value/unsigned-input":67}],103:[function(require,module,exports){ -const { WebGLKernel } = require('../web-gl/kernel'); -const { WebGL2FunctionNode } = require('./function-node'); -const { FunctionBuilder } = require('../function-builder'); -const { utils } = require('../../utils'); -const { fragmentShader } = require('./fragment-shader'); -const { vertexShader } = require('./vertex-shader'); -const { lookupKernelValueType } = require('./kernel-value-maps'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; - -let features = null; - -class WebGL2Kernel extends WebGLKernel { - static get isSupported() { - if (isSupported !== null) { - return isSupported; + function getRenderString(targetName, kernel) { + const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`; + if (kernel.output[2]) { + return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`; } - this.setupFeatureChecks(); - isSupported = this.isContextMatch(testContext); - return isSupported; - } - - static setupFeatureChecks() { - if (typeof document !== 'undefined') { - testCanvas = document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - testCanvas = new OffscreenCanvas(0, 0); - } - if (!testCanvas) return; - testContext = testCanvas.getContext('webgl2'); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - }; - features = this.getFeatures(); - } - - static isContextMatch(context) { - if (typeof WebGL2RenderingContext !== 'undefined') { - return context instanceof WebGL2RenderingContext; + if (kernel.output[1]) { + return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`; } - return false; + return `renderOutput(${readBackValue}, ${kernel.output[0]})`; } - - static getFeatures() { - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - kernelMap: true, - isTextureFloat: true, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), + function getGetPixelsString(kernel) { + const getPixels = kernel.getPixels.toString(); + const useFunctionKeyword = !/^function/.test(getPixels); + return utils$1.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils$1[name].toString()};`; + } + return null; + }, + thisLookup: (property) => { + if (property === 'context') { + return null; + } + if (kernel.hasOwnProperty(property)) { + return JSON.stringify(kernel[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } }); } - - static getIsTextureFloat() { - return true; + function getToArrayString(kernelResult, textureName) { + const toArray = kernelResult.toArray.toString(); + const useFunctionKeyword = !/^function/.test(toArray); + const flattenedFunctions = utils$1.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils$1[name].toString()};`; + } else if (object === 'this') { + return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + } else { + throw new Error('unhandled fromObject'); + } + }, + thisLookup: (property) => { + if (property === 'texture') { + return textureName; + } + if (kernelResult.hasOwnProperty(property)) { + return JSON.stringify(kernelResult[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } + }); + return `() => { + ${flattenedFunctions} + return toArray(); + }`; } - - static getIsIntegerDivisionAccurate() { - return super.getIsIntegerDivisionAccurate(); + function findKernelValue(argument, kernelValues, values, context, uploadedValues) { + if (argument === null) return null; + switch (typeof argument) { + case 'boolean': + case 'number': + return null; + } + if ( + typeof HTMLImageElement !== 'undefined' && + argument instanceof HTMLImageElement + ) { + for (let i = 0; i < kernelValues.length; i++) { + const kernelValue = kernelValues[i]; + if (kernelValue.type !== 'HTMLImageArray') continue; + if (kernelValue.uploadValue !== argument) continue; + const variableIndex = values[i].indexOf(argument); + if (variableIndex === -1) continue; + const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`; + context.insertVariable(variableName, argument); + return variableName; + } + return null; + } + for (let i = 0; i < kernelValues.length; i++) { + const kernelValue = kernelValues[i]; + if (argument !== kernelValue.uploadValue) continue; + const variable = `uploadValue_${kernelValue.name}`; + context.insertVariable(variable, kernelValue); + return variable; + } + return null; } - static getChannelCount() { - return testContext.getParameter(testContext.MAX_DRAW_BUFFERS); + class KernelValue { + constructor(value, settings) { + const { + name, + kernel, + context, + checkContext, + onRequestContextHandle, + onUpdateValueMismatch, + origin, + strictIntegers, + type, + tactic, + } = settings; + if (!name) { + throw new Error('name not set'); + } + if (!type) { + throw new Error('type not set'); + } + if (!origin) { + throw new Error('origin not set'); + } + if (!tactic) { + throw new Error('tactic not set'); + } + if (origin !== 'user' && origin !== 'constants') { + throw new Error(`origin must be "user" or "constants" value is "${ origin }"`); + } + if (!onRequestContextHandle) { + throw new Error('onRequestContextHandle is not set'); + } + this.name = name; + this.origin = origin; + this.tactic = tactic; + this.id = `${this.origin}_${name}`; + this.varName = origin === 'constants' ? `constants.${name}` : name; + this.kernel = kernel; + this.strictIntegers = strictIntegers; + this.type = value.type || type; + this.size = value.size || null; + this.index = null; + this.context = context; + this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true; + this.contextHandle = null; + this.onRequestContextHandle = onRequestContextHandle; + this.onUpdateValueMismatch = onUpdateValueMismatch; + this.forceUploadEachRun = null; + } + getSource() { + throw new Error(`"getSource" not defined on ${ this.constructor.name }`); + } + updateValue(value) { + throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); + } + } + + class WebGLKernelValue extends KernelValue { + constructor(value, settings) { + super(value, settings); + this.dimensionsId = null; + this.sizeId = null; + this.initialValueConstructor = value.constructor; + this.onRequestTexture = settings.onRequestTexture; + this.onRequestIndex = settings.onRequestIndex; + this.uploadValue = null; + this.textureSize = null; + this.bitRatio = null; + } + checkSize(width, height) { + if (!this.kernel.validate) return; + const { maxTextureSize } = this.kernel.constructor.features; + if (width > maxTextureSize || height > maxTextureSize) { + if (width > height) { + throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); + } else { + throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); + } + } + } + requestTexture() { + this.texture = this.onRequestTexture(); + this.setupTexture(); + } + setupTexture() { + this.contextHandle = this.onRequestContextHandle(); + this.index = this.onRequestIndex(); + this.dimensionsId = this.id + 'Dim'; + this.sizeId = this.id + 'Size'; + } + getTransferArrayType(value) { + if (Array.isArray(value[0])) { + return this.getTransferArrayType(value[0]); + } + switch (value.constructor) { + case Array: + case Int32Array: + case Int16Array: + case Int8Array: + return Float32Array; + case Uint8ClampedArray: + case Uint8Array: + case Uint16Array: + case Uint32Array: + case Float32Array: + case Float64Array: + return value.constructor; + } + console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros'); + return value.constructor; + } + formatArrayTransfer(value, length, Type) { + if (utils$1.isArray(value[0]) || this.optimizeFloatMemory) { + const valuesFlat = new Float32Array(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } else { + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + case Uint16Array: + case Int16Array: + case Float32Array: + case Int32Array: { + const valuesFlat = new(Type || value.constructor)(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } + default: { + const valuesFlat = new Float32Array(length); + utils$1.flattenTo(value, valuesFlat); + return valuesFlat; + } + } + } + } + getBitRatio(value) { + if (Array.isArray(value[0])) { + return this.getBitRatio(value[0]); + } else if (value.constructor === Input) { + return this.getBitRatio(value.value); + } + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + return 1; + case Uint16Array: + case Int16Array: + return 2; + case Float32Array: + case Int32Array: + default: + return 4; + } + } + getStringValueHandler() { + throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); + } + getVariablePrecisionString() { + switch (this.tactic) { + case 'speed': + return 'lowp'; + case 'performance': + return 'highp'; + case 'balanced': + default: + return 'mediump'; + } + } } - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); + class WebGLKernelValueBoolean extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const bool ${this.id} = ${value};\n`; + } + return `uniform bool ${this.id};\n`; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); + } } - static lookupKernelValueType(type, dynamic, precision, value) { - return lookupKernelValueType(type, dynamic, precision, value); + class WebGLKernelValueFloat extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource(value) { + if (this.origin === 'constants') { + if (Number.isInteger(value)) { + return `const float ${this.id} = ${value}.0;\n`; + } + return `const float ${this.id} = ${value};\n`; + } + return `uniform float ${this.id};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1f(this.id, this.uploadValue = value); + } } - static get testCanvas() { - return testCanvas; + class WebGLKernelValueInteger extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource(value) { + if (this.origin === 'constants') { + return `const int ${this.id} = ${ parseInt(value) };\n`; + } + return `uniform int ${this.id};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); + } } - static get testContext() { - return testContext; + class WebGLKernelValueHTMLImage extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.requestTexture(); + this.textureSize = [width, height]; + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(inputImage) { + if (inputImage.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.textureSize = [width, height]; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} + + class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} + + class WebGLKernelValueSingleInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}.value, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(input) { + if (input.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(input.value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueUnsignedInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + const [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value.value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, + `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, + `flattenTo(${this.varName}.value, preUploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(input) { + if (input.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(input.value, this.preUploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + const Type = this.getTransferArrayType(value.value); + this.preUploadValue = new Type(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + this.dimensions = value.dimensions; + this.textureSize = value.size; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(inputTexture) { + if (inputTexture.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type }) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(inputTexture) { + this.checkSize(inputTexture.size[0], inputTexture.size[1]); + this.dimensions = inputTexture.dimensions; + this.textureSize = inputTexture.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(inputTexture); + } + } + + class WebGLKernelValueNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + const { size: textureSize, dimensions } = value; + this.bitRatio = this.getBitRatio(value); + this.dimensions = dimensions; + this.textureSize = textureSize; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(inputTexture) { + if (inputTexture.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type}) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = value.dimensions; + this.checkSize(value.size[0], value.size[1]); + this.textureSize = value.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], 1, 1]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flatten2dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flatten3dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + setShape(value) { + const valueDimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flatten4dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } } - static get features() { - return features; + class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } - static get fragmentShader() { - return fragmentShader; - } - static get vertexShader() { - return vertexShader; + class WebGLKernelValueSingleArray2 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`; + } + return `uniform vec2 ${this.id};\n`; + } + getStringValueHandler() { + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform2fv(this.id, this.uploadValue = value); + } } - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - const context = this.canvas.getContext('webgl2', settings); - return context; + class WebGLKernelValueSingleArray3 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`; + } + return `uniform vec3 ${this.id};\n`; + } + getStringValueHandler() { + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform3fv(this.id, this.uploadValue = value); + } } - initExtensions() { - this.extensions = { - EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - }; + class WebGLKernelValueSingleArray4 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`; + } + return `uniform vec4 ${this.id};\n`; + } + getStringValueHandler() { + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform4fv(this.id, this.uploadValue = value); + } } - validateSettings(args) { - if (!this.validate) { - this.texSize = utils.getKernelTextureSize({ + class WebGLKernelValueUnsignedArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + getStringValueHandler() { + return utils$1.linesToString([ + `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, + `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, + `flattenTo(${this.varName}, preUploadValue_${this.name})`, + ]); + } + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.preUploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + const Type = this.getTransferArrayType(value); + this.preUploadValue = new Type(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + const kernelValueMaps = { + unsigned: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGLKernelValueDynamicUnsignedInput, + 'NumberTexture': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGLKernelValueUnsignedInput, + 'NumberTexture': WebGLKernelValueNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI, + 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI, + 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI, + 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI, + 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI, + 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI, + 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI, + 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI, + 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI, + 'Input': WebGLKernelValueDynamicSingleInput, + 'NumberTexture': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + 'Array1D(2)': WebGLKernelValueSingleArray1DI, + 'Array1D(3)': WebGLKernelValueSingleArray1DI, + 'Array1D(4)': WebGLKernelValueSingleArray1DI, + 'Array2D(2)': WebGLKernelValueSingleArray2DI, + 'Array2D(3)': WebGLKernelValueSingleArray2DI, + 'Array2D(4)': WebGLKernelValueSingleArray2DI, + 'Array3D(2)': WebGLKernelValueSingleArray3DI, + 'Array3D(3)': WebGLKernelValueSingleArray3DI, + 'Array3D(4)': WebGLKernelValueSingleArray3DI, + 'Input': WebGLKernelValueSingleInput, + 'NumberTexture': WebGLKernelValueNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, + }; + function lookupKernelValueType(type, dynamic, precision, value) { + if (!type) { + throw new Error('type missing'); + } + if (!dynamic) { + throw new Error('dynamic missing'); + } + if (!precision) { + throw new Error('precision missing'); + } + if (value.type) { + type = value.type; + } + const types = kernelValueMaps[precision][dynamic]; + if (types[type] === false) { + return null; + } else if (types[type] === undefined) { + throw new Error(`Could not find a KernelValue for ${ type }`); + } + return types[type]; + } + + let isSupported = null; + let testCanvas = null; + let testContext = null; + let testExtensions = null; + let features = null; + const plugins$1 = [triangleNoise]; + const canvases = []; + const maxTexSizes = {}; + class WebGLKernel extends GLKernel { + static get isSupported() { + if (isSupported !== null) { + return isSupported; + } + this.setupFeatureChecks(); + isSupported = this.isContextMatch(testContext); + return isSupported; + } + static setupFeatureChecks() { + if (typeof document !== 'undefined') { + testCanvas = document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + testCanvas = new OffscreenCanvas(0, 0); + } + if (!testCanvas) return; + testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); + if (!testContext || !testContext.getExtension) return; + testExtensions = { + OES_texture_float: testContext.getExtension('OES_texture_float'), + OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), + OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), + WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), + }; + features = this.getFeatures(); + } + static isContextMatch(context) { + if (typeof WebGLRenderingContext !== 'undefined') { + return context instanceof WebGLRenderingContext; + } + return false; + } + static getFeatures() { + const isDrawBuffers = this.getIsDrawBuffers(); + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + isTextureFloat: this.getIsTextureFloat(), + isDrawBuffers, + kernelMap: isDrawBuffers, + channelCount: this.getChannelCount(), + }); + } + static getIsTextureFloat() { + return Boolean(testExtensions.OES_texture_float); + } + static getIsDrawBuffers() { + return Boolean(testExtensions.WEBGL_draw_buffers); + } + static getChannelCount() { + return testExtensions.WEBGL_draw_buffers ? + testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : + 1; + } + static lookupKernelValueType(type, dynamic, precision, value) { + return lookupKernelValueType(type, dynamic, precision, value); + } + static get testCanvas() { + return testCanvas; + } + static get testContext() { + return testContext; + } + static get features() { + return features; + } + static get fragmentShader() { + return fragmentShader; + } + static get vertexShader() { + return vertexShader; + } + constructor(source, settings) { + super(source, settings); + this.program = null; + this.pipeline = settings.pipeline; + this.endianness = utils$1.systemEndianness(); + this.extensions = {}; + this.subKernelOutputTextures = null; + this.kernelArguments = null; + this.argumentTextureCount = 0; + this.constantTextureCount = 0; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + this.fragShader = null; + this.vertShader = null; + this.drawBuffersMap = null; + this.outputTexture = null; + this.maxTexSize = null; + this.switchingKernels = false; + this.onRequestSwitchKernel = null; + this.mergeSettings(source.settings || settings); + this.threadDim = null; + this.framebuffer = null; + this.buffer = null; + this.textureCache = {}; + this.programUniformLocationCache = {}; + this.uniform1fCache = {}; + this.uniform1iCache = {}; + this.uniform2fCache = {}; + this.uniform2fvCache = {}; + this.uniform2ivCache = {}; + this.uniform3fvCache = {}; + this.uniform3ivCache = {}; + this.uniform4fvCache = {}; + this.uniform4ivCache = {}; + } + initCanvas() { + if (typeof document !== 'undefined') { + const canvas = document.createElement('canvas'); + canvas.width = 2; + canvas.height = 2; + return canvas; + } else if (typeof OffscreenCanvas !== 'undefined') { + return new OffscreenCanvas(0, 0); + } + } + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings); + } + initPlugins(settings) { + const pluginsToUse = []; + const { source } = this; + if (typeof source === 'string') { + for (let i = 0; i < plugins$1.length; i++) { + const plugin = plugins$1[i]; + if (source.match(plugin.functionMatch)) { + pluginsToUse.push(plugin); + } + } + } else if (typeof source === 'object') { + if (settings.pluginNames) { + for (let i = 0; i < plugins$1.length; i++) { + const plugin = plugins$1[i]; + const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name); + if (usePlugin) { + pluginsToUse.push(plugin); + } + } + } + } + return pluginsToUse; + } + initExtensions() { + this.extensions = { + OES_texture_float: this.context.getExtension('OES_texture_float'), + OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), + OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), + WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), + WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'), + }; + } + validateSettings(args) { + if (!this.validate) { + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + return; + } + const { features } = this.constructor; + if (this.optimizeFloatMemory === true && !features.isTextureFloat) { + throw new Error('Float textures are not supported'); + } else if (this.precision === 'single' && !features.isFloatRead) { + throw new Error('Single precision not supported'); + } else if (!this.graphical && this.precision === null && features.isTextureFloat) { + this.precision = features.isFloatRead ? 'single' : 'unsigned'; + } + if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) { + throw new Error('could not instantiate draw buffers extension'); + } + if (this.fixIntegerDivisionAccuracy === null) { + this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; + } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { + this.fixIntegerDivisionAccuracy = false; + } + this.checkOutput(); + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + const argType = utils$1.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils$1.getDimensions(argType); + } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { + this.output = args[0].output; + } else { + throw new Error('Auto output not supported for input type: ' + argType); + } + } + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); + } + if (this.precision === 'precision') { + this.precision = 'unsigned'; + console.warn('Cannot use graphical mode and single precision at the same time'); + } + this.texSize = utils$1.clone(this.output); + return; + } else if (this.precision === null && features.isTextureFloat) { + this.precision = 'single'; + } + this.texSize = utils$1.getKernelTextureSize({ optimizeFloatMemory: this.optimizeFloatMemory, precision: this.precision, }, this.output); - return; + this.checkTextureSize(); } - - const features = this.constructor.features; - if (this.precision === 'single' && !features.isFloatRead) { - throw new Error('Float texture outputs are not supported'); - } else if (!this.graphical && this.precision === null) { - this.precision = features.isFloatRead ? 'single' : 'unsigned'; + updateMaxTexSize() { + const { texSize, canvas } = this; + if (this.maxTexSize === null) { + let canvasIndex = canvases.indexOf(canvas); + if (canvasIndex === -1) { + canvasIndex = canvases.length; + canvases.push(canvas); + maxTexSizes[canvasIndex] = [texSize[0], texSize[1]]; + } + this.maxTexSize = maxTexSizes[canvasIndex]; + } + if (this.maxTexSize[0] < texSize[0]) { + this.maxTexSize[0] = texSize[0]; + } + if (this.maxTexSize[1] < texSize[1]) { + this.maxTexSize[1] = texSize[1]; + } } - - if (this.fixIntegerDivisionAccuracy === null) { - this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; - } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { - this.fixIntegerDivisionAccuracy = false; + _oldtranslateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + const translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + let requiredChannels = 0; + const returnTypes = functionBuilder.getReturnTypes(); + for (let i = 0; i < returnTypes.length; i++) { + switch (returnTypes[i]) { + case 'Float': + case 'Number': + case 'Integer': + requiredChannels++; + break; + case 'Array(2)': + requiredChannels += 2; + break; + case 'Array(3)': + requiredChannels += 3; + break; + case 'Array(4)': + requiredChannels += 4; + break; + } + } + if (features && requiredChannels > features.channelCount) { + throw new Error('Too many channels!'); + } + return this.translatedSource = translatedSource; } - - this.checkOutput(); - - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); + setupArguments(args) { + this.kernelArguments = []; + this.argumentTextureCount = 0; + const needsArgumentTypes = this.argumentTypes === null; + if (needsArgumentTypes) { + this.argumentTypes = []; } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - switch (argType) { - case 'Array': - this.output = utils.getDimensions(argType); - break; - case 'NumberTexture': - case 'MemoryOptimizedNumberTexture': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - this.output = args[0].output; - break; - default: - throw new Error('Auto output not supported for input type: ' + argType); + this.argumentSizes = []; + this.argumentBitRatios = []; + if (args.length < this.argumentNames.length) { + throw new Error('not enough arguments for kernel'); + } else if (args.length > this.argumentNames.length) { + throw new Error('too many arguments for kernel'); + } + const { context: gl } = this; + let textureIndexes = 0; + for (let index = 0; index < args.length; index++) { + const value = args[index]; + const name = this.argumentNames[index]; + let type; + if (needsArgumentTypes) { + type = utils$1.getVariableType(value, this.strictIntegers); + this.argumentTypes.push(type); + } else { + type = this.argumentTypes[index]; + } + const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]); + if (KernelValue === null) { + return this.requestFallback(args); + } + const kernelArgument = new KernelValue(value, { + name, + type, + tactic: this.tactic, + origin: 'user', + context: gl, + checkContext: this.checkContext, + kernel: this, + strictIntegers: this.strictIntegers, + onRequestTexture: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onUpdateValueMismatch: () => { + this.switchingKernels = true; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + } + }); + this.kernelArguments.push(kernelArgument); + this.argumentSizes.push(kernelArgument.textureSize); + this.argumentBitRatios[index] = kernelArgument.bitRatio; } } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); + setupConstants(args) { + const { context: gl } = this; + this.kernelConstants = []; + this.forceUploadKernelConstants = []; + let needsConstantTypes = this.constantTypes === null; + if (needsConstantTypes) { + this.constantTypes = {}; } - - if (this.precision === 'single') { - console.warn('Cannot use graphical mode and single precision at the same time'); - this.precision = 'unsigned'; + this.constantBitRatios = {}; + let textureIndexes = 0; + for (const name in this.constants) { + const value = this.constants[name]; + let type; + if (needsConstantTypes) { + type = utils$1.getVariableType(value, this.strictIntegers); + this.constantTypes[name] = type; + } else { + type = this.constantTypes[name]; + } + const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value); + if (KernelValue === null) { + return this.requestFallback(args); + } + const kernelValue = new KernelValue(value, { + name, + type, + tactic: this.tactic, + origin: 'constants', + context: this.context, + checkContext: this.checkContext, + kernel: this, + strictIntegers: this.strictIntegers, + onRequestTexture: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount++; + } + }); + this.constantBitRatios[name] = kernelValue.bitRatio; + this.kernelConstants.push(kernelValue); + if (kernelValue.forceUploadEachRun) { + this.forceUploadKernelConstants.push(kernelValue); + } } - - this.texSize = utils.clone(this.output); - return; - } else if (!this.graphical && this.precision === null && features.isTextureFloat) { - this.precision = 'single'; } - - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - - this.checkTextureSize(); - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); + build() { + this.initExtensions(); + this.validateSettings(arguments); + this.setupConstants(arguments); + if (this.fallbackRequested) return; + this.setupArguments(arguments); + if (this.fallbackRequested) return; + this.updateMaxTexSize(); + this.translateSource(); + const failureResult = this.pickRenderStrategy(arguments); + if (failureResult) { + return failureResult; + } + const { texSize, context: gl, canvas } = this; + gl.enable(gl.SCISSOR_TEST); + if (this.pipeline && this.precision === 'single') { + gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + canvas.width = this.maxTexSize[0]; + canvas.height = this.maxTexSize[1]; + } else { + gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + canvas.width = this.maxTexSize[0]; + canvas.height = this.maxTexSize[1]; + } + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) { + threadDim.push(1); + } + const compiledVertexShader = this.getVertexShader(arguments); + const vertShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertShader, compiledVertexShader); + gl.compileShader(vertShader); + this.vertShader = vertShader; + const compiledFragmentShader = this.getFragmentShader(arguments); + const fragShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragShader, compiledFragmentShader); + gl.compileShader(fragShader); + this.fragShader = fragShader; + if (this.debug) { + console.log('GLSL Shader Output:'); + console.log(compiledFragmentShader); + } + if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) { + throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader)); + } + if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) { + throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader)); + } + const program = this.program = gl.createProgram(); + gl.attachShader(program, vertShader); + gl.attachShader(program, fragShader); + gl.linkProgram(program); + this.framebuffer = gl.createFramebuffer(); + this.framebuffer.width = texSize[0]; + this.framebuffer.height = texSize[1]; + const vertices = new Float32Array([-1, -1, + 1, -1, -1, 1, + 1, 1 + ]); + const texCoords = new Float32Array([ + 0, 0, + 1, 0, + 0, 1, + 1, 1 + ]); + const texCoordOffset = vertices.byteLength; + let buffer = this.buffer; + if (!buffer) { + buffer = this.buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW); + } else { + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + } + gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); + gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords); + const aPosLoc = gl.getAttribLocation(this.program, 'aPos'); + gl.enableVertexAttribArray(aPosLoc); + gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0); + const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord'); + gl.enableVertexAttribArray(aTexCoordLoc); + gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + let i = 0; + gl.useProgram(this.program); + for (let p in this.constants) { + this.kernelConstants[i++].updateValue(this.constants[p]); + } + if (!this.immutable) { + this._setupOutputTexture(); + if ( + this.subKernels !== null && + this.subKernels.length > 0 + ) { + this._setupSubOutputTextures(); + } + } } - - if (this.subKernels && this.subKernels.length > 0) { + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + if (this.subKernels && this.subKernels.length > 0) { + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (!subKernel.returnType) { + subKernel.returnType = functionBuilder.getSubKernelResultType(i); + } + } + } + } + run() { + const { kernelArguments, forceUploadKernelConstants } = this; + const texSize = this.texSize; + const gl = this.context; + gl.useProgram(this.program); + gl.scissor(0, 0, texSize[0], texSize[1]); + if (this.dynamicOutput) { + this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); + this.setUniform2iv('uTexSize', texSize); + } + this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); + this.switchingKernels = false; + for (let i = 0; i < forceUploadKernelConstants.length; i++) { + const constant = forceUploadKernelConstants[i]; + constant.updateValue(this.constants[constant.name]); + if (this.switchingKernels) return; + } + for (let i = 0; i < kernelArguments.length; i++) { + kernelArguments[i].updateValue(arguments[i]); + if (this.switchingKernels) return; + } + if (this.plugins) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.onBeforeRun) { + plugin.onBeforeRun(this); + } + } + } + if (this.graphical) { + if (this.pipeline) { + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (!this.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return; + } + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (this.immutable) { + this._setupOutputTexture(); + } + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + getOutputTexture() { + return this.outputTexture; + } + _setupOutputTexture() { + const gl = this.context; + const texSize = this.texSize; + const texture = this.outputTexture = this.context.createTexture(); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } + break; + case 'Array(2)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(3)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(4)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + default: + if (!this.graphical) { + throw new Error('Unhandled return type'); + } + } + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + } + _setupSubOutputTextures() { + const gl = this.context; + const texSize = this.texSize; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (!subKernel.returnType) { - subKernel.returnType = functionBuilder.getSubKernelResultType(i); + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); } } - } - - run() { - const { kernelArguments, texSize, forceUploadKernelConstants } = this; - const gl = this.context; - - gl.useProgram(this.program); - gl.scissor(0, 0, texSize[0], texSize[1]); - - if (this.dynamicOutput) { - this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); - this.setUniform2iv('uTexSize', texSize); + getTextureCache(name) { + if (this.textureCache.hasOwnProperty(name)) { + return this.textureCache[name]; + } + return this.textureCache[name] = this.context.createTexture(); } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.switchingKernels = false; - for (let i = 0; i < forceUploadKernelConstants.length; i++) { - const constant = forceUploadKernelConstants[i]; - constant.updateValue(this.constants[constant.name]); - if (this.switchingKernels) return; + detachTextureCache(name) { + delete this.textureCache[name]; } - for (let i = 0; i < kernelArguments.length; i++) { - kernelArguments[i].updateValue(arguments[i]); - if (this.switchingKernels) return; + setUniform1f(name, value) { + if (this.uniform1fCache.hasOwnProperty(name)) { + const cache = this.uniform1fCache[name]; + if (value === cache) { + return; + } + } + this.uniform1fCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform1f(loc, value); } - - if (this.plugins) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.onBeforeRun) { - plugin.onBeforeRun(this); + setUniform1i(name, value) { + if (this.uniform1iCache.hasOwnProperty(name)) { + const cache = this.uniform1iCache[name]; + if (value === cache) { + return; } } + this.uniform1iCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform1i(loc, value); } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); + setUniform2f(name, value1, value2) { + if (this.uniform2fCache.hasOwnProperty(name)) { + const cache = this.uniform2fCache[name]; + if ( + value1 === cache[0] && + value2 === cache[1] + ) { + return; } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context - }); } - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return; + this.uniform2fCache[name] = [value1, value2]; + const loc = this.getUniformLocation(name); + this.context.uniform2f(loc, value1, value2); + } + setUniform2fv(name, value) { + if (this.uniform2fvCache.hasOwnProperty(name)) { + const cache = this.uniform2fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] + ) { + return; + } + } + this.uniform2fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform2fv(loc, value); + } + setUniform2iv(name, value) { + if (this.uniform2ivCache.hasOwnProperty(name)) { + const cache = this.uniform2ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] + ) { + return; + } + } + this.uniform2ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform2iv(loc, value); + } + setUniform3fv(name, value) { + if (this.uniform3fvCache.hasOwnProperty(name)) { + const cache = this.uniform3fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3fv(loc, value); + } + setUniform3iv(name, value) { + if (this.uniform3ivCache.hasOwnProperty(name)) { + const cache = this.uniform3ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3iv(loc, value); + } + setUniform3fv(name, value) { + if (this.uniform3fvCache.hasOwnProperty(name)) { + const cache = this.uniform3fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3fv(loc, value); + } + setUniform4iv(name, value) { + if (this.uniform4ivCache.hasOwnProperty(name)) { + const cache = this.uniform4ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] && + value[3] === cache[3] + ) { + return; + } + } + this.uniform4ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform4iv(loc, value); + } + setUniform4fv(name, value) { + if (this.uniform4fvCache.hasOwnProperty(name)) { + const cache = this.uniform4fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] && + value[3] === cache[3] + ) { + return; + } + } + this.uniform4fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform4fv(loc, value); + } + getUniformLocation(name) { + if (this.programUniformLocationCache.hasOwnProperty(name)) { + return this.programUniformLocationCache[name]; + } + return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name); + } + _getFragShaderArtifactMap(args) { + return { + HEADER: this._getHeaderString(), + LOOP_MAX: this._getLoopMaxString(), + PLUGINS: this._getPluginsString(), + CONSTANTS: this._getConstantsString(), + DECODE32_ENDIANNESS: this._getDecode32EndiannessString(), + ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(), + DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(), + INJECTED_NATIVE: this._getInjectedNative(), + MAIN_CONSTANTS: this._getMainConstantsString(), + MAIN_ARGUMENTS: this._getMainArgumentsString(args), + KERNEL: this.getKernelString(), + MAIN_RESULT: this.getMainResultString(), + FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), + INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), + SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), + SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), + }; + } + _getVertShaderArtifactMap(args) { + return { + FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), + INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), + SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), + SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), + }; + } + _getHeaderString() { + return ( + this.subKernels !== null ? + '#extension GL_EXT_draw_buffers : require\n' : + '' + ); + } + _getLoopMaxString() { + return ( + this.loopMaxIterations ? + ` ${parseInt(this.loopMaxIterations)};\n` : + ' 1000;\n' + ); + } + _getPluginsString() { + if (!this.plugins) return '\n'; + return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n'); + } + _getConstantsString() { + const result = []; + const { threadDim, texSize } = this; + if (this.dynamicOutput) { + result.push( + 'uniform ivec3 uOutputDim', + 'uniform ivec2 uTexSize' + ); + } else { + result.push( + `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`, + `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})` + ); + } + return utils$1.linesToString(result); + } + _getTextureCoordinate() { + const subKernels = this.subKernels; + if (subKernels === null || subKernels.length < 1) { + return 'varying vec2 vTexCoord;\n'; + } else { + return 'out vec2 vTexCoord;\n'; + } + } + _getDecode32EndiannessString() { + return ( + this.endianness === 'LE' ? + '' : + ' texel.rgba = texel.abgr;\n' + ); + } + _getEncode32EndiannessString() { + return ( + this.endianness === 'LE' ? + '' : + ' texel.rgba = texel.abgr;\n' + ); + } + _getDivideWithIntegerCheckString() { + return this.fixIntegerDivisionAccuracy ? + `float div_with_int_check(float x, float y) { + if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { + return float(int(x)/int(y)); + } + return x / y; +}` : + ''; + } + _getMainArgumentsString(args) { + const results = []; + const { argumentNames } = this; + for (let i = 0; i < argumentNames.length; i++) { + results.push(this.kernelArguments[i].getSource(args[i])); + } + return results.join(''); } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.immutable) { - this._setupOutputTexture(); + _getInjectedNative() { + return this.injectedNative || ''; } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); + _getMainConstantsString() { + const result = []; + const { constants } = this; + if (constants) { + let i = 0; + for (const name in constants) { + result.push(this.kernelConstants[i++].getSource(this.constants[name])); + } } - gl.drawBuffers(this.drawBuffersMap); + return result.join(''); } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - drawBuffers() { - this.context.drawBuffers(this.drawBuffersMap); - } - - getOutputTexture() { - return this.outputTexture; - } - - _setupOutputTexture() { - const { texSize } = this; - const gl = this.context; - const texture = this.outputTexture = gl.createTexture(); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.precision === 'single') { - if (this.pipeline) { + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration + ); switch (this.returnType) { case 'Number': case 'Float': case 'Integer': - if (this.optimizeFloatMemory) { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + for (let i = 0; i < subKernels.length; i++) { + const subKernel = subKernels[i]; + result.push( + subKernel.returnType === 'Integer' ? + `int subKernelResult_${ subKernel.name } = 0` : + `float subKernelResult_${ subKernel.name } = 0.0` + ); } break; case 'Array(2)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec2 subKernelResult_${ subKernels[i].name }` + ); + } + break; + case 'Array(3)': + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec3 subKernelResult_${ subKernels[i].name }` + ); + } break; - case 'Array(3)': case 'Array(4)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec4 subKernelResult_${ subKernels[i].name }` + ); + } break; - default: - throw new Error('Unhandled return type'); } } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + result.push( + kernelResultDeclaration + ); } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + return utils$1.linesToString(result) + this.translatedSource; } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - _setupSubOutputTextures() { - const { texSize } = this; - const gl = this.context; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.precision === 'single') { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); + getMainResultGraphical() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragColor = actualColor', + ]); } - } - - _getHeaderString() { - return ''; - } - - _getTextureCoordinate() { - const subKernels = this.subKernels; - if (subKernels === null || subKernels.length < 1) { - switch (this.tactic) { - case 'speed': - return 'in lowp vec2 vTexCoord;\n'; - case 'performance': - return 'in highp vec2 vTexCoord;\n'; - case 'balanced': - default: - return 'in mediump vec2 vTexCoord;\n'; - } - } else { - switch (this.tactic) { - case 'speed': - return 'out lowp vec2 vTexCoord;\n'; - case 'performance': - return 'out highp vec2 vTexCoord;\n'; - case 'balanced': + getMainResultPackedPixels() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return this.getMainResultKernelPackedPixels() + + this.getMainResultSubKernelPackedPixels(); default: - return 'out mediump vec2 vTexCoord;\n'; + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); } } - } - - _getMainArgumentsString(args) { - const result = []; - const argumentNames = this.argumentNames; - for (let i = 0; i < argumentNames.length; i++) { - result.push(this.kernelArguments[i].getSource(args[i])); + getMainResultKernelPackedPixels() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); } - return result.join(''); - } - - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; + getMainResultSubKernelPackedPixels() { + const result = []; + if (!this.subKernels) return ''; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` + ); } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); + result.push( + ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` + ); } + } + return utils$1.linesToString(result); } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration, - 'layout(location = 0) out vec4 data0' - ); - for (let i = 0; i < subKernels.length; i++) { - const subKernel = subKernels[i]; - result.push( - subKernel.returnType === 'Integer' ? - `int subKernelResult_${ subKernel.name } = 0` : - `float subKernelResult_${ subKernel.name } = 0.0`, - `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }` - ); + getMainResultMemoryOptimizedFloats() { + const result = [ + ' index *= 4', + ]; + switch (this.returnType) { + case 'Number': + case 'Integer': + case 'Float': + const channels = ['r', 'g', 'b', 'a']; + for (let i = 0; i < channels.length; i++) { + const channel = channels[i]; + this.getMainResultKernelMemoryOptimizedFloats(result, channel); + this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); + if (i + 1 < channels.length) { + result.push(' index += 1'); + } + } + break; + default: + throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); } - } else { + return utils$1.linesToString(result); + } + getMainResultKernelMemoryOptimizedFloats(result, channel) { result.push( - 'out vec4 data0', - kernelResultDeclaration + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0].${channel} = kernelResult`, ); } - - return utils.linesToString(result) + this.translatedSource; - } - - getMainResultGraphical() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0 = actualColor', - ]); - } - - getMainResultPackedPixels() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return this.getMainResultKernelPackedPixels() + - this.getMainResultSubKernelPackedPixels(); - default: - throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); - } - } - - getMainResultKernelPackedPixels() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` - ]); - } - - getMainResultSubKernelPackedPixels() { - const result = []; - if (!this.subKernels) return ''; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` - ); - } else { - result.push( - ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` - ); + getMainResultSubKernelMemoryOptimizedFloats(result, channel) { + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`, + ); + } } } - return utils.linesToString(result); - } - - getMainResultMemoryOptimizedFloats() { - const result = [ - ' index *= 4', - ]; - - switch (this.returnType) { - case 'Number': - case 'Integer': - case 'Float': - const channels = ['r', 'g', 'b', 'a']; - for (let i = 0; i < channels.length; i++) { - const channel = channels[i]; - this.getMainResultKernelMemoryOptimizedFloats(result, channel); - this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); - if (i + 1 < channels.length) { - result.push(' index += 1'); - } + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult', + ]; + } + getMainResultSubKernelNumberTexture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`, + ); } - break; - default: - throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); + } + return result; } - - return utils.linesToString(result); - } - - getMainResultKernelMemoryOptimizedFloats(result, channel) { - result.push( - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` data0.${channel} = kernelResult`, - ); - } - - getMainResultSubKernelMemoryOptimizedFloats(result, channel) { - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`, - ); - } else { + getMainResultKernelArray2Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult[0]', + ' gl_FragData[0][1] = kernelResult[1]', + ]; + } + getMainResultSubKernelArray2Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { result.push( - ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`, + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, ); } + return result; } - } - - getMainResultKernelNumberTexture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult', - ]; - } - - getMainResultSubKernelNumberTexture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`, - ); - } else { + getMainResultKernelArray3Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult[0]', + ' gl_FragData[0][1] = kernelResult[1]', + ' gl_FragData[0][2] = kernelResult[2]', + ]; + } + getMainResultSubKernelArray3Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}`, + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, ); } + return result; } - return result; - } - - getMainResultKernelArray2Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult[0]', - ' data0[1] = kernelResult[1]', - ]; - } - - getMainResultSubKernelArray2Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, - ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, - ); - } - return result; - } - - getMainResultKernelArray3Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult[0]', - ' data0[1] = kernelResult[1]', - ' data0[2] = kernelResult[2]', - ]; - } - - getMainResultSubKernelArray3Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, - ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, - ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`, - ); + getMainResultKernelArray4Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0] = kernelResult', + ]; } - return result; - } - - getMainResultKernelArray4Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0 = kernelResult', - ]; - } - - getMainResultSubKernelArray4Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`, - ); + getMainResultSubKernelArray4Texture() { + const result = []; + if (!this.subKernels) return result; + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`, + ); + } + } + break; + case 'Array(2)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ); + } + break; + case 'Array(3)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, + ); + } + break; + case 'Array(4)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, + ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`, + ); + } + break; + } + return result; } - return result; - } - - destroyExtensions() { - this.extensions.EXT_color_buffer_float = null; - this.extensions.OES_texture_float_linear = null; - } - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON(); - return json; - } -} - -module.exports = { - WebGL2Kernel -}; -},{"../../utils":112,"../function-builder":9,"../web-gl/kernel":68,"./fragment-shader":70,"./function-node":71,"./kernel-value-maps":72,"./vertex-shader":104}],104:[function(require,module,exports){ -const vertexShader = `#version 300 es -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -in vec2 aPos; -in vec2 aTexCoord; - -out vec2 vTexCoord; -uniform vec2 ratio; - -void main(void) { - gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); - vTexCoord = aTexCoord; -}`; - -module.exports = { - vertexShader -}; -},{}],105:[function(require,module,exports){ -const lib = require('./index'); -const GPU = lib.GPU; -for (const p in lib) { - if (!lib.hasOwnProperty(p)) continue; - if (p === 'GPU') continue; - GPU[p] = lib[p]; -} -module.exports = GPU; -},{"./index":107}],106:[function(require,module,exports){ -const { gpuMock } = require('gpu-mock.js'); -const { utils } = require('./utils'); -const { CPUKernel } = require('./backend/cpu/kernel'); -const { HeadlessGLKernel } = require('./backend/headless-gl/kernel'); -const { WebGL2Kernel } = require('./backend/web-gl2/kernel'); -const { WebGLKernel } = require('./backend/web-gl/kernel'); -const { kernelRunShortcut } = require('./kernel-run-shortcut'); - - -const kernelOrder = [HeadlessGLKernel, WebGL2Kernel, WebGLKernel]; - -const kernelTypes = ['gpu', 'cpu']; - -const internalKernels = { - 'headlessgl': HeadlessGLKernel, - 'webgl2': WebGL2Kernel, - 'webgl': WebGLKernel, -}; - -let validate = true; - -class GPU { - static disableValidation() { - validate = false; - } - - static enableValidation() { - validate = true; - } - - static get isGPUSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported); - } - - static get isKernelMapSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); - } - - static get isOffscreenCanvasSupported() { - return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined'; - } - - static get isWebGLSupported() { - return WebGLKernel.isSupported; - } - - static get isWebGL2Supported() { - return WebGL2Kernel.isSupported; - } - - static get isHeadlessGLSupported() { - return HeadlessGLKernel.isSupported; - } - - static get isCanvasSupported() { - return typeof HTMLCanvasElement !== 'undefined'; - } - - static get isGPUHTMLImageArraySupported() { - return WebGL2Kernel.isSupported; - } - - static get isSinglePrecisionSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); - } - - constructor(settings) { - settings = settings || {}; - this.canvas = settings.canvas || null; - this.context = settings.context || null; - this.mode = settings.mode; - this.Kernel = null; - this.kernels = []; - this.functions = []; - this.nativeFunctions = []; - this.injectedNative = null; - if (this.mode === 'dev') return; - this.chooseKernel(); - if (settings.functions) { - for (let i = 0; i < settings.functions.length; i++) { - this.addFunction(settings.functions[i]); + replaceArtifacts(src, map) { + return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => { + if (map.hasOwnProperty(artifact)) { + return map[artifact]; + } + throw `unhandled artifact ${artifact}`; + }); + } + getFragmentShader(args) { + if (this.compiledFragmentShader !== null) { + return this.compiledFragmentShader; } + return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args)); } - - if (settings.nativeFunctions) { - for (const p in settings.nativeFunctions) { - this.addNativeFunction(p, settings.nativeFunctions[p]); + getVertexShader(args) { + if (this.compiledVertexShader !== null) { + return this.compiledVertexShader; } + return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args)); } - } - - chooseKernel() { - if (this.Kernel) return; - - let Kernel = null; - - if (this.context) { - for (let i = 0; i < kernelOrder.length; i++) { - const ExternalKernel = kernelOrder[i]; - if (ExternalKernel.isContextMatch(this.context)) { - if (!ExternalKernel.isSupported) { - throw new Error(`Kernel type ${ExternalKernel.name} not supported`); - } - Kernel = ExternalKernel; - break; - } + toString() { + const setupContextString = utils$1.linesToString([ + `const gl = context`, + ]); + return glKernelString(this.constructor, arguments, this, setupContextString); + } + destroy(removeCanvasReferences) { + if (this.outputTexture) { + this.context.deleteTexture(this.outputTexture); } - if (Kernel === null) { - throw new Error('unknown Context'); + if (this.buffer) { + this.context.deleteBuffer(this.buffer); } - } else if (this.mode) { - if (this.mode in internalKernels) { - if (!validate || internalKernels[this.mode].isSupported) { - Kernel = internalKernels[this.mode]; - } - } else if (this.mode === 'gpu') { - for (let i = 0; i < kernelOrder.length; i++) { - if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; - } - } - } else if (this.mode === 'cpu') { - Kernel = CPUKernel; + if (this.framebuffer) { + this.context.deleteFramebuffer(this.framebuffer); } - if (!Kernel) { - throw new Error(`A requested mode of "${this.mode}" and is not supported`); + if (this.vertShader) { + this.context.deleteShader(this.vertShader); } - } else { - for (let i = 0; i < kernelOrder.length; i++) { - if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; + if (this.fragShader) { + this.context.deleteShader(this.fragShader); + } + if (this.program) { + this.context.deleteProgram(this.program); + } + const keys = Object.keys(this.textureCache); + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + this.context.deleteTexture(this.textureCache[name]); + } + if (this.subKernelOutputTextures) { + for (let i = 0; i < this.subKernelOutputTextures.length; i++) { + this.context.deleteTexture(this.subKernelOutputTextures[i]); } } - if (!Kernel) { - Kernel = CPUKernel; + if (removeCanvasReferences) { + const idx = canvases.indexOf(this.canvas); + if (idx >= 0) { + canvases[idx] = null; + maxTexSizes[idx] = null; + } } + this.destroyExtensions(); + delete this.context; + delete this.canvas; } - - if (!this.mode) { - this.mode = Kernel.mode; - } - this.Kernel = Kernel; - } - - createKernel(source, settings) { - if (typeof source === 'undefined') { - throw new Error('Missing source parameter'); - } - if (typeof source !== 'object' && !utils.isFunction(source) && typeof source !== 'string') { - throw new Error('source parameter not a function'); - } - - if (this.mode === 'dev') { - const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); - this.kernels.push(devKernel); - return devKernel; + destroyExtensions() { + this.extensions.OES_texture_float = null; + this.extensions.OES_texture_float_linear = null; + this.extensions.OES_element_index_uint = null; + this.extensions.WEBGL_draw_buffers = null; } - - source = typeof source === 'function' ? source.toString() : source; - const switchableKernels = {}; - const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {}; - if (settings && typeof settings.argumentTypes === 'object') { - settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + static destroyContext(context) { + const extension = context.getExtension('WEBGL_lose_context'); + if (extension) { + extension.loseContext(); + } } - - function onRequestFallback(args) { - const fallbackKernel = new CPUKernel(source, { - argumentTypes: kernelRun.argumentTypes, - constantTypes: kernelRun.constantTypes, - graphical: kernelRun.graphical, - loopMaxIterations: kernelRun.loopMaxIterations, - constants: kernelRun.constants, - dynamicOutput: kernelRun.dynamicOutput, - dynamicArgument: kernelRun.dynamicArguments, - output: kernelRun.output, - precision: kernelRun.precision, - pipeline: kernelRun.pipeline, - immutable: kernelRun.immutable, - optimizeFloatMemory: kernelRun.optimizeFloatMemory, - fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy, - functions: kernelRun.functions, - nativeFunctions: kernelRun.nativeFunctions, - injectedNative: kernelRun.injectedNative, - subKernels: kernelRun.subKernels, - strictIntegers: kernelRun.strictIntegers, - debug: kernelRun.debug, - warnVarUsage: kernelRun.warnVarUsage, - }); - fallbackKernel.build.apply(fallbackKernel, args); - const result = fallbackKernel.run.apply(fallbackKernel, args); - kernelRun.replaceKernel(fallbackKernel); - return result; + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); + return json; } + } - function onRequestSwitchKernel(args, kernel) { - const argumentTypes = new Array(args.length); - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - const type = kernel.argumentTypes[i]; - if (arg.type) { - argumentTypes[i] = arg.type; - } else { - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'ArrayTexture(1)': - argumentTypes[i] = utils.getVariableType(arg); - break; - default: - argumentTypes[i] = type; - } - } + class WebGL2FunctionNode extends WebGLFunctionNode { + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); } - const signature = argumentTypes.join(','); - const existingKernel = switchableKernels[signature]; - if (existingKernel) { - existingKernel.run.apply(existingKernel, args); - if (existingKernel.renderKernels) { - return existingKernel.renderKernels(); + const type = this.getType(idtNode); + if (idtNode.name === 'Infinity') { + retArr.push('intBitsToFloat(2139095039)'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); } else { - return existingKernel.renderOutput(); + retArr.push(`user_${idtNode.name}`); } - } - - const newKernel = switchableKernels[signature] = new kernel.constructor(source, { - argumentTypes, - constantTypes: kernel.constantTypes, - graphical: kernel.graphical, - loopMaxIterations: kernel.loopMaxIterations, - constants: kernel.constants, - dynamicOutput: kernel.dynamicOutput, - dynamicArgument: kernel.dynamicArguments, - context: kernel.context, - canvas: kernel.canvas, - output: kernel.output, - precision: kernel.precision, - pipeline: kernel.pipeline, - immutable: kernel.immutable, - optimizeFloatMemory: kernel.optimizeFloatMemory, - fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy, - functions: kernel.functions, - nativeFunctions: kernel.nativeFunctions, - injectedNative: kernel.injectedNative, - subKernels: kernel.subKernels, - strictIntegers: kernel.strictIntegers, - debug: kernel.debug, - gpu: kernel.gpu, - validate, - warnVarUsage: kernel.warnVarUsage, - returnType: kernel.returnType, - onRequestFallback, - onRequestSwitchKernel, - }); - newKernel.build.apply(newKernel, args); - newKernel.run.apply(newKernel, args); - kernelRun.replaceKernel(newKernel); - if (newKernel.renderKernels) { - return newKernel.renderKernels(); } else { - return newKernel.renderOutput(); - } - } - const mergedSettings = Object.assign({ - context: this.context, - canvas: this.canvas, - functions: this.functions, - nativeFunctions: this.nativeFunctions, - injectedNative: this.injectedNative, - gpu: this, - validate, - onRequestFallback, - onRequestSwitchKernel - }, settingsCopy); - - const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); - - if (!this.canvas) { - this.canvas = kernelRun.canvas; + retArr.push(`user_${idtNode.name}`); + } + return retArr; } + } - if (!this.context) { - this.context = kernelRun.context; - } + const fragmentShader$1 = `#version 300 es +__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; +__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +in vec2 vTexCoord; + +const int BIT_COUNT = 32; +int modi(int x, int y) { + return x - y * (x / y); +} + +int bitwiseOr(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseXOR(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseAnd(int a, int b) { + int result = 0; + int n = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 && b > 0)) { + break; + } + } + return result; +} +int bitwiseNot(int a) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if (modi(a, 2) == 0) { + result += n; + } + a = a / 2; + n = n * 2; + } + return result; +} +int bitwiseZeroFillLeftShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n *= 2; + } + + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +int bitwiseSignedRightShift(int num, int shifts) { + return int(floor(float(num) / pow(2.0, float(shifts)))); +} + +int bitwiseZeroFillRightShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n /= 2; + } + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +vec2 integerMod(vec2 x, float y) { + vec2 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec3 integerMod(vec3 x, float y) { + vec3 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec4 integerMod(vec4 x, vec4 y) { + vec4 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +float integerMod(float x, float y) { + float res = floor(mod(x, y)); + return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); +} + +int integerMod(int x, int y) { + return x - (y * int(x/y)); +} + +__DIVIDE_WITH_INTEGER_CHECK__; + +// Here be dragons! +// DO NOT OPTIMIZE THIS CODE +// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE +// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME +const vec2 MAGIC_VEC = vec2(1.0, -256.0); +const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); +const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 +float decode32(vec4 texel) { + __DECODE32_ENDIANNESS__; + texel *= 255.0; + vec2 gte128; + gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; + gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; + float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); + float res = exp2(round(exponent)); + texel.b = texel.b - 128.0 * gte128.x; + res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; + res *= gte128.y * -2.0 + 1.0; + return res; +} + +float decode16(vec4 texel, int index) { + int channel = integerMod(index, 2); + return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; +} + +float decode8(vec4 texel, int index) { + int channel = integerMod(index, 4); + return texel[channel] * 255.0; +} + +vec4 legacyEncode32(float f) { + float F = abs(f); + float sign = f < 0.0 ? 1.0 : 0.0; + float exponent = floor(log2(F)); + float mantissa = (exp2(-exponent) * F); + // exponent += floor(log2(mantissa)); + vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; + texel.rg = integerMod(texel.rg, 256.0); + texel.b = integerMod(texel.b, 128.0); + texel.a = exponent*0.5 + 63.5; + texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; + texel = floor(texel); + texel *= 0.003921569; // 1/255 + __ENCODE32_ENDIANNESS__; + return texel; +} + +// https://github.com/gpujs/gpu.js/wiki/Encoder-details +vec4 encode32(float value) { + if (value == 0.0) return vec4(0, 0, 0, 0); + + float exponent; + float mantissa; + vec4 result; + float sgn; + + sgn = step(0.0, -value); + value = abs(value); + + exponent = floor(log2(value)); + + mantissa = value*pow(2.0, -exponent)-1.0; + exponent = exponent+127.0; + result = vec4(0,0,0,0); + + result.a = floor(exponent/2.0); + exponent = exponent - result.a*2.0; + result.a = result.a + 128.0*sgn; + + result.b = floor(mantissa * 128.0); + mantissa = mantissa - result.b / 128.0; + result.b = result.b + exponent*128.0; + + result.g = floor(mantissa*32768.0); + mantissa = mantissa - result.g/32768.0; + + result.r = floor(mantissa*8388608.0); + return result/255.0; +} +// Dragons end here + +int index; +ivec3 threadId; + +ivec3 indexTo3D(int idx, ivec3 texDim) { + int z = int(idx / (texDim.x * texDim.y)); + idx -= z * int(texDim.x * texDim.y); + int y = int(idx / texDim.x); + int x = int(integerMod(idx, texDim.x)); + return ivec3(x, y, z); +} + +float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + return decode32(texel); +} + +float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int w = texSize.x * 2; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); + return decode16(texel, index); +} + +float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int w = texSize.x * 4; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); + return decode8(texel, index); +} + +float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int channel = integerMod(index, 4); + index = index / 4; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + index = index / 4; + vec4 texel = texture(tex, st / vec2(texSize)); + return texel[channel]; +} + +vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture(tex, st / vec2(texSize)); +} + +vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture(tex, vec3(st / vec2(texSize), z)); +} + +float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return result[0]; +} + +vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec2(result[0], result[1]); +} + +vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + index = index / 2; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + if (channel == 0) return vec2(texel.r, texel.g); + if (channel == 1) return vec2(texel.b, texel.a); + return vec2(0.0, 0.0); +} + +vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec3(result[0], result[1], result[2]); +} + +vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); + int vectorIndex = fieldIndex / 4; + int vectorOffset = fieldIndex - vectorIndex * 4; + int readY = vectorIndex / texSize.x; + int readX = vectorIndex - readY * texSize.x; + vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); + + if (vectorOffset == 0) { + return tex1.xyz; + } else if (vectorOffset == 1) { + return tex1.yzw; + } else { + readX++; + if (readX >= texSize.x) { + readX = 0; + readY++; + } + vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); + if (vectorOffset == 2) { + return vec3(tex1.z, tex1.w, tex2.x); + } else { + return vec3(tex1.w, tex2.x, tex2.y); + } + } +} + +vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + return getImage2D(tex, texSize, texDim, z, y, x); +} + +vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + return vec4(texel.r, texel.g, texel.b, texel.a); +} + +vec4 actualColor; +void color(float r, float g, float b, float a) { + actualColor = vec4(r,g,b,a); +} + +void color(float r, float g, float b) { + color(r,g,b,1.0); +} + +__INJECTED_NATIVE__; +__MAIN_CONSTANTS__; +__MAIN_ARGUMENTS__; +__KERNEL__; + +void main(void) { + index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; + __MAIN_RESULT__; +}`; - this.kernels.push(kernelRun); + const vertexShader$1 = `#version 300 es +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +in vec2 aPos; +in vec2 aTexCoord; + +out vec2 vTexCoord; +uniform vec2 ratio; + +void main(void) { + gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); + vTexCoord = aTexCoord; +}`; - return kernelRun; - } + class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - createKernelMap() { - let fn; - let settings; - if (typeof arguments[arguments.length - 2] === 'function') { - fn = arguments[arguments.length - 2]; - settings = arguments[arguments.length - 1]; - } else { - fn = arguments[arguments.length - 1]; - } + class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - if (this.mode !== 'dev') { - if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { - if (this.mode && kernelTypes.indexOf(this.mode) < 0) { - throw new Error(`kernelMap not supported on ${this.Kernel.name}`); - } + class WebGL2KernelValueInteger extends WebGLKernelValueInteger { + getSource(value) { + const variablePrecision = this.getVariablePrecisionString(); + if (this.origin === 'constants') { + return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`; } + return `uniform ${ variablePrecision } int ${this.id};\n`; } - - const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings); - if (settings && typeof settings.argumentTypes === 'object') { - settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); } + } - if (Array.isArray(arguments[0])) { - settingsCopy.subKernels = []; - const functions = arguments[0]; - for (let i = 0; i < functions.length; i++) { - const source = functions[i].toString(); - const name = utils.getFunctionNameFromString(source); - settingsCopy.subKernels.push({ - name, - source, - property: i, - }); - } - } else { - settingsCopy.subKernels = []; - const functions = arguments[0]; - for (let p in functions) { - if (!functions.hasOwnProperty(p)) continue; - const source = functions[p].toString(); - const name = utils.getFunctionNameFromString(source); - settingsCopy.subKernels.push({ - name: name || p, - source, - property: p, - }); - } + class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); } - const kernel = this.createKernel(fn, settingsCopy); - - return kernel; } - combineKernels() { - const firstKernel = arguments[0]; - const combinedKernel = arguments[arguments.length - 1]; - if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel; - const canvas = arguments[0].canvas; - const context = arguments[0].context; - const max = arguments.length - 1; - for (let i = 0; i < max; i++) { - arguments[i] - .setCanvas(canvas) - .setContext(context) - .setPipeline(true); + class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); } + } - return function() { - const texture = combinedKernel.apply(this, arguments); - if (texture.toArray) { - return texture.toArray(); + class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.checkSize(value[0].width, value[0].height); + this.requestTexture(); + this.dimensions = [value[0].width, value[0].height, value.length]; + this.textureSize = [value[0].width, value[0].height]; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2DArray ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(images) { + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage3D( + gl.TEXTURE_2D_ARRAY, + 0, + gl.RGBA, + images[0].width, + images[0].height, + images.length, + 0, + gl.RGBA, + gl.UNSIGNED_BYTE, + null + ); + for (let i = 0; i < images.length; i++) { + const xOffset = 0; + const yOffset = 0; + const imageDepth = 1; + gl.texSubImage3D( + gl.TEXTURE_2D_ARRAY, + 0, + xOffset, + yOffset, + i, + images[i].width, + images[i].height, + imageDepth, + gl.RGBA, + gl.UNSIGNED_BYTE, + this.uploadValue = images[i] + ); } - return texture; - }; + this.kernel.setUniform1i(this.id, this.index); + } } - addFunction(source, settings) { - this.functions.push(utils.functionToIFunction(source, settings)); - return this; + class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2DArray ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(images) { + const { width, height } = images[0]; + this.checkSize(width, height); + this.dimensions = [width, height, images.length]; + this.textureSize = [width, height]; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(images); + } } - addNativeFunction(name, source, settings) { - if (this.kernels.length > 0) { - throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); + class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} + + class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} + + class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + updateValue(input) { + const { context: gl } = this; + utils$1.flattenTo(input.value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); } - settings = settings || {}; - const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; - this.nativeFunctions.push({ - name, - source, - settings, - argumentTypes, - argumentNames, - returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), - }); - return this; } - injectNative(source) { - this.injectedNative = source; - return this; + class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } - destroy() { - if (!this.kernels) return; - setTimeout(() => { - for (let i = 0; i < this.kernels.length; i++) { - this.kernels[i].destroy(true); - } - let firstKernel = this.kernels[0]; - if (firstKernel) { - if (firstKernel.kernel) { - firstKernel = firstKernel.kernel; - } - if (firstKernel.constructor.destroyContext) { - firstKernel.constructor.destroyContext(this.context); - } - } - }, 0); + class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } } -} - -function upgradeDeprecatedCreateKernelSettings(settings) { - if (!settings) { - return {}; + class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } } - const upgradedSettings = Object.assign({}, settings); - if (settings.hasOwnProperty('floatOutput')) { - utils.warnDeprecated('setting', 'floatOutput', 'precision'); - upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; - } - if (settings.hasOwnProperty('outputToTexture')) { - utils.warnDeprecated('setting', 'outputToTexture', 'pipeline'); - upgradedSettings.pipeline = Boolean(settings.outputToTexture); - } - if (settings.hasOwnProperty('outputImmutable')) { - utils.warnDeprecated('setting', 'outputImmutable', 'immutable'); - upgradedSettings.immutable = Boolean(settings.outputImmutable); - } - if (settings.hasOwnProperty('floatTextures')) { - utils.warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); - upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); + class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); + } } - return upgradedSettings; -} - -module.exports = { - GPU, - kernelOrder, - kernelTypes -}; -},{"./backend/cpu/kernel":8,"./backend/headless-gl/kernel":33,"./backend/web-gl/kernel":68,"./backend/web-gl2/kernel":103,"./kernel-run-shortcut":109,"./utils":112,"gpu-mock.js":4}],107:[function(require,module,exports){ -const { GPU } = require('./gpu'); -const { alias } = require('./alias'); -const { utils } = require('./utils'); -const { Input, input } = require('./input'); -const { Texture } = require('./texture'); -const { FunctionBuilder } = require('./backend/function-builder'); -const { FunctionNode } = require('./backend/function-node'); -const { CPUFunctionNode } = require('./backend/cpu/function-node'); -const { CPUKernel } = require('./backend/cpu/kernel'); - -const { HeadlessGLKernel } = require('./backend/headless-gl/kernel'); - -const { WebGLFunctionNode } = require('./backend/web-gl/function-node'); -const { WebGLKernel } = require('./backend/web-gl/kernel'); -const { kernelValueMaps: webGLKernelValueMaps } = require('./backend/web-gl/kernel-value-maps'); - -const { WebGL2FunctionNode } = require('./backend/web-gl2/function-node'); -const { WebGL2Kernel } = require('./backend/web-gl2/kernel'); -const { kernelValueMaps: webGL2KernelValueMaps } = require('./backend/web-gl2/kernel-value-maps'); - -const { GLKernel } = require('./backend/gl/kernel'); - -const { Kernel } = require('./backend/kernel'); -const { FunctionTracer } = require('./backend/function-tracer'); - -module.exports = { - alias, - CPUFunctionNode, - CPUKernel, - GPU, - FunctionBuilder, - FunctionNode, - HeadlessGLKernel, - Input, - input, - Texture, - utils, - - WebGL2FunctionNode, - WebGL2Kernel, - webGL2KernelValueMaps, - - WebGLFunctionNode, - WebGLKernel, - webGLKernelValueMaps, - - GLKernel, - Kernel, - FunctionTracer, -}; -},{"./alias":5,"./backend/cpu/function-node":6,"./backend/cpu/kernel":8,"./backend/function-builder":9,"./backend/function-node":10,"./backend/function-tracer":11,"./backend/gl/kernel":13,"./backend/headless-gl/kernel":33,"./backend/kernel":35,"./backend/web-gl/function-node":37,"./backend/web-gl/kernel":68,"./backend/web-gl/kernel-value-maps":38,"./backend/web-gl2/function-node":71,"./backend/web-gl2/kernel":103,"./backend/web-gl2/kernel-value-maps":72,"./gpu":106,"./input":108,"./texture":111,"./utils":112}],108:[function(require,module,exports){ -class Input { - constructor(value, size) { - this.value = value; - if (Array.isArray(size)) { - this.size = size; - } else { - this.size = new Int32Array(3); - if (size.z) { - this.size = new Int32Array([size.x, size.y, size.z]); - } else if (size.y) { - this.size = new Int32Array([size.x, size.y]); - } else { - this.size = new Int32Array([size.x]); - } + class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { + getSource() { + return utils$1.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); } + } - const [w, h, d] = this.size; - if (d) { - if (this.value.length !== (w * h * d)) { - throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`); - } - } else if (h) { - if (this.value.length !== (w * h)) { - throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`); - } - } else { - if (this.value.length !== w) { - throw new Error(`Input size ${this.value.length} does not match ${w}`); - } + class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); } - } - toArray() { - const { utils } = require('./utils'); - const [w, h, d] = this.size; - if (d) { - return utils.erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); - } else if (h) { - return utils.erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h); - } else { - return this.value; + class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); } } -} - -function input(value, size) { - return new Input(value, size); -} -module.exports = { - Input, - input -}; -},{"./utils":112}],109:[function(require,module,exports){ -const { utils } = require('./utils'); - -function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - if (kernel.renderKernels) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderKernels(); - }; - } else if (kernel.renderOutput) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderOutput(); - }; - } else { - run = function() { - return kernel.run.apply(kernel, arguments); - }; + class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); } - return run.apply(kernel, arguments); - }; - const shortcut = function() { - return run.apply(kernel, arguments); - }; - shortcut.exec = function() { - return new Promise((accept, reject) => { - try { - accept(run.apply(this, arguments)); - } catch (e) { - reject(e); + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; } - }); - }; - shortcut.replaceKernel = function(replacementKernel) { - kernel = replacementKernel; - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - }; + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - return shortcut; -} + class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.dimensions = utils$1.getDimensions(value, true); + this.textureSize = utils$1.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } -function bindKernelToShortcut(kernel, shortcut) { - const properties = utils.allPropertiesOf(kernel); - for (let i = 0; i < properties.length; i++) { - const property = properties[i]; - if (property[0] === '_' && property[1] === '_') continue; - if (typeof kernel[property] === 'function') { - if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') { - shortcut[property] = function() { - kernel[property].apply(kernel, arguments); - return shortcut; - }; - } else { - if (property === 'toString') { - shortcut.toString = function() { - return kernel.toString.apply(kernel, arguments); - }; - } else { - shortcut[property] = kernel[property].bind(kernel); - } + class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; } - } else { - shortcut.__defineGetter__(property, () => { - return kernel[property]; - }); - shortcut.__defineSetter__(property, (value) => { - kernel[property] = value; - }); + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); } } -} -module.exports = { - kernelRunShortcut -}; -},{"./utils":112}],110:[function(require,module,exports){ -const source = ` - -uniform highp float triangle_noise_seed; -highp float triangle_noise_shift = 0.000001; - -//https://www.shadertoy.com/view/4t2SDh -//note: uniformly distributed, normalized rand, [0;1[ -float nrand( vec2 n ) -{ - return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); -} -//note: remaps v to [0;1] in interval [a;b] -float remap( float a, float b, float v ) -{ - return clamp( (v-a) / (b-a), 0.0, 1.0 ); -} - -float n4rand( vec2 n ) -{ - float t = fract( triangle_noise_seed + triangle_noise_shift ); - float nrnd0 = nrand( n + 0.07*t ); - float nrnd1 = nrand( n + 0.11*t ); - float nrnd2 = nrand( n + 0.13*t ); - float nrnd3 = nrand( n + 0.17*t ); - float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; - triangle_noise_shift = result + 0.000001; - return result; -}`; - -const name = 'triangle-noise-noise'; -const functionMatch = 'Math.random()'; - -const functionReplace = 'n4rand(vTexCoord)'; - -const functionReturnType = 'Number'; - -const onBeforeRun = (kernel) => { - kernel.setUniform1f('triangle_noise_seed', Math.random()); -}; - -module.exports = { - name, - onBeforeRun, - functionMatch, - functionReplace, - functionReturnType, - source -}; -},{}],111:[function(require,module,exports){ -class Texture { - constructor(settings) { - const { - texture, - size, - dimensions, - output, - context, - type = 'NumberTexture', - } = settings; - if (!output) throw new Error('settings property "output" required.'); - if (!context) throw new Error('settings property "context" required.'); - this.texture = texture; - this.size = size; - this.dimensions = dimensions; - this.output = output; - this.context = context; - this.kernel = null; - this.type = type; + class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } - toArray() { - throw new Error(`Not implemented on ${this.constructor.name}`); + class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } } - delete() { - return this.context.deleteTexture(this.texture); + class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } } -} - -module.exports = { - Texture -}; -},{}],112:[function(require,module,exports){ -const acorn = require('acorn'); -const { Input } = require('./input'); -const { Texture } = require('./texture'); - -const FUNCTION_NAME = /function ([^(]*)/; -const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; -const ARGUMENT_NAMES = /([^\s,]+)/g; - -const utils = { - systemEndianness() { - return _systemEndianness; - }, - getSystemEndianness() { - const b = new ArrayBuffer(4); - const a = new Uint32Array(b); - const c = new Uint8Array(b); - a[0] = 0xdeadbeef; - if (c[0] === 0xef) return 'LE'; - if (c[0] === 0xde) return 'BE'; - throw new Error('unknown endianness'); - }, - - isFunction(funcObj) { - return typeof(funcObj) === 'function'; - }, - isFunctionString(fn) { - if (typeof fn === 'string') { - return (fn - .slice(0, 'function'.length) - .toLowerCase() === 'function'); + class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils$1.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } + } + + class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } + } + + class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} + + class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} + + class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} + + class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + } + + class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils$1.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + } + + const kernelValueMaps$1 = { + unsigned: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGL2KernelValueDynamicUnsignedInput, + 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGL2KernelValueUnsignedInput, + 'NumberTexture': WebGL2KernelValueNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI, + 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI, + 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI, + 'Input': WebGL2KernelValueDynamicSingleInput, + 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + 'Array1D(2)': WebGL2KernelValueSingleArray1DI, + 'Array1D(3)': WebGL2KernelValueSingleArray1DI, + 'Array1D(4)': WebGL2KernelValueSingleArray1DI, + 'Array2D(2)': WebGL2KernelValueSingleArray2DI, + 'Array2D(3)': WebGL2KernelValueSingleArray2DI, + 'Array2D(4)': WebGL2KernelValueSingleArray2DI, + 'Array3D(2)': WebGL2KernelValueSingleArray3DI, + 'Array3D(3)': WebGL2KernelValueSingleArray3DI, + 'Array3D(4)': WebGL2KernelValueSingleArray3DI, + 'Input': WebGL2KernelValueSingleInput, + 'NumberTexture': WebGL2KernelValueNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + }; + function lookupKernelValueType$1(type, dynamic, precision, value) { + if (!type) { + throw new Error('type missing'); } - return false; - }, - - getFunctionNameFromString(funcStr) { - return FUNCTION_NAME.exec(funcStr)[1].trim(); - }, - - getFunctionBodyFromString(funcStr) { - return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); - }, - - getArgumentNamesFromString(fn) { - const fnStr = fn.replace(STRIP_COMMENTS, ''); - let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); - if (result === null) { - result = []; + if (!dynamic) { + throw new Error('dynamic missing'); + } + if (!precision) { + throw new Error('precision missing'); + } + if (value.type) { + type = value.type; + } + const types = kernelValueMaps$1[precision][dynamic]; + if (types[type] === false) { + return null; + } else if (types[type] === undefined) { + throw new Error(`Could not find a KernelValue for ${ type }`); + } + return types[type]; + } + + let isSupported$1 = null; + let testCanvas$1 = null; + let testContext$1 = null; + let testExtensions$1 = null; + let features$1 = null; + class WebGL2Kernel extends WebGLKernel { + static get isSupported() { + if (isSupported$1 !== null) { + return isSupported$1; + } + this.setupFeatureChecks(); + isSupported$1 = this.isContextMatch(testContext$1); + return isSupported$1; + } + static setupFeatureChecks() { + if (typeof document !== 'undefined') { + testCanvas$1 = document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + testCanvas$1 = new OffscreenCanvas(0, 0); + } + if (!testCanvas$1) return; + testContext$1 = testCanvas$1.getContext('webgl2'); + if (!testContext$1 || !testContext$1.getExtension) return; + testExtensions$1 = { + EXT_color_buffer_float: testContext$1.getExtension('EXT_color_buffer_float'), + OES_texture_float_linear: testContext$1.getExtension('OES_texture_float_linear'), + }; + features$1 = this.getFeatures(); } - return result; - }, - - clone(obj) { - if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj; - - const temp = obj.constructor(); - - for (let key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - obj.isActiveClone = null; - temp[key] = utils.clone(obj[key]); - delete obj.isActiveClone; + static isContextMatch(context) { + if (typeof WebGL2RenderingContext !== 'undefined') { + return context instanceof WebGL2RenderingContext; } + return false; } - - return temp; - }, - - isArray(array) { - return !isNaN(array.length); - }, - - getVariableType(value, strictIntegers) { - if (utils.isArray(value)) { - if (value[0].nodeName === 'IMG') { - return 'HTMLImageArray'; - } - return 'Array'; + static getFeatures() { + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + kernelMap: true, + isTextureFloat: true, + channelCount: this.getChannelCount(), + maxTextureSize: this.getMaxTextureSize(), + }); } - - switch (value.constructor) { - case Boolean: - return 'Boolean'; - case Number: - if (strictIntegers && Number.isInteger(value)) { - return 'Integer'; - } - return 'Float'; - case Texture: - return value.type; - case Input: - return 'Input'; + static getIsTextureFloat() { + return true; } - switch (value.nodeName) { - case 'IMG': - return 'HTMLImage'; - case 'VIDEO': - return 'HTMLVideo'; + static getIsIntegerDivisionAccurate() { + return super.getIsIntegerDivisionAccurate(); } - if (value.hasOwnProperty('type')) { - return value.type; + static getChannelCount() { + return testContext$1.getParameter(testContext$1.MAX_DRAW_BUFFERS); } - return 'Unknown'; - }, - - getKernelTextureSize(settings, dimensions) { - let [w, h, d] = dimensions; - let texelCount = (w || 1) * (h || 1) * (d || 1); - - if (settings.optimizeFloatMemory && settings.precision === 'single') { - w = texelCount = Math.ceil(texelCount / 4); + static getMaxTextureSize() { + return testContext$1.getParameter(testContext$1.MAX_TEXTURE_SIZE); } - if (h > 1 && w * h === texelCount) { - return new Int32Array([w, h]); + static lookupKernelValueType(type, dynamic, precision, value) { + return lookupKernelValueType$1(type, dynamic, precision, value); } - return utils.closestSquareDimensions(texelCount); - }, - - closestSquareDimensions(length) { - const sqrt = Math.sqrt(length); - let high = Math.ceil(sqrt); - let low = Math.floor(sqrt); - while (high * low < length) { - high--; - low = Math.ceil(length / high); - } - return new Int32Array([low, Math.ceil(length / low)]); - }, - - getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) { - const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4); - const texelCount = totalArea / bitRatio; - return utils.closestSquareDimensions(texelCount); - }, - - getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) { - const [w, h, d] = dimensions; - const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4); - const texelCount = totalArea / (4 / bitRatio); - return utils.closestSquareDimensions(texelCount); - }, - - roundTo(n, d) { - return Math.floor((n + d - 1) / d) * d; - }, - getDimensions(x, pad) { - let ret; - if (utils.isArray(x)) { - const dim = []; - let temp = x; - while (utils.isArray(temp)) { - dim.push(temp.length); - temp = temp[0]; - } - ret = dim.reverse(); - } else if (x instanceof Texture) { - ret = x.output; - } else if (x instanceof Input) { - ret = x.size; - } else { - throw new Error(`Unknown dimensions of ${x}`); + static get testCanvas() { + return testCanvas$1; } - - if (pad) { - ret = Array.from(ret); - while (ret.length < 3) { - ret.push(1); - } + static get testContext() { + return testContext$1; } - - return new Int32Array(ret); - }, - - flatten2dArrayTo(array, target) { - let offset = 0; - for (let y = 0; y < array.length; y++) { - target.set(array[y], offset); - offset += array[y].length; + static get features() { + return features$1; } - }, - - flatten3dArrayTo(array, target) { - let offset = 0; - for (let z = 0; z < array.length; z++) { - for (let y = 0; y < array[z].length; y++) { - target.set(array[z][y], offset); - offset += array[z][y].length; + static get fragmentShader() { + return fragmentShader$1; + } + static get vertexShader() { + return vertexShader$1; + } + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + const context = this.canvas.getContext('webgl2', settings); + return context; + } + initExtensions() { + this.extensions = { + EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'), + OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), + }; + } + validateSettings(args) { + if (!this.validate) { + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + return; + } + const features = this.constructor.features; + if (this.precision === 'single' && !features.isFloatRead) { + throw new Error('Float texture outputs are not supported'); + } else if (!this.graphical && this.precision === null) { + this.precision = features.isFloatRead ? 'single' : 'unsigned'; + } + if (this.fixIntegerDivisionAccuracy === null) { + this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; + } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { + this.fixIntegerDivisionAccuracy = false; + } + this.checkOutput(); + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + const argType = utils$1.getVariableType(args[0], this.strictIntegers); + switch (argType) { + case 'Array': + this.output = utils$1.getDimensions(argType); + break; + case 'NumberTexture': + case 'MemoryOptimizedNumberTexture': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + this.output = args[0].output; + break; + default: + throw new Error('Auto output not supported for input type: ' + argType); + } + } + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); + } + if (this.precision === 'single') { + console.warn('Cannot use graphical mode and single precision at the same time'); + this.precision = 'unsigned'; + } + this.texSize = utils$1.clone(this.output); + return; + } else if (!this.graphical && this.precision === null && features.isTextureFloat) { + this.precision = 'single'; } + this.texSize = utils$1.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + this.checkTextureSize(); } - }, - - flatten4dArrayTo(array, target) { - let offset = 0; - for (let l = 0; l < array.length; l++) { - for (let z = 0; z < array[l].length; z++) { - for (let y = 0; y < array[l][z].length; y++) { - target.set(array[l][z][y], offset); - offset += array[l][z][y].length; + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + if (this.subKernels && this.subKernels.length > 0) { + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (!subKernel.returnType) { + subKernel.returnType = functionBuilder.getSubKernelResultType(i); + } } } } - }, - - flattenTo(array, target) { - if (utils.isArray(array[0])) { - if (utils.isArray(array[0][0])) { - if (utils.isArray(array[0][0][0])) { - utils.flatten4dArrayTo(array, target); + run() { + const { kernelArguments, texSize, forceUploadKernelConstants } = this; + const gl = this.context; + gl.useProgram(this.program); + gl.scissor(0, 0, texSize[0], texSize[1]); + if (this.dynamicOutput) { + this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); + this.setUniform2iv('uTexSize', texSize); + } + this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); + this.switchingKernels = false; + for (let i = 0; i < forceUploadKernelConstants.length; i++) { + const constant = forceUploadKernelConstants[i]; + constant.updateValue(this.constants[constant.name]); + if (this.switchingKernels) return; + } + for (let i = 0; i < kernelArguments.length; i++) { + kernelArguments[i].updateValue(arguments[i]); + if (this.switchingKernels) return; + } + if (this.plugins) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.onBeforeRun) { + plugin.onBeforeRun(this); + } + } + } + if (this.graphical) { + if (this.pipeline) { + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (!this.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context + }); + } + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return; + } + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (this.immutable) { + this._setupOutputTexture(); + } + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + gl.drawBuffers(this.drawBuffersMap); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + drawBuffers() { + this.context.drawBuffers(this.drawBuffersMap); + } + getOutputTexture() { + return this.outputTexture; + } + _setupOutputTexture() { + const { texSize } = this; + const gl = this.context; + const texture = this.outputTexture = gl.createTexture(); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + } else { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + } + break; + case 'Array(2)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + break; + case 'Array(3)': + case 'Array(4)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + break; + default: + throw new Error('Unhandled return type'); + } } else { - utils.flatten3dArrayTo(array, target); + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); } } else { - utils.flatten2dArrayTo(array, target); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); } - } else { - target.set(array); - } - }, - - splitArray(array, part) { - const result = []; - for (let i = 0; i < array.length; i += part) { - result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part)); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); } - return result; - }, - - getAstString(source, ast) { - const lines = Array.isArray(source) ? source : source.split(/\r?\n/g); - const start = ast.loc.start; - const end = ast.loc.end; - const result = []; - if (start.line === end.line) { - result.push(lines[start.line - 1].substring(start.column, end.column)); - } else { - result.push(lines[start.line - 1].slice(start.column)); - for (let i = start.line; i < end.line; i++) { - result.push(lines[i]); + _setupSubOutputTextures() { + const { texSize } = this; + const gl = this.context; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; + for (let i = 0; i < this.subKernels.length; i++) { + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); } - result.push(lines[end.line - 1].slice(0, end.column)); } - return result.join('\n'); - }, - - allPropertiesOf(obj) { - const props = []; - - do { - props.push.apply(props, Object.getOwnPropertyNames(obj)); - } while (obj = Object.getPrototypeOf(obj)); - - return props; - }, - - linesToString(lines) { - if (lines.length > 0) { - return lines.join(';\n') + ';\n'; - } else { - return '\n'; + _getHeaderString() { + return ''; } - }, - warnDeprecated(type, oldName, newName) { - if (newName) { - console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been replaced with "${ newName }". Fixing, but please upgrade as it will soon be removed.`); - } else { - console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been removed. Fixing, but please upgrade as it will soon be removed.`); + _getTextureCoordinate() { + const subKernels = this.subKernels; + if (subKernels === null || subKernels.length < 1) { + switch (this.tactic) { + case 'speed': + return 'in lowp vec2 vTexCoord;\n'; + case 'performance': + return 'in highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'in mediump vec2 vTexCoord;\n'; + } + } else { + switch (this.tactic) { + case 'speed': + return 'out lowp vec2 vTexCoord;\n'; + case 'performance': + return 'out highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'out mediump vec2 vTexCoord;\n'; + } + } } - }, - functionToIFunction(source, settings) { - settings = settings || {}; - if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function'); - const sourceString = typeof source === 'string' ? source : source.toString(); - - let argumentTypes = []; - - if (Array.isArray(settings.argumentTypes)) { - argumentTypes = settings.argumentTypes; - } else if (typeof settings.argumentTypes === 'object') { - argumentTypes = utils.getArgumentNamesFromString(sourceString) - .map(name => settings.argumentTypes[name]) || []; - } else { - argumentTypes = settings.argumentTypes || []; + _getMainArgumentsString(args) { + const result = []; + const argumentNames = this.argumentNames; + for (let i = 0; i < argumentNames.length; i++) { + result.push(this.kernelArguments[i].getSource(args[i])); + } + return result.join(''); } - - return { - source: sourceString, - argumentTypes, - returnType: settings.returnType || null, - }; - }, - flipPixels: (pixels, width, height) => { - const halfHeight = height / 2 | 0; - const bytesPerRow = width * 4; - const temp = new Uint8ClampedArray(width * 4); - const result = pixels.slice(0); - for (let y = 0; y < halfHeight; ++y) { - const topOffset = y * bytesPerRow; - const bottomOffset = (height - y - 1) * bytesPerRow; - - temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); - - result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); - - result.set(temp, bottomOffset); + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration, + 'layout(location = 0) out vec4 data0' + ); + for (let i = 0; i < subKernels.length; i++) { + const subKernel = subKernels[i]; + result.push( + subKernel.returnType === 'Integer' ? + `int subKernelResult_${ subKernel.name } = 0` : + `float subKernelResult_${ subKernel.name } = 0.0`, + `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }` + ); + } + } else { + result.push( + 'out vec4 data0', + kernelResultDeclaration + ); + } + return utils$1.linesToString(result) + this.translatedSource; } - return result; - }, - erectPackedFloat: (array, width) => { - return array.subarray(0, width); - }, - erect2DPackedFloat: (array, width, height) => { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xStart = y * width; - const xEnd = xStart + width; - yResults[y] = array.subarray(xStart, xEnd); + getMainResultGraphical() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0 = actualColor', + ]); } - return yResults; - }, - erect3DPackedFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xStart = (z * height * width) + y * width; - const xEnd = xStart + width; - yResults[y] = array.subarray(xStart, xEnd); + getMainResultPackedPixels() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return this.getMainResultKernelPackedPixels() + + this.getMainResultSubKernelPackedPixels(); + default: + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); } - zResults[z] = yResults; } - return zResults; - }, - erectMemoryOptimizedFloat: (array, width) => { - return array.subarray(0, width); - }, - erectMemoryOptimized2DFloat: (array, width, height) => { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const offset = y * width; - yResults[y] = array.subarray(offset, offset + width); + getMainResultKernelPackedPixels() { + return utils$1.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); } - return yResults; - }, - erectMemoryOptimized3DFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const offset = (z * height * width) + (y * width); - yResults[y] = array.subarray(offset, offset + width); + getMainResultSubKernelPackedPixels() { + const result = []; + if (!this.subKernels) return ''; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` + ); + } else { + result.push( + ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` + ); + } + } + return utils$1.linesToString(result); + } + getMainResultMemoryOptimizedFloats() { + const result = [ + ' index *= 4', + ]; + switch (this.returnType) { + case 'Number': + case 'Integer': + case 'Float': + const channels = ['r', 'g', 'b', 'a']; + for (let i = 0; i < channels.length; i++) { + const channel = channels[i]; + this.getMainResultKernelMemoryOptimizedFloats(result, channel); + this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); + if (i + 1 < channels.length) { + result.push(' index += 1'); + } + } + break; + default: + throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); } - zResults[z] = yResults; + return utils$1.linesToString(result); } - return zResults; - }, - erectFloat: (array, width) => { - const xResults = new Float32Array(width); - let i = 0; - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; - } - return xResults; - }, - erect2DFloat: (array, width, height) => { - const yResults = new Array(height); - let i = 0; - for (let y = 0; y < height; y++) { - const xResults = new Float32Array(width); - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; - } - yResults[y] = xResults; + getMainResultKernelMemoryOptimizedFloats(result, channel) { + result.push( + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0.${channel} = kernelResult`, + ); } - return yResults; - }, - erect3DFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - let i = 0; - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Float32Array(width); - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; + getMainResultSubKernelMemoryOptimizedFloats(result, channel) { + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`, + ); } - yResults[y] = xResults; } - zResults[z] = yResults; } - return zResults; - }, - erectArray2: (array, width) => { - const xResults = new Array(width); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 2); - } - return xResults; - }, - erect2DArray2: (array, width, height) => { - const yResults = new Array(height); - const XResultsMax = width * 4; - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * XResultsMax; - let i = 0; - for (let x = 0; x < XResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 2); - } - yResults[y] = xResults; + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult', + ]; } - return yResults; - }, - erect3DArray2: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 2); + getMainResultSubKernelNumberTexture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}`, + ); } - yResults[y] = xResults; } - zResults[z] = yResults; + return result; } - return zResults; - }, - erectArray3: (array, width) => { - const xResults = new Array(width); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 3); - } - return xResults; - }, - erect2DArray3: (array, width, height) => { - const xResultsMax = width * 4; - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * xResultsMax; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 3); + getMainResultKernelArray2Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult[0]', + ' data0[1] = kernelResult[1]', + ]; + } + getMainResultSubKernelArray2Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, + ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, + ); } - yResults[y] = xResults; + return result; } - return yResults; - }, - erect3DArray3: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 3); - } - yResults[y] = xResults; + getMainResultKernelArray3Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult[0]', + ' data0[1] = kernelResult[1]', + ' data0[2] = kernelResult[2]', + ]; + } + getMainResultSubKernelArray3Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, + ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, + ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`, + ); } - zResults[z] = yResults; + return result; } - return zResults; - }, - erectArray4: (array, width) => { - const xResults = new Array(array); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 4); - } - return xResults; - }, - erect2DArray4: (array, width, height) => { - const xResultsMax = width * 4; - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * xResultsMax; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 4); + getMainResultKernelArray4Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0 = kernelResult', + ]; + } + getMainResultSubKernelArray4Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`, + ); } - yResults[y] = xResults; + return result; } - return yResults; - }, - erect3DArray4: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 4); + destroyExtensions() { + this.extensions.EXT_color_buffer_float = null; + this.extensions.OES_texture_float_linear = null; + } + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON(); + return json; + } + } + + function kernelRunShortcut(kernel) { + let run = function() { + kernel.build.apply(kernel, arguments); + if (kernel.renderKernels) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderKernels(); + }; + } else if (kernel.renderOutput) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderOutput(); + }; + } else { + run = function() { + return kernel.run.apply(kernel, arguments); + }; + } + return run.apply(kernel, arguments); + }; + const shortcut = function() { + return run.apply(kernel, arguments); + }; + shortcut.exec = function() { + return new Promise((accept, reject) => { + try { + accept(run.apply(this, arguments)); + } catch (e) { + reject(e); } - yResults[y] = xResults; + }); + }; + shortcut.replaceKernel = function(replacementKernel) { + kernel = replacementKernel; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + }; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + return shortcut; + } + function bindKernelToShortcut(kernel, shortcut) { + const properties = utils$1.allPropertiesOf(kernel); + for (let i = 0; i < properties.length; i++) { + const property = properties[i]; + if (property[0] === '_' && property[1] === '_') continue; + if (typeof kernel[property] === 'function') { + if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') { + shortcut[property] = function() { + kernel[property].apply(kernel, arguments); + return shortcut; + }; + } else { + if (property === 'toString') { + shortcut.toString = function() { + return kernel.toString.apply(kernel, arguments); + }; + } else { + shortcut[property] = kernel[property].bind(kernel); + } + } + } else { + shortcut.__defineGetter__(property, () => { + return kernel[property]; + }); + shortcut.__defineSetter__(property, (value) => { + kernel[property] = value; + }); } - zResults[z] = yResults; } - return zResults; - }, - - flattenFunctionToString: (source, settings) => { - const { findDependency, thisLookup, doNotDefine } = settings; - let flattened = settings.flattened; - if (!flattened) { - flattened = settings.flattened = {}; - } - const ast = acorn.parse(source); - const functionDependencies = []; + } - function flatten(ast) { - if (Array.isArray(ast)) { - const results = []; - for (let i = 0; i < ast.length; i++) { - results.push(flatten(ast[i])); + const kernelOrder = [ WebGL2Kernel, WebGLKernel ]; + const kernelTypes = [ 'gpu', 'cpu' ]; + const internalKernels = { + 'webgl2': WebGL2Kernel, + 'webgl': WebGLKernel, + }; + let validate = true; + class GPU { + static disableValidation() { + validate = false; + } + static enableValidation() { + validate = true; + } + static get isGPUSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported); + } + static get isKernelMapSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); + } + static get isOffscreenCanvasSupported() { + return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined'; + } + static get isWebGLSupported() { + return WebGLKernel.isSupported; + } + static get isWebGL2Supported() { + return WebGL2Kernel.isSupported; + } + static get isHeadlessGLSupported() { + return false; + } + static get isCanvasSupported() { + return typeof HTMLCanvasElement !== 'undefined'; + } + static get isGPUHTMLImageArraySupported() { + return WebGL2Kernel.isSupported; + } + static get isSinglePrecisionSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + } + constructor(settings) { + settings = settings || {}; + this.canvas = settings.canvas || null; + this.context = settings.context || null; + this.mode = settings.mode; + this.Kernel = null; + this.kernels = []; + this.functions = []; + this.nativeFunctions = []; + this.injectedNative = null; + if (this.mode === 'dev') return; + this.chooseKernel(); + if (settings.functions) { + for (let i = 0; i < settings.functions.length; i++) { + this.addFunction(settings.functions[i]); } - return results.join(''); } - switch (ast.type) { - case 'Program': - return flatten(ast.body); - case 'FunctionDeclaration': - return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; - case 'BlockStatement': { - const result = []; - for (let i = 0; i < ast.body.length; i++) { - result.push(flatten(ast.body[i]), ';\n'); - } - return `{\n${result.join('')}}`; + if (settings.nativeFunctions) { + for (const p in settings.nativeFunctions) { + this.addNativeFunction(p, settings.nativeFunctions[p]); } - case 'VariableDeclaration': - switch (ast.declarations[0].id.type) { - case 'ObjectPattern': { - const source = flatten(ast.declarations[0].init); - const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; - if (/this/.test(source)) { - const result = []; - const lookups = properties.map(thisLookup); - for (let i = 0; i < lookups.length; i++) { - const lookup = lookups[i]; - if (lookup === null) continue; - const property = properties[i]; - result.push(`${ast.kind} ${ property } = ${ lookup };\n`); - } - - return result.join(''); - } - return `${ast.kind} { ${properties} } = ${source}`; + } + } + getValidate() { + return validate; + } + chooseKernel() { + if (this.Kernel) return; + let Kernel = null; + if (this.context) { + for (let i = 0; i < kernelOrder.length; i++) { + const ExternalKernel = kernelOrder[i]; + if (ExternalKernel.isContextMatch(this.context)) { + if (!ExternalKernel.isSupported) { + throw new Error(`Kernel type ${ExternalKernel.name} not supported`); } - case 'ArrayPattern': - return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; + Kernel = ExternalKernel; + break; } - if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { - return ''; + } + if (Kernel === null) { + throw new Error('unknown Context'); + } + } else if (this.mode) { + if (this.mode in internalKernels) { + if (!validate || internalKernels[this.mode].isSupported) { + Kernel = internalKernels[this.mode]; } - return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`; - case 'CallExpression': { - if (ast.callee.property.name === 'subarray') { - return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else if (this.mode === 'gpu') { + for (let i = 0; i < kernelOrder.length; i++) { + if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } } - if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') { - return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else if (this.mode === 'cpu') { + Kernel = CPUKernel; + } + if (!Kernel) { + throw new Error(`A requested mode of "${this.mode}" and is not supported`); + } + } else { + for (let i = 0; i < kernelOrder.length; i++) { + if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; } - if (ast.callee.object.type === 'ThisExpression') { - functionDependencies.push(findDependency('this', ast.callee.property.name)); - return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } else if (ast.callee.object.name) { - const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name); - if (foundSource === null) { - return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } else { - functionDependencies.push(foundSource); - return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } - } else if (ast.callee.object.type === 'MemberExpression') { - return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + if (!Kernel) { + Kernel = CPUKernel; + } + } + if (!this.mode) { + this.mode = Kernel.mode; + } + this.Kernel = Kernel; + } + createKernel(source, settings) { + if (typeof source === 'undefined') { + throw new Error('Missing source parameter'); + } + if (typeof source !== 'object' && !isFunction(source) && typeof source !== 'string') { + throw new Error('source parameter not a function'); + } + if (this.mode === 'dev') { + const devKernel = gpuMock_js_1(source, upgradeDeprecatedCreateKernelSettings(settings)); + this.kernels.push(devKernel); + return devKernel; + } + source = typeof source === 'function' ? source.toString() : source; + const switchableKernels = {}; + const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {}; + if (settings && typeof settings.argumentTypes === 'object') { + settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + } + function onRequestFallback(args) { + const fallbackKernel = new CPUKernel(source, { + argumentTypes: kernelRun.argumentTypes, + constantTypes: kernelRun.constantTypes, + graphical: kernelRun.graphical, + loopMaxIterations: kernelRun.loopMaxIterations, + constants: kernelRun.constants, + dynamicOutput: kernelRun.dynamicOutput, + dynamicArgument: kernelRun.dynamicArguments, + output: kernelRun.output, + precision: kernelRun.precision, + pipeline: kernelRun.pipeline, + immutable: kernelRun.immutable, + optimizeFloatMemory: kernelRun.optimizeFloatMemory, + fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy, + functions: kernelRun.functions, + nativeFunctions: kernelRun.nativeFunctions, + injectedNative: kernelRun.injectedNative, + subKernels: kernelRun.subKernels, + strictIntegers: kernelRun.strictIntegers, + debug: kernelRun.debug, + warnVarUsage: kernelRun.warnVarUsage, + }); + fallbackKernel.build.apply(fallbackKernel, args); + const result = fallbackKernel.run.apply(fallbackKernel, args); + kernelRun.replaceKernel(fallbackKernel); + return result; + } + function onRequestSwitchKernel(args, kernel) { + const argumentTypes = new Array(args.length); + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + const type = kernel.argumentTypes[i]; + if (arg.type) { + argumentTypes[i] = arg.type; } else { - throw new Error('unknown ast.callee'); + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'ArrayTexture(1)': + argumentTypes[i] = getVariableType(arg); + break; + default: + argumentTypes[i] = type; + } } } - case 'ReturnStatement': - return `return ${flatten(ast.argument)}`; - case 'BinaryExpression': - return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`; - case 'UnaryExpression': - if (ast.prefix) { - return `${ast.operator} ${flatten(ast.argument)}`; + const signature = argumentTypes.join(','); + const existingKernel = switchableKernels[signature]; + if (existingKernel) { + existingKernel.run.apply(existingKernel, args); + if (existingKernel.renderKernels) { + return existingKernel.renderKernels(); } else { - return `${flatten(ast.argument)} ${ast.operator}`; + return existingKernel.renderOutput(); } - case 'ExpressionStatement': - return `(${flatten(ast.expression)})`; - case 'ArrowFunctionExpression': - return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`; - case 'Literal': - return ast.raw; - case 'Identifier': - return ast.name; - case 'MemberExpression': - if (ast.object.type === 'ThisExpression') { - return thisLookup(ast.property.name); - } - if (ast.computed) { - return `${flatten(ast.object)}[${flatten(ast.property)}]`; - } - return flatten(ast.object) + '.' + flatten(ast.property); - case 'ThisExpression': - return 'this'; - case 'NewExpression': - return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - case 'ForStatement': - return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`; - case 'AssignmentExpression': - return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`; - case 'UpdateExpression': - return `${flatten(ast.argument)}${ast.operator}`; - case 'IfStatement': - return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`; - case 'ThrowStatement': - return `throw ${flatten(ast.argument)}`; - case 'ObjectPattern': - return ast.properties.map(flatten).join(', '); - case 'ArrayPattern': - return ast.elements.map(flatten).join(', '); - case 'DebuggerStatement': - return 'debugger;'; - case 'ConditionalExpression': - return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`; - case 'Property': - if (ast.kind === 'init') { - return flatten(ast.key); - } + } + const newKernel = switchableKernels[signature] = new kernel.constructor(source, { + argumentTypes, + constantTypes: kernel.constantTypes, + graphical: kernel.graphical, + loopMaxIterations: kernel.loopMaxIterations, + constants: kernel.constants, + dynamicOutput: kernel.dynamicOutput, + dynamicArgument: kernel.dynamicArguments, + context: kernel.context, + canvas: kernel.canvas, + output: kernel.output, + precision: kernel.precision, + pipeline: kernel.pipeline, + immutable: kernel.immutable, + optimizeFloatMemory: kernel.optimizeFloatMemory, + fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy, + functions: kernel.functions, + nativeFunctions: kernel.nativeFunctions, + injectedNative: kernel.injectedNative, + subKernels: kernel.subKernels, + strictIntegers: kernel.strictIntegers, + debug: kernel.debug, + gpu: kernel.gpu, + validate, + warnVarUsage: kernel.warnVarUsage, + returnType: kernel.returnType, + onRequestFallback, + onRequestSwitchKernel, + }); + newKernel.build.apply(newKernel, args); + newKernel.run.apply(newKernel, args); + kernelRun.replaceKernel(newKernel); + if (newKernel.renderKernels) { + return newKernel.renderKernels(); + } else { + return newKernel.renderOutput(); + } + } + const mergedSettings = Object.assign({ + context: this.context, + canvas: this.canvas, + functions: this.functions, + nativeFunctions: this.nativeFunctions, + injectedNative: this.injectedNative, + gpu: this, + validate, + onRequestFallback, + onRequestSwitchKernel + }, settingsCopy); + const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); + if (!this.canvas) { + this.canvas = kernelRun.canvas; + } + if (!this.context) { + this.context = kernelRun.context; + } + this.kernels.push(kernelRun); + return kernelRun; + } + createKernelMap() { + let fn; + let settings; + if (typeof arguments[arguments.length - 2] === 'function') { + fn = arguments[arguments.length - 2]; + settings = arguments[arguments.length - 1]; + } else { + fn = arguments[arguments.length - 1]; } - throw new Error(`unhandled ast.type of ${ ast.type }`); + if (this.mode !== 'dev') { + if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { + if (this.mode && kernelTypes.indexOf(this.mode) < 0) { + throw new Error(`kernelMap not supported on ${this.Kernel.name}`); + } + } + } + const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings); + if (settings && typeof settings.argumentTypes === 'object') { + settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + } + if (Array.isArray(arguments[0])) { + settingsCopy.subKernels = []; + const functions = arguments[0]; + for (let i = 0; i < functions.length; i++) { + const source = functions[i].toString(); + const name = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name, + source, + property: i, + }); + } + } else { + settingsCopy.subKernels = []; + const functions = arguments[0]; + for (let p in functions) { + if (!functions.hasOwnProperty(p)) continue; + const source = functions[p].toString(); + const name = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name: name || p, + source, + property: p, + }); + } + } + const kernel = this.createKernel(fn, settingsCopy); + return kernel; } - const result = flatten(ast); - if (functionDependencies.length > 0) { - const flattenedFunctionDependencies = []; - for (let i = 0; i < functionDependencies.length; i++) { - const functionDependency = functionDependencies[i]; - if (!flattened[functionDependency]) { - flattened[functionDependency] = true; + combineKernels() { + const firstKernel = arguments[0]; + const combinedKernel = arguments[arguments.length - 1]; + if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel; + const canvas = arguments[0].canvas; + const context = arguments[0].context; + const max = arguments.length - 1; + for (let i = 0; i < max; i++) { + arguments[i] + .setCanvas(canvas) + .setContext(context) + .setPipeline(true); + } + return function() { + const texture = combinedKernel.apply(this, arguments); + if (texture.toArray) { + return texture.toArray(); } - flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\n'); + return texture; + }; + } + addFunction(source, settings) { + this.functions.push(functionToIFunction(source, settings)); + return this; + } + addNativeFunction(name, source, settings) { + if (this.kernels.length > 0) { + throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); } - return flattenedFunctionDependencies.join('') + result; + settings = settings || {}; + const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; + this.nativeFunctions.push({ + name, + source, + settings, + argumentTypes, + argumentNames, + returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), + }); + return this; + } + injectNative(source) { + this.injectedNative = source; + return this; + } + destroy() { + if (!this.kernels) return; + setTimeout(() => { + for (let i = 0; i < this.kernels.length; i++) { + this.kernels[i].destroy(true); + } + let firstKernel = this.kernels[0]; + if (firstKernel) { + if (firstKernel.kernel) { + firstKernel = firstKernel.kernel; + } + if (firstKernel.constructor.destroyContext) { + firstKernel.constructor.destroyContext(this.context); + } + } + }, 0); } - return result; - }, - - splitHTMLImageToRGB: (image, mode) => { - const gpu = new GPU({ mode }); - - const rKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.r * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const gKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.g * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const bKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.b * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const aKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.a * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const result = [ - rKernel(image), - gKernel(image), - bKernel(image), - aKernel(image), - ]; - result.rKernel = rKernel; - result.gKernel = gKernel; - result.bKernel = bKernel; - result.aKernel = aKernel; - result.gpu = gpu; - return result; - }, - - splitRGBAToCanvases: (rgba, width, height, mode) => { - const { GPU } = require('./gpu.js'); - - const visualGPUR = new GPU({ mode }); - const visualKernelR = visualGPUR.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(pixel.r / 255, 0, 0, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelR(rgba); - - const visualGPUG = new GPU({ mode }); - const visualKernelG = visualGPUG.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(0, pixel.g / 255, 0, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelG(rgba); - - const visualGPUB = new GPU({ mode }); - const visualKernelB = visualGPUB.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(0, 0, pixel.b / 255, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelB(rgba); - - const visualGPUA = new GPU({ mode }); - const visualKernelA = visualGPUA.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(255, 255, 255, pixel.a / 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelA(rgba); - - visualGPUR.destroy(); - visualGPUG.destroy(); - visualGPUB.destroy(); - visualGPUA.destroy(); - - return [ - visualKernelR.canvas, - visualKernelG.canvas, - visualKernelB.canvas, - visualKernelA.canvas, - ]; } -}; + function upgradeDeprecatedCreateKernelSettings(settings) { + if (!settings) { + return {}; + } + const upgradedSettings = Object.assign({}, settings); + if (settings.hasOwnProperty('floatOutput')) { + warnDeprecated('setting', 'floatOutput', 'precision'); + upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; + } + if (settings.hasOwnProperty('outputToTexture')) { + warnDeprecated('setting', 'outputToTexture', 'pipeline'); + upgradedSettings.pipeline = Boolean(settings.outputToTexture); + } + if (settings.hasOwnProperty('outputImmutable')) { + warnDeprecated('setting', 'outputImmutable', 'immutable'); + upgradedSettings.immutable = Boolean(settings.outputImmutable); + } + if (settings.hasOwnProperty('floatTextures')) { + warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); + upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); + } + return upgradedSettings; + } -const _systemEndianness = utils.getSystemEndianness(); + function alias(name, source) { + const fnString = source.toString(); + return new Function(`return function ${ name } (${ utils$1.getArgumentNamesFromString(fnString).join(', ') }) { + ${ utils$1.getFunctionBodyFromString(fnString) } +}`)(); + } -module.exports = { - utils -}; -},{"./gpu.js":106,"./input":108,"./texture":111,"acorn":1}]},{},[105])(105) -}); + class HeadlessGLKernel extends WebGLKernel { + static get isSupported() { return false } + static isContextMatch() { return false } + static getIsTextureFloat() { return false } + static getIsDrawBuffers() { return false } + static getChannelCount() { return 1 } + static get testCanvas() { return null } + static get testContext() { return null } + static get features() { return null } + static setupFeatureChecks() {} + static destroyContext() {} + initCanvas() { return {} } + initContext() { return null } + toString() { return '' } + initExtensions() {} + build() {} + destroyExtensions() {} + setOutput() {} + static getFeatures() { + return Object.freeze({ + isFloatRead: false, + isIntegerDivisionAccurate: false, + isTextureFloat: false, + isDrawBuffers: false, + kernelMap: false, + channelCount: 1, + }); + } + }const lib = GPU; + lib.alias = alias; + lib.CPUFunctionNode = CPUFunctionNode; + lib.CPUKernel = CPUKernel; + lib.FunctionBuilder = FunctionBuilder; + lib.FunctionNode = FunctionNode; + lib.HeadlessGLKernel = HeadlessGLKernel; + lib.Input = Input; + lib.input = input; + lib.Texture = Texture; + lib.utils = { ...common, ...utils$1 }; + lib.WebGL2FunctionNode = WebGL2FunctionNode; + lib.WebGL2Kernel = WebGL2Kernel; + lib.WebGLFunctionNode = WebGLFunctionNode; + lib.WebGLKernel = WebGLKernel; + lib.GLKernel = GLKernel; + lib.Kernel = Kernel; + + return lib; + +}()); +//# sourceMappingURL=gpu-browser.js.map diff --git a/dist/gpu-browser.js.map b/dist/gpu-browser.js.map new file mode 100644 index 00000000..ac7ddb42 --- /dev/null +++ b/dist/gpu-browser.js.map @@ -0,0 +1 @@ +{"version":3,"file":"gpu-browser.js","sources":["../node_modules/gpu-mock.js/index.js","../src/common.js","../src/input.js","../node_modules/acorn/dist/acorn.es.js","../src/texture.js","../src/utils.js","../src/backend/kernel.js","../src/backend/function-builder.js","../src/backend/function-tracer.js","../src/backend/function-node.js","../src/backend/cpu/function-node.js","../src/backend/cpu/kernel-string.js","../src/backend/cpu/kernel.js","../src/backend/gl/texture/float.js","../src/backend/gl/texture/array-2-float.js","../src/backend/gl/texture/array-2-float-2d.js","../src/backend/gl/texture/array-2-float-3d.js","../src/backend/gl/texture/array-3-float.js","../src/backend/gl/texture/array-3-float-2d.js","../src/backend/gl/texture/array-3-float-3d.js","../src/backend/gl/texture/array-4-float.js","../src/backend/gl/texture/array-4-float-2d.js","../src/backend/gl/texture/array-4-float-3d.js","../src/backend/gl/texture/float-2d.js","../src/backend/gl/texture/float-3d.js","../src/backend/gl/texture/memory-optimized.js","../src/backend/gl/texture/memory-optimized-2d.js","../src/backend/gl/texture/memory-optimized-3d.js","../src/backend/gl/texture/unsigned.js","../src/backend/gl/texture/unsigned-2d.js","../src/backend/gl/texture/unsigned-3d.js","../src/backend/gl/texture/graphical.js","../src/backend/gl/kernel.js","../src/backend/web-gl/function-node.js","../src/plugins/triangle-noise.js","../src/backend/web-gl/fragment-shader.js","../src/backend/web-gl/vertex-shader.js","../node_modules/gl-wiretap/index.js","../src/backend/gl/kernel-string.js","../src/backend/kernel-value.js","../src/backend/web-gl/kernel-value/index.js","../src/backend/web-gl/kernel-value/boolean.js","../src/backend/web-gl/kernel-value/float.js","../src/backend/web-gl/kernel-value/integer.js","../src/backend/web-gl/kernel-value/html-image.js","../src/backend/web-gl/kernel-value/dynamic-html-image.js","../src/backend/web-gl/kernel-value/html-video.js","../src/backend/web-gl/kernel-value/dynamic-html-video.js","../src/backend/web-gl/kernel-value/single-input.js","../src/backend/web-gl/kernel-value/dynamic-single-input.js","../src/backend/web-gl/kernel-value/unsigned-input.js","../src/backend/web-gl/kernel-value/dynamic-unsigned-input.js","../src/backend/web-gl/kernel-value/memory-optimized-number-texture.js","../src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js","../src/backend/web-gl/kernel-value/number-texture.js","../src/backend/web-gl/kernel-value/dynamic-number-texture.js","../src/backend/web-gl/kernel-value/single-array.js","../src/backend/web-gl/kernel-value/dynamic-single-array.js","../src/backend/web-gl/kernel-value/single-array1d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js","../src/backend/web-gl/kernel-value/single-array2d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js","../src/backend/web-gl/kernel-value/single-array3d-i.js","../src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js","../src/backend/web-gl/kernel-value/single-array2.js","../src/backend/web-gl/kernel-value/single-array3.js","../src/backend/web-gl/kernel-value/single-array4.js","../src/backend/web-gl/kernel-value/unsigned-array.js","../src/backend/web-gl/kernel-value/dynamic-unsigned-array.js","../src/backend/web-gl/kernel-value-maps.js","../src/backend/web-gl/kernel.js","../src/backend/web-gl2/function-node.js","../src/backend/web-gl2/fragment-shader.js","../src/backend/web-gl2/vertex-shader.js","../src/backend/web-gl2/kernel-value/boolean.js","../src/backend/web-gl2/kernel-value/float.js","../src/backend/web-gl2/kernel-value/integer.js","../src/backend/web-gl2/kernel-value/html-image.js","../src/backend/web-gl2/kernel-value/dynamic-html-image.js","../src/backend/web-gl2/kernel-value/html-image-array.js","../src/backend/web-gl2/kernel-value/dynamic-html-image-array.js","../src/backend/web-gl2/kernel-value/html-video.js","../src/backend/web-gl2/kernel-value/dynamic-html-video.js","../src/backend/web-gl2/kernel-value/single-input.js","../src/backend/web-gl2/kernel-value/dynamic-single-input.js","../src/backend/web-gl2/kernel-value/unsigned-input.js","../src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js","../src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js","../src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js","../src/backend/web-gl2/kernel-value/number-texture.js","../src/backend/web-gl2/kernel-value/dynamic-number-texture.js","../src/backend/web-gl2/kernel-value/single-array.js","../src/backend/web-gl2/kernel-value/dynamic-single-array.js","../src/backend/web-gl2/kernel-value/single-array1d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js","../src/backend/web-gl2/kernel-value/single-array2d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js","../src/backend/web-gl2/kernel-value/single-array3d-i.js","../src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js","../src/backend/web-gl2/kernel-value/single-array2.js","../src/backend/web-gl2/kernel-value/single-array3.js","../src/backend/web-gl2/kernel-value/single-array4.js","../src/backend/web-gl2/kernel-value/unsigned-array.js","../src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js","../src/backend/web-gl2/kernel-value-maps.js","../src/backend/web-gl2/kernel.js","../src/kernel-run-shortcut.js","../src/base-gpu.js","../src/alias.js","../src/browser.js"],"sourcesContent":["function setupArguments(args) {\n const newArguments = new Array(args.length);\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n if (arg.toArray) {\n newArguments[i] = arg.toArray();\n } else {\n newArguments[i] = arg;\n }\n }\n return newArguments;\n}\n\nfunction mock1D() {\n const args = setupArguments(arguments);\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = 0;\n this.thread.z = 0;\n row[x] = this._fn.apply(this, args);\n }\n return row;\n}\n\nfunction mock2D() {\n const args = setupArguments(arguments);\n const matrix = new Array(this.output.y);\n for (let y = 0; y < this.output.y; y++) {\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = 0;\n row[x] = this._fn.apply(this, args);\n }\n matrix[y] = row;\n }\n return matrix;\n}\n\nfunction mock2DGraphical() {\n const args = setupArguments(arguments);\n for (let y = 0; y < this.output.y; y++) {\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = 0;\n this._fn.apply(this, args);\n }\n }\n}\n\nfunction mock3D() {\n const args = setupArguments(arguments);\n const cube = new Array(this.output.z);\n for (let z = 0; z < this.output.z; z++) {\n const matrix = new Array(this.output.y);\n for (let y = 0; y < this.output.y; y++) {\n const row = new Float32Array(this.output.x);\n for (let x = 0; x < this.output.x; x++) {\n this.thread.x = x;\n this.thread.y = y;\n this.thread.z = z;\n row[x] = this._fn.apply(this, args);\n }\n matrix[y] = row;\n }\n cube[z] = matrix;\n }\n return cube;\n}\n\nfunction apiDecorate(kernel) {\n kernel.setOutput = (output) => {\n kernel.output = setupOutput(output);\n if (kernel.graphical) {\n setupGraphical(kernel);\n }\n };\n kernel.toJSON = () => {\n throw new Error('Not usable with gpuMock');\n };\n kernel.setConstants = (flag) => {\n kernel.constants = flag;\n return kernel;\n };\n kernel.setGraphical = (flag) => {\n kernel.graphical = flag;\n return kernel;\n };\n kernel.setCanvas = (flag) => {\n kernel.canvas = flag;\n return kernel;\n };\n kernel.setContext = (flag) => {\n kernel.context = flag;\n return kernel;\n };\n kernel.exec = function() {\n return new Promise((resolve, reject) => {\n try {\n resolve(kernel.apply(kernel, arguments));\n } catch(e) {\n reject(e);\n }\n });\n };\n kernel.getPixels = (flip) => {\n const {x, y} = kernel.output;\n // cpu is not flipped by default\n return flip ? flipPixels(kernel._imageData.data, x, y) : kernel._imageData.data.slice(0);\n };\n kernel.color = function(r, g, b, a) {\n if (typeof a === 'undefined') {\n a = 1;\n }\n\n r = Math.floor(r * 255);\n g = Math.floor(g * 255);\n b = Math.floor(b * 255);\n a = Math.floor(a * 255);\n\n const width = kernel.output.x;\n const height = kernel.output.y;\n\n const x = kernel.thread.x;\n const y = height - kernel.thread.y - 1;\n\n const index = x + y * width;\n\n kernel._colorData[index * 4 + 0] = r;\n kernel._colorData[index * 4 + 1] = g;\n kernel._colorData[index * 4 + 2] = b;\n kernel._colorData[index * 4 + 3] = a;\n };\n\n // these are added for api compatibility, but have no affect\n kernel.setWarnVarUsage = () => {\n return kernel;\n };\n kernel.setOptimizeFloatMemory = () => {\n return kernel;\n };\n kernel.setArgumentTypes = () => {\n return kernel;\n };\n kernel.setDebug = () => {\n return kernel;\n };\n kernel.setLoopMaxIterations = () => {\n return kernel;\n };\n kernel.setPipeline = () => {\n return kernel;\n };\n kernel.setPrecision = () => {\n return kernel;\n };\n kernel.setImmutable = () => {\n return kernel;\n };\n kernel.setFunctions = () => {\n return kernel;\n };\n kernel.addSubKernel = () => {\n return kernel;\n };\n kernel.destroy = () => {};\n kernel.validateSettings = () => {};\n if (kernel.graphical && kernel.output) {\n setupGraphical(kernel);\n }\n return kernel;\n}\n\nfunction setupGraphical(kernel) {\n const {x, y} = kernel.output;\n if (kernel.context && kernel.context.createImageData) {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = kernel.context.createImageData(x, y);\n kernel._colorData = data;\n } else {\n const data = new Uint8ClampedArray(x * y * 4);\n kernel._imageData = { data };\n kernel._colorData = data;\n }\n}\n\nfunction setupOutput(output) {\n let result = null;\n if (output.length) {\n if (output.length === 3) {\n const [x,y,z] = output;\n result = { x, y, z };\n } else if (output.length === 2) {\n const [x,y] = output;\n result = { x, y };\n } else {\n const [x] = output;\n result = { x };\n }\n } else {\n result = output;\n }\n return result;\n}\n\nfunction gpuMock(fn, settings = {}) {\n const output = settings.output ? setupOutput(settings.output) : null;\n function kernel() {\n if (kernel.output.z) {\n return mock3D.apply(kernel, arguments);\n } else if (kernel.output.y) {\n if (kernel.graphical) {\n return mock2DGraphical.apply(kernel, arguments);\n }\n return mock2D.apply(kernel, arguments);\n } else {\n return mock1D.apply(kernel, arguments);\n }\n }\n kernel._fn = fn;\n kernel.constants = settings.constants || null;\n kernel.context = settings.context || null;\n kernel.canvas = settings.canvas || null;\n kernel.graphical = settings.graphical || false;\n kernel._imageData = null;\n kernel._colorData = null;\n kernel.output = output;\n kernel.thread = {\n x: 0,\n y: 0,\n z: 0\n };\n return apiDecorate(kernel);\n}\n\nfunction flipPixels(pixels, width, height) {\n // https://stackoverflow.com/a/41973289/1324039\n const halfHeight = height / 2 | 0; // the | 0 keeps the result an int\n const bytesPerRow = width * 4;\n // make a temp buffer to hold one row\n const temp = new Uint8ClampedArray(width * 4);\n const result = pixels.slice(0);\n for (let y = 0; y < halfHeight; ++y) {\n const topOffset = y * bytesPerRow;\n const bottomOffset = (height - y - 1) * bytesPerRow;\n\n // make copy of a row on the top half\n temp.set(result.subarray(topOffset, topOffset + bytesPerRow));\n\n // copy a row from the bottom half to the top\n result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow);\n\n // copy the copy of the top half row to the bottom half\n result.set(temp, bottomOffset);\n }\n return result;\n}\n\nmodule.exports = {\n gpuMock\n};\n","/**\r\n * @fileoverview Branch of utils to prevent circular dependencies.\r\n */\r\n\r\nconst ARGUMENT_NAMES = /([^\\s,]+)/g;\r\nconst FUNCTION_NAME = /function ([^(]*)/;\r\nconst STRIP_COMMENTS = /((\\/\\/.*$)|(\\/\\*[\\s\\S]*?\\*\\/))/mg;\r\n\r\n/**\r\n * @descReturn TRUE, on a JS function\r\n * @param {Function} funcObj - Object to validate if its a function\r\n * @returns {Boolean} TRUE if the object is a JS function\r\n */\r\nexport function isFunction(funcObj) {\r\n return typeof(funcObj) === 'function';\r\n};\r\n\r\n/**\r\n * @desc Return the function name from a JS function string\r\n * @param {String} funcStr - String of JS function to validate\r\n * @returns {String} Function name string (if found)\r\n */\r\nexport function getFunctionNameFromString(funcStr) {\r\n return FUNCTION_NAME.exec(funcStr)[1].trim();\r\n};\r\n\r\n/**\r\n *\r\n * @param {String|Function} source\r\n * @param {IFunctionSettings} [settings]\r\n * @returns {IFunction}\r\n */\r\nexport function functionToIFunction(source, settings) {\r\n settings = settings || {};\r\n if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function');\r\n const sourceString = typeof source === 'string' ? source : source.toString();\r\n\r\n let argumentTypes = [];\r\n\r\n if (Array.isArray(settings.argumentTypes)) {\r\n argumentTypes = settings.argumentTypes;\r\n } else if (typeof settings.argumentTypes === 'object') {\r\n argumentTypes = getArgumentNamesFromString(sourceString)\r\n .map(name => settings.argumentTypes[name]) || [];\r\n } else {\r\n argumentTypes = settings.argumentTypes || [];\r\n }\r\n\r\n return {\r\n source: sourceString,\r\n argumentTypes,\r\n returnType: settings.returnType || null,\r\n };\r\n};\r\n\r\nexport function warnDeprecated(type, oldName, newName) {\r\n const msg = newName\r\n ? `It has been replaced with \"${ newName }\"`\r\n : 'It has been removed';\r\n console.warn(`You are using a deprecated ${ type } \"${ oldName }\". ${msg}. Fixing, but please upgrade as it will soon be removed.`)\r\n};\r\n\r\n/**\r\n * @desc Return TRUE, on a valid JS function string\r\n * Note: This does just a VERY simply sanity check. And may give false positives.\r\n *\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {Boolean} TRUE if the string passes basic validation\r\n */\r\nexport function isFunctionString(fn) {\r\n if (typeof fn === 'string') {\r\n return (fn\r\n .slice(0, 'function'.length)\r\n .toLowerCase() === 'function');\r\n }\r\n return false;\r\n};\r\n\r\n/**\r\n * @desc Return list of argument names extracted from a javascript function\r\n * @param {String} fn - String of JS function to validate\r\n * @returns {String[]} Array representing all the parameter names\r\n */\r\nexport function getArgumentNamesFromString(fn) {\r\n const fnStr = fn.replace(STRIP_COMMENTS, '');\r\n let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);\r\n if (result === null) {\r\n result = [];\r\n }\r\n return result;\r\n};\r\n\r\n/**\r\n * @desc Checks if is an array or Array-like object\r\n * @param {Object} array - The argument object to check if is array\r\n * @returns {Boolean} true if is array or Array-like object\r\n */\r\nexport function isArray(array) {\r\n return !isNaN(array.length);\r\n};\r\n\r\nexport function erectMemoryOptimized2DFloat(array, width, height) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = y * width;\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n return yResults;\r\n};\r\n\r\nexport function erectMemoryOptimized3DFloat(array, width, height, depth) {\r\n const zResults = new Array(depth);\r\n for (let z = 0; z < depth; z++) {\r\n const yResults = new Array(height);\r\n for (let y = 0; y < height; y++) {\r\n const offset = (z * height * width) + (y * width);\r\n yResults[y] = array.subarray(offset, offset + width);\r\n }\r\n zResults[z] = yResults;\r\n }\r\n return zResults;\r\n};\r\n\r\nexport function getAstString(source, ast) {\r\n const lines = Array.isArray(source) ? source : source.split(/\\r?\\n/g);\r\n const start = ast.loc.start;\r\n const end = ast.loc.end;\r\n const result = [];\r\n if (start.line === end.line) {\r\n result.push(lines[start.line - 1].substring(start.column, end.column));\r\n } else {\r\n result.push(lines[start.line - 1].slice(start.column));\r\n for (let i = start.line; i < end.line; i++) {\r\n result.push(lines[i]);\r\n }\r\n result.push(lines[end.line - 1].slice(0, end.column));\r\n }\r\n return result.join('\\n');\r\n};\r\n","import { erectMemoryOptimized2DFloat, erectMemoryOptimized3DFloat } from './common';\r\n\r\nexport class Input {\r\n constructor(value, size) {\r\n this.value = value;\r\n if (Array.isArray(size)) {\r\n this.size = size;\r\n } else {\r\n this.size = new Int32Array(3);\r\n if (size.z) {\r\n this.size = new Int32Array([size.x, size.y, size.z]);\r\n } else if (size.y) {\r\n this.size = new Int32Array([size.x, size.y]);\r\n } else {\r\n this.size = new Int32Array([size.x]);\r\n }\r\n }\r\n\r\n const [w, h, d] = this.size;\r\n if (d) {\r\n if (this.value.length !== (w * h * d)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`);\r\n }\r\n } else if (h) {\r\n if (this.value.length !== (w * h)) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`);\r\n }\r\n } else {\r\n if (this.value.length !== w) {\r\n throw new Error(`Input size ${this.value.length} does not match ${w}`);\r\n }\r\n }\r\n\r\n }\r\n\r\n toArray() {\r\n const [ w, h, d ] = this.size;\r\n if (d) {\r\n return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d);\r\n } else if (h) {\r\n return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h);\r\n } else {\r\n return this.value;\r\n }\r\n }\r\n};\r\n\r\nexport function input(value, size) {\r\n return new Input(value, size);\r\n};\r\n","// Reserved word lists for various dialects of the language\n\nvar reservedWords = {\n 3: \"abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile\",\n 5: \"class enum extends super const export import\",\n 6: \"enum\",\n strict: \"implements interface let package private protected public static yield\",\n strictBind: \"eval arguments\"\n};\n\n// And the keywords\n\nvar ecma5AndLessKeywords = \"break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this\";\n\nvar keywords = {\n 5: ecma5AndLessKeywords,\n 6: ecma5AndLessKeywords + \" const class extends export import super\"\n};\n\nvar keywordRelationalOperator = /^in(stanceof)?$/;\n\n// ## Character categories\n\n// Big ugly regular expressions that match characters in the\n// whitespace, identifier, and identifier-start categories. These\n// are only applied when a character is found to actually have a\n// code point above 128.\n// Generated by `bin/generate-identifier-regex.js`.\n\nvar nonASCIIidentifierStartChars = \"\\xaa\\xb5\\xba\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\u02c1\\u02c6-\\u02d1\\u02e0-\\u02e4\\u02ec\\u02ee\\u0370-\\u0374\\u0376\\u0377\\u037a-\\u037d\\u037f\\u0386\\u0388-\\u038a\\u038c\\u038e-\\u03a1\\u03a3-\\u03f5\\u03f7-\\u0481\\u048a-\\u052f\\u0531-\\u0556\\u0559\\u0560-\\u0588\\u05d0-\\u05ea\\u05ef-\\u05f2\\u0620-\\u064a\\u066e\\u066f\\u0671-\\u06d3\\u06d5\\u06e5\\u06e6\\u06ee\\u06ef\\u06fa-\\u06fc\\u06ff\\u0710\\u0712-\\u072f\\u074d-\\u07a5\\u07b1\\u07ca-\\u07ea\\u07f4\\u07f5\\u07fa\\u0800-\\u0815\\u081a\\u0824\\u0828\\u0840-\\u0858\\u0860-\\u086a\\u08a0-\\u08b4\\u08b6-\\u08bd\\u0904-\\u0939\\u093d\\u0950\\u0958-\\u0961\\u0971-\\u0980\\u0985-\\u098c\\u098f\\u0990\\u0993-\\u09a8\\u09aa-\\u09b0\\u09b2\\u09b6-\\u09b9\\u09bd\\u09ce\\u09dc\\u09dd\\u09df-\\u09e1\\u09f0\\u09f1\\u09fc\\u0a05-\\u0a0a\\u0a0f\\u0a10\\u0a13-\\u0a28\\u0a2a-\\u0a30\\u0a32\\u0a33\\u0a35\\u0a36\\u0a38\\u0a39\\u0a59-\\u0a5c\\u0a5e\\u0a72-\\u0a74\\u0a85-\\u0a8d\\u0a8f-\\u0a91\\u0a93-\\u0aa8\\u0aaa-\\u0ab0\\u0ab2\\u0ab3\\u0ab5-\\u0ab9\\u0abd\\u0ad0\\u0ae0\\u0ae1\\u0af9\\u0b05-\\u0b0c\\u0b0f\\u0b10\\u0b13-\\u0b28\\u0b2a-\\u0b30\\u0b32\\u0b33\\u0b35-\\u0b39\\u0b3d\\u0b5c\\u0b5d\\u0b5f-\\u0b61\\u0b71\\u0b83\\u0b85-\\u0b8a\\u0b8e-\\u0b90\\u0b92-\\u0b95\\u0b99\\u0b9a\\u0b9c\\u0b9e\\u0b9f\\u0ba3\\u0ba4\\u0ba8-\\u0baa\\u0bae-\\u0bb9\\u0bd0\\u0c05-\\u0c0c\\u0c0e-\\u0c10\\u0c12-\\u0c28\\u0c2a-\\u0c39\\u0c3d\\u0c58-\\u0c5a\\u0c60\\u0c61\\u0c80\\u0c85-\\u0c8c\\u0c8e-\\u0c90\\u0c92-\\u0ca8\\u0caa-\\u0cb3\\u0cb5-\\u0cb9\\u0cbd\\u0cde\\u0ce0\\u0ce1\\u0cf1\\u0cf2\\u0d05-\\u0d0c\\u0d0e-\\u0d10\\u0d12-\\u0d3a\\u0d3d\\u0d4e\\u0d54-\\u0d56\\u0d5f-\\u0d61\\u0d7a-\\u0d7f\\u0d85-\\u0d96\\u0d9a-\\u0db1\\u0db3-\\u0dbb\\u0dbd\\u0dc0-\\u0dc6\\u0e01-\\u0e30\\u0e32\\u0e33\\u0e40-\\u0e46\\u0e81\\u0e82\\u0e84\\u0e87\\u0e88\\u0e8a\\u0e8d\\u0e94-\\u0e97\\u0e99-\\u0e9f\\u0ea1-\\u0ea3\\u0ea5\\u0ea7\\u0eaa\\u0eab\\u0ead-\\u0eb0\\u0eb2\\u0eb3\\u0ebd\\u0ec0-\\u0ec4\\u0ec6\\u0edc-\\u0edf\\u0f00\\u0f40-\\u0f47\\u0f49-\\u0f6c\\u0f88-\\u0f8c\\u1000-\\u102a\\u103f\\u1050-\\u1055\\u105a-\\u105d\\u1061\\u1065\\u1066\\u106e-\\u1070\\u1075-\\u1081\\u108e\\u10a0-\\u10c5\\u10c7\\u10cd\\u10d0-\\u10fa\\u10fc-\\u1248\\u124a-\\u124d\\u1250-\\u1256\\u1258\\u125a-\\u125d\\u1260-\\u1288\\u128a-\\u128d\\u1290-\\u12b0\\u12b2-\\u12b5\\u12b8-\\u12be\\u12c0\\u12c2-\\u12c5\\u12c8-\\u12d6\\u12d8-\\u1310\\u1312-\\u1315\\u1318-\\u135a\\u1380-\\u138f\\u13a0-\\u13f5\\u13f8-\\u13fd\\u1401-\\u166c\\u166f-\\u167f\\u1681-\\u169a\\u16a0-\\u16ea\\u16ee-\\u16f8\\u1700-\\u170c\\u170e-\\u1711\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176c\\u176e-\\u1770\\u1780-\\u17b3\\u17d7\\u17dc\\u1820-\\u1878\\u1880-\\u18a8\\u18aa\\u18b0-\\u18f5\\u1900-\\u191e\\u1950-\\u196d\\u1970-\\u1974\\u1980-\\u19ab\\u19b0-\\u19c9\\u1a00-\\u1a16\\u1a20-\\u1a54\\u1aa7\\u1b05-\\u1b33\\u1b45-\\u1b4b\\u1b83-\\u1ba0\\u1bae\\u1baf\\u1bba-\\u1be5\\u1c00-\\u1c23\\u1c4d-\\u1c4f\\u1c5a-\\u1c7d\\u1c80-\\u1c88\\u1c90-\\u1cba\\u1cbd-\\u1cbf\\u1ce9-\\u1cec\\u1cee-\\u1cf1\\u1cf5\\u1cf6\\u1d00-\\u1dbf\\u1e00-\\u1f15\\u1f18-\\u1f1d\\u1f20-\\u1f45\\u1f48-\\u1f4d\\u1f50-\\u1f57\\u1f59\\u1f5b\\u1f5d\\u1f5f-\\u1f7d\\u1f80-\\u1fb4\\u1fb6-\\u1fbc\\u1fbe\\u1fc2-\\u1fc4\\u1fc6-\\u1fcc\\u1fd0-\\u1fd3\\u1fd6-\\u1fdb\\u1fe0-\\u1fec\\u1ff2-\\u1ff4\\u1ff6-\\u1ffc\\u2071\\u207f\\u2090-\\u209c\\u2102\\u2107\\u210a-\\u2113\\u2115\\u2118-\\u211d\\u2124\\u2126\\u2128\\u212a-\\u2139\\u213c-\\u213f\\u2145-\\u2149\\u214e\\u2160-\\u2188\\u2c00-\\u2c2e\\u2c30-\\u2c5e\\u2c60-\\u2ce4\\u2ceb-\\u2cee\\u2cf2\\u2cf3\\u2d00-\\u2d25\\u2d27\\u2d2d\\u2d30-\\u2d67\\u2d6f\\u2d80-\\u2d96\\u2da0-\\u2da6\\u2da8-\\u2dae\\u2db0-\\u2db6\\u2db8-\\u2dbe\\u2dc0-\\u2dc6\\u2dc8-\\u2dce\\u2dd0-\\u2dd6\\u2dd8-\\u2dde\\u3005-\\u3007\\u3021-\\u3029\\u3031-\\u3035\\u3038-\\u303c\\u3041-\\u3096\\u309b-\\u309f\\u30a1-\\u30fa\\u30fc-\\u30ff\\u3105-\\u312f\\u3131-\\u318e\\u31a0-\\u31ba\\u31f0-\\u31ff\\u3400-\\u4db5\\u4e00-\\u9fef\\ua000-\\ua48c\\ua4d0-\\ua4fd\\ua500-\\ua60c\\ua610-\\ua61f\\ua62a\\ua62b\\ua640-\\ua66e\\ua67f-\\ua69d\\ua6a0-\\ua6ef\\ua717-\\ua71f\\ua722-\\ua788\\ua78b-\\ua7b9\\ua7f7-\\ua801\\ua803-\\ua805\\ua807-\\ua80a\\ua80c-\\ua822\\ua840-\\ua873\\ua882-\\ua8b3\\ua8f2-\\ua8f7\\ua8fb\\ua8fd\\ua8fe\\ua90a-\\ua925\\ua930-\\ua946\\ua960-\\ua97c\\ua984-\\ua9b2\\ua9cf\\ua9e0-\\ua9e4\\ua9e6-\\ua9ef\\ua9fa-\\ua9fe\\uaa00-\\uaa28\\uaa40-\\uaa42\\uaa44-\\uaa4b\\uaa60-\\uaa76\\uaa7a\\uaa7e-\\uaaaf\\uaab1\\uaab5\\uaab6\\uaab9-\\uaabd\\uaac0\\uaac2\\uaadb-\\uaadd\\uaae0-\\uaaea\\uaaf2-\\uaaf4\\uab01-\\uab06\\uab09-\\uab0e\\uab11-\\uab16\\uab20-\\uab26\\uab28-\\uab2e\\uab30-\\uab5a\\uab5c-\\uab65\\uab70-\\uabe2\\uac00-\\ud7a3\\ud7b0-\\ud7c6\\ud7cb-\\ud7fb\\uf900-\\ufa6d\\ufa70-\\ufad9\\ufb00-\\ufb06\\ufb13-\\ufb17\\ufb1d\\ufb1f-\\ufb28\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40\\ufb41\\ufb43\\ufb44\\ufb46-\\ufbb1\\ufbd3-\\ufd3d\\ufd50-\\ufd8f\\ufd92-\\ufdc7\\ufdf0-\\ufdfb\\ufe70-\\ufe74\\ufe76-\\ufefc\\uff21-\\uff3a\\uff41-\\uff5a\\uff66-\\uffbe\\uffc2-\\uffc7\\uffca-\\uffcf\\uffd2-\\uffd7\\uffda-\\uffdc\";\nvar nonASCIIidentifierChars = \"\\u200c\\u200d\\xb7\\u0300-\\u036f\\u0387\\u0483-\\u0487\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u064b-\\u0669\\u0670\\u06d6-\\u06dc\\u06df-\\u06e4\\u06e7\\u06e8\\u06ea-\\u06ed\\u06f0-\\u06f9\\u0711\\u0730-\\u074a\\u07a6-\\u07b0\\u07c0-\\u07c9\\u07eb-\\u07f3\\u07fd\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0859-\\u085b\\u08d3-\\u08e1\\u08e3-\\u0903\\u093a-\\u093c\\u093e-\\u094f\\u0951-\\u0957\\u0962\\u0963\\u0966-\\u096f\\u0981-\\u0983\\u09bc\\u09be-\\u09c4\\u09c7\\u09c8\\u09cb-\\u09cd\\u09d7\\u09e2\\u09e3\\u09e6-\\u09ef\\u09fe\\u0a01-\\u0a03\\u0a3c\\u0a3e-\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a66-\\u0a71\\u0a75\\u0a81-\\u0a83\\u0abc\\u0abe-\\u0ac5\\u0ac7-\\u0ac9\\u0acb-\\u0acd\\u0ae2\\u0ae3\\u0ae6-\\u0aef\\u0afa-\\u0aff\\u0b01-\\u0b03\\u0b3c\\u0b3e-\\u0b44\\u0b47\\u0b48\\u0b4b-\\u0b4d\\u0b56\\u0b57\\u0b62\\u0b63\\u0b66-\\u0b6f\\u0b82\\u0bbe-\\u0bc2\\u0bc6-\\u0bc8\\u0bca-\\u0bcd\\u0bd7\\u0be6-\\u0bef\\u0c00-\\u0c04\\u0c3e-\\u0c44\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62\\u0c63\\u0c66-\\u0c6f\\u0c81-\\u0c83\\u0cbc\\u0cbe-\\u0cc4\\u0cc6-\\u0cc8\\u0cca-\\u0ccd\\u0cd5\\u0cd6\\u0ce2\\u0ce3\\u0ce6-\\u0cef\\u0d00-\\u0d03\\u0d3b\\u0d3c\\u0d3e-\\u0d44\\u0d46-\\u0d48\\u0d4a-\\u0d4d\\u0d57\\u0d62\\u0d63\\u0d66-\\u0d6f\\u0d82\\u0d83\\u0dca\\u0dcf-\\u0dd4\\u0dd6\\u0dd8-\\u0ddf\\u0de6-\\u0def\\u0df2\\u0df3\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0e50-\\u0e59\\u0eb1\\u0eb4-\\u0eb9\\u0ebb\\u0ebc\\u0ec8-\\u0ecd\\u0ed0-\\u0ed9\\u0f18\\u0f19\\u0f20-\\u0f29\\u0f35\\u0f37\\u0f39\\u0f3e\\u0f3f\\u0f71-\\u0f84\\u0f86\\u0f87\\u0f8d-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u102b-\\u103e\\u1040-\\u1049\\u1056-\\u1059\\u105e-\\u1060\\u1062-\\u1064\\u1067-\\u106d\\u1071-\\u1074\\u1082-\\u108d\\u108f-\\u109d\\u135d-\\u135f\\u1369-\\u1371\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17b4-\\u17d3\\u17dd\\u17e0-\\u17e9\\u180b-\\u180d\\u1810-\\u1819\\u18a9\\u1920-\\u192b\\u1930-\\u193b\\u1946-\\u194f\\u19d0-\\u19da\\u1a17-\\u1a1b\\u1a55-\\u1a5e\\u1a60-\\u1a7c\\u1a7f-\\u1a89\\u1a90-\\u1a99\\u1ab0-\\u1abd\\u1b00-\\u1b04\\u1b34-\\u1b44\\u1b50-\\u1b59\\u1b6b-\\u1b73\\u1b80-\\u1b82\\u1ba1-\\u1bad\\u1bb0-\\u1bb9\\u1be6-\\u1bf3\\u1c24-\\u1c37\\u1c40-\\u1c49\\u1c50-\\u1c59\\u1cd0-\\u1cd2\\u1cd4-\\u1ce8\\u1ced\\u1cf2-\\u1cf4\\u1cf7-\\u1cf9\\u1dc0-\\u1df9\\u1dfb-\\u1dff\\u203f\\u2040\\u2054\\u20d0-\\u20dc\\u20e1\\u20e5-\\u20f0\\u2cef-\\u2cf1\\u2d7f\\u2de0-\\u2dff\\u302a-\\u302f\\u3099\\u309a\\ua620-\\ua629\\ua66f\\ua674-\\ua67d\\ua69e\\ua69f\\ua6f0\\ua6f1\\ua802\\ua806\\ua80b\\ua823-\\ua827\\ua880\\ua881\\ua8b4-\\ua8c5\\ua8d0-\\ua8d9\\ua8e0-\\ua8f1\\ua8ff-\\ua909\\ua926-\\ua92d\\ua947-\\ua953\\ua980-\\ua983\\ua9b3-\\ua9c0\\ua9d0-\\ua9d9\\ua9e5\\ua9f0-\\ua9f9\\uaa29-\\uaa36\\uaa43\\uaa4c\\uaa4d\\uaa50-\\uaa59\\uaa7b-\\uaa7d\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uaaeb-\\uaaef\\uaaf5\\uaaf6\\uabe3-\\uabea\\uabec\\uabed\\uabf0-\\uabf9\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe2f\\ufe33\\ufe34\\ufe4d-\\ufe4f\\uff10-\\uff19\\uff3f\";\n\nvar nonASCIIidentifierStart = new RegExp(\"[\" + nonASCIIidentifierStartChars + \"]\");\nvar nonASCIIidentifier = new RegExp(\"[\" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + \"]\");\n\nnonASCIIidentifierStartChars = nonASCIIidentifierChars = null;\n\n// These are a run-length and offset encoded representation of the\n// >0xffff code points that are a valid part of identifiers. The\n// offset starts at 0x10000, and each pair of numbers represents an\n// offset to the next range, and then a size of the range. They were\n// generated by bin/generate-identifier-regex.js\n\n// eslint-disable-next-line comma-spacing\nvar astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,190,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,26,230,43,117,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,68,12,0,67,12,65,1,31,6129,15,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541];\n\n// eslint-disable-next-line comma-spacing\nvar astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239];\n\n// This has a complexity linear to the value of the code. The\n// assumption is that looking up astral identifier characters is\n// rare.\nfunction isInAstralSet(code, set) {\n var pos = 0x10000;\n for (var i = 0; i < set.length; i += 2) {\n pos += set[i];\n if (pos > code) { return false }\n pos += set[i + 1];\n if (pos >= code) { return true }\n }\n}\n\n// Test whether a given character code starts an identifier.\n\nfunction isIdentifierStart(code, astral) {\n if (code < 65) { return code === 36 }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes)\n}\n\n// Test whether a given character is part of an identifier.\n\nfunction isIdentifierChar(code, astral) {\n if (code < 48) { return code === 36 }\n if (code < 58) { return true }\n if (code < 65) { return false }\n if (code < 91) { return true }\n if (code < 97) { return code === 95 }\n if (code < 123) { return true }\n if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }\n if (astral === false) { return false }\n return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)\n}\n\n// ## Token types\n\n// The assignment of fine-grained, information-carrying type objects\n// allows the tokenizer to store the information it has about a\n// token in a way that is very cheap for the parser to look up.\n\n// All token type variables start with an underscore, to make them\n// easy to recognize.\n\n// The `beforeExpr` property is used to disambiguate between regular\n// expressions and divisions. It is set on all token types that can\n// be followed by an expression (thus, a slash after them would be a\n// regular expression).\n//\n// The `startsExpr` property is used to check if the token ends a\n// `yield` expression. It is set on all token types that either can\n// directly start an expression (like a quotation mark) or can\n// continue an expression (like the body of a string).\n//\n// `isLoop` marks a keyword as starting a loop, which is important\n// to know when parsing a label, in order to allow or disallow\n// continue jumps to that label.\n\nvar TokenType = function TokenType(label, conf) {\n if ( conf === void 0 ) conf = {};\n\n this.label = label;\n this.keyword = conf.keyword;\n this.beforeExpr = !!conf.beforeExpr;\n this.startsExpr = !!conf.startsExpr;\n this.isLoop = !!conf.isLoop;\n this.isAssign = !!conf.isAssign;\n this.prefix = !!conf.prefix;\n this.postfix = !!conf.postfix;\n this.binop = conf.binop || null;\n this.updateContext = null;\n};\n\nfunction binop(name, prec) {\n return new TokenType(name, {beforeExpr: true, binop: prec})\n}\nvar beforeExpr = {beforeExpr: true};\nvar startsExpr = {startsExpr: true};\n\n// Map keyword names to token types.\n\nvar keywords$1 = {};\n\n// Succinct definitions of keyword token types\nfunction kw(name, options) {\n if ( options === void 0 ) options = {};\n\n options.keyword = name;\n return keywords$1[name] = new TokenType(name, options)\n}\n\nvar types = {\n num: new TokenType(\"num\", startsExpr),\n regexp: new TokenType(\"regexp\", startsExpr),\n string: new TokenType(\"string\", startsExpr),\n name: new TokenType(\"name\", startsExpr),\n eof: new TokenType(\"eof\"),\n\n // Punctuation token types.\n bracketL: new TokenType(\"[\", {beforeExpr: true, startsExpr: true}),\n bracketR: new TokenType(\"]\"),\n braceL: new TokenType(\"{\", {beforeExpr: true, startsExpr: true}),\n braceR: new TokenType(\"}\"),\n parenL: new TokenType(\"(\", {beforeExpr: true, startsExpr: true}),\n parenR: new TokenType(\")\"),\n comma: new TokenType(\",\", beforeExpr),\n semi: new TokenType(\";\", beforeExpr),\n colon: new TokenType(\":\", beforeExpr),\n dot: new TokenType(\".\"),\n question: new TokenType(\"?\", beforeExpr),\n arrow: new TokenType(\"=>\", beforeExpr),\n template: new TokenType(\"template\"),\n invalidTemplate: new TokenType(\"invalidTemplate\"),\n ellipsis: new TokenType(\"...\", beforeExpr),\n backQuote: new TokenType(\"`\", startsExpr),\n dollarBraceL: new TokenType(\"${\", {beforeExpr: true, startsExpr: true}),\n\n // Operators. These carry several kinds of properties to help the\n // parser use them properly (the presence of these properties is\n // what categorizes them as operators).\n //\n // `binop`, when present, specifies that this operator is a binary\n // operator, and will refer to its precedence.\n //\n // `prefix` and `postfix` mark the operator as a prefix or postfix\n // unary operator.\n //\n // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as\n // binary operators with a very low precedence, that should result\n // in AssignmentExpression nodes.\n\n eq: new TokenType(\"=\", {beforeExpr: true, isAssign: true}),\n assign: new TokenType(\"_=\", {beforeExpr: true, isAssign: true}),\n incDec: new TokenType(\"++/--\", {prefix: true, postfix: true, startsExpr: true}),\n prefix: new TokenType(\"!/~\", {beforeExpr: true, prefix: true, startsExpr: true}),\n logicalOR: binop(\"||\", 1),\n logicalAND: binop(\"&&\", 2),\n bitwiseOR: binop(\"|\", 3),\n bitwiseXOR: binop(\"^\", 4),\n bitwiseAND: binop(\"&\", 5),\n equality: binop(\"==/!=/===/!==\", 6),\n relational: binop(\"/<=/>=\", 7),\n bitShift: binop(\"<>/>>>\", 8),\n plusMin: new TokenType(\"+/-\", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),\n modulo: binop(\"%\", 10),\n star: binop(\"*\", 10),\n slash: binop(\"/\", 10),\n starstar: new TokenType(\"**\", {beforeExpr: true}),\n\n // Keyword token types.\n _break: kw(\"break\"),\n _case: kw(\"case\", beforeExpr),\n _catch: kw(\"catch\"),\n _continue: kw(\"continue\"),\n _debugger: kw(\"debugger\"),\n _default: kw(\"default\", beforeExpr),\n _do: kw(\"do\", {isLoop: true, beforeExpr: true}),\n _else: kw(\"else\", beforeExpr),\n _finally: kw(\"finally\"),\n _for: kw(\"for\", {isLoop: true}),\n _function: kw(\"function\", startsExpr),\n _if: kw(\"if\"),\n _return: kw(\"return\", beforeExpr),\n _switch: kw(\"switch\"),\n _throw: kw(\"throw\", beforeExpr),\n _try: kw(\"try\"),\n _var: kw(\"var\"),\n _const: kw(\"const\"),\n _while: kw(\"while\", {isLoop: true}),\n _with: kw(\"with\"),\n _new: kw(\"new\", {beforeExpr: true, startsExpr: true}),\n _this: kw(\"this\", startsExpr),\n _super: kw(\"super\", startsExpr),\n _class: kw(\"class\", startsExpr),\n _extends: kw(\"extends\", beforeExpr),\n _export: kw(\"export\"),\n _import: kw(\"import\"),\n _null: kw(\"null\", startsExpr),\n _true: kw(\"true\", startsExpr),\n _false: kw(\"false\", startsExpr),\n _in: kw(\"in\", {beforeExpr: true, binop: 7}),\n _instanceof: kw(\"instanceof\", {beforeExpr: true, binop: 7}),\n _typeof: kw(\"typeof\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _void: kw(\"void\", {beforeExpr: true, prefix: true, startsExpr: true}),\n _delete: kw(\"delete\", {beforeExpr: true, prefix: true, startsExpr: true})\n};\n\n// Matches a whole line break (where CRLF is considered a single\n// line break). Used to count lines.\n\nvar lineBreak = /\\r\\n?|\\n|\\u2028|\\u2029/;\nvar lineBreakG = new RegExp(lineBreak.source, \"g\");\n\nfunction isNewLine(code, ecma2019String) {\n return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029))\n}\n\nvar nonASCIIwhitespace = /[\\u1680\\u180e\\u2000-\\u200a\\u202f\\u205f\\u3000\\ufeff]/;\n\nvar skipWhiteSpace = /(?:\\s|\\/\\/.*|\\/\\*[^]*?\\*\\/)*/g;\n\nvar ref = Object.prototype;\nvar hasOwnProperty = ref.hasOwnProperty;\nvar toString = ref.toString;\n\n// Checks if an object has a property.\n\nfunction has(obj, propName) {\n return hasOwnProperty.call(obj, propName)\n}\n\nvar isArray = Array.isArray || (function (obj) { return (\n toString.call(obj) === \"[object Array]\"\n); });\n\n// These are used when `options.locations` is on, for the\n// `startLoc` and `endLoc` properties.\n\nvar Position = function Position(line, col) {\n this.line = line;\n this.column = col;\n};\n\nPosition.prototype.offset = function offset (n) {\n return new Position(this.line, this.column + n)\n};\n\nvar SourceLocation = function SourceLocation(p, start, end) {\n this.start = start;\n this.end = end;\n if (p.sourceFile !== null) { this.source = p.sourceFile; }\n};\n\n// The `getLineInfo` function is mostly useful when the\n// `locations` option is off (for performance reasons) and you\n// want to find the line/column position for a given character\n// offset. `input` should be the code string that the offset refers\n// into.\n\nfunction getLineInfo(input, offset) {\n for (var line = 1, cur = 0;;) {\n lineBreakG.lastIndex = cur;\n var match = lineBreakG.exec(input);\n if (match && match.index < offset) {\n ++line;\n cur = match.index + match[0].length;\n } else {\n return new Position(line, offset - cur)\n }\n }\n}\n\n// A second optional argument can be given to further configure\n// the parser process. These options are recognized:\n\nvar defaultOptions = {\n // `ecmaVersion` indicates the ECMAScript version to parse. Must\n // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support\n // for strict mode, the set of reserved words, and support for\n // new syntax features. The default is 7.\n ecmaVersion: 7,\n // `sourceType` indicates the mode the code should be parsed in.\n // Can be either `\"script\"` or `\"module\"`. This influences global\n // strict mode and parsing of `import` and `export` declarations.\n sourceType: \"script\",\n // `onInsertedSemicolon` can be a callback that will be called\n // when a semicolon is automatically inserted. It will be passed\n // th position of the comma as an offset, and if `locations` is\n // enabled, it is given the location as a `{line, column}` object\n // as second argument.\n onInsertedSemicolon: null,\n // `onTrailingComma` is similar to `onInsertedSemicolon`, but for\n // trailing commas.\n onTrailingComma: null,\n // By default, reserved words are only enforced if ecmaVersion >= 5.\n // Set `allowReserved` to a boolean value to explicitly turn this on\n // an off. When this option has the value \"never\", reserved words\n // and keywords can also not be used as property names.\n allowReserved: null,\n // When enabled, a return at the top level is not considered an\n // error.\n allowReturnOutsideFunction: false,\n // When enabled, import/export statements are not constrained to\n // appearing at the top of the program.\n allowImportExportEverywhere: false,\n // When enabled, await identifiers are allowed to appear at the top-level scope,\n // but they are still not allowed in non-async functions.\n allowAwaitOutsideFunction: false,\n // When enabled, hashbang directive in the beginning of file\n // is allowed and treated as a line comment.\n allowHashBang: false,\n // When `locations` is on, `loc` properties holding objects with\n // `start` and `end` properties in `{line, column}` form (with\n // line being 1-based and column 0-based) will be attached to the\n // nodes.\n locations: false,\n // A function can be passed as `onToken` option, which will\n // cause Acorn to call that function with object in the same\n // format as tokens returned from `tokenizer().getToken()`. Note\n // that you are not allowed to call the parser from the\n // callback—that will corrupt its internal state.\n onToken: null,\n // A function can be passed as `onComment` option, which will\n // cause Acorn to call that function with `(block, text, start,\n // end)` parameters whenever a comment is skipped. `block` is a\n // boolean indicating whether this is a block (`/* */`) comment,\n // `text` is the content of the comment, and `start` and `end` are\n // character offsets that denote the start and end of the comment.\n // When the `locations` option is on, two more parameters are\n // passed, the full `{line, column}` locations of the start and\n // end of the comments. Note that you are not allowed to call the\n // parser from the callback—that will corrupt its internal state.\n onComment: null,\n // Nodes have their start and end characters offsets recorded in\n // `start` and `end` properties (directly on the node, rather than\n // the `loc` object, which holds line/column data. To also add a\n // [semi-standardized][range] `range` property holding a `[start,\n // end]` array with the same numbers, set the `ranges` option to\n // `true`.\n //\n // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678\n ranges: false,\n // It is possible to parse multiple files into a single AST by\n // passing the tree produced by parsing the first file as\n // `program` option in subsequent parses. This will add the\n // toplevel forms of the parsed file to the `Program` (top) node\n // of an existing parse tree.\n program: null,\n // When `locations` is on, you can pass this to record the source\n // file in every node's `loc` object.\n sourceFile: null,\n // This value, if given, is stored in every node, whether\n // `locations` is on or off.\n directSourceFile: null,\n // When enabled, parenthesized expressions are represented by\n // (non-standard) ParenthesizedExpression nodes\n preserveParens: false,\n plugins: {}\n};\n\n// Interpret and default an options object\n\nfunction getOptions(opts) {\n var options = {};\n\n for (var opt in defaultOptions)\n { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }\n\n if (options.ecmaVersion >= 2015)\n { options.ecmaVersion -= 2009; }\n\n if (options.allowReserved == null)\n { options.allowReserved = options.ecmaVersion < 5; }\n\n if (isArray(options.onToken)) {\n var tokens = options.onToken;\n options.onToken = function (token) { return tokens.push(token); };\n }\n if (isArray(options.onComment))\n { options.onComment = pushComment(options, options.onComment); }\n\n return options\n}\n\nfunction pushComment(options, array) {\n return function(block, text, start, end, startLoc, endLoc) {\n var comment = {\n type: block ? \"Block\" : \"Line\",\n value: text,\n start: start,\n end: end\n };\n if (options.locations)\n { comment.loc = new SourceLocation(this, startLoc, endLoc); }\n if (options.ranges)\n { comment.range = [start, end]; }\n array.push(comment);\n }\n}\n\n// Registered plugins\nvar plugins = {};\n\nfunction keywordRegexp(words) {\n return new RegExp(\"^(?:\" + words.replace(/ /g, \"|\") + \")$\")\n}\n\nvar Parser = function Parser(options, input, startPos) {\n this.options = options = getOptions(options);\n this.sourceFile = options.sourceFile;\n this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]);\n var reserved = \"\";\n if (!options.allowReserved) {\n for (var v = options.ecmaVersion;; v--)\n { if (reserved = reservedWords[v]) { break } }\n if (options.sourceType === \"module\") { reserved += \" await\"; }\n }\n this.reservedWords = keywordRegexp(reserved);\n var reservedStrict = (reserved ? reserved + \" \" : \"\") + reservedWords.strict;\n this.reservedWordsStrict = keywordRegexp(reservedStrict);\n this.reservedWordsStrictBind = keywordRegexp(reservedStrict + \" \" + reservedWords.strictBind);\n this.input = String(input);\n\n // Used to signal to callers of `readWord1` whether the word\n // contained any escape sequences. This is needed because words with\n // escape sequences must not be interpreted as keywords.\n this.containsEsc = false;\n\n // Load plugins\n this.loadPlugins(options.plugins);\n\n // Set up token state\n\n // The current position of the tokenizer in the input.\n if (startPos) {\n this.pos = startPos;\n this.lineStart = this.input.lastIndexOf(\"\\n\", startPos - 1) + 1;\n this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;\n } else {\n this.pos = this.lineStart = 0;\n this.curLine = 1;\n }\n\n // Properties of the current token:\n // Its type\n this.type = types.eof;\n // For tokens that include more information than their type, the value\n this.value = null;\n // Its start and end offset\n this.start = this.end = this.pos;\n // And, if locations are used, the {line, column} object\n // corresponding to those offsets\n this.startLoc = this.endLoc = this.curPosition();\n\n // Position information for the previous token\n this.lastTokEndLoc = this.lastTokStartLoc = null;\n this.lastTokStart = this.lastTokEnd = this.pos;\n\n // The context stack is used to superficially track syntactic\n // context to predict whether a regular expression is allowed in a\n // given position.\n this.context = this.initialContext();\n this.exprAllowed = true;\n\n // Figure out if it's a module code.\n this.inModule = options.sourceType === \"module\";\n this.strict = this.inModule || this.strictDirective(this.pos);\n\n // Used to signify the start of a potential arrow function\n this.potentialArrowAt = -1;\n\n // Flags to track whether we are in a function, a generator, an async function.\n this.inFunction = this.inGenerator = this.inAsync = false;\n // Positions to delayed-check that yield/await does not exist in default parameters.\n this.yieldPos = this.awaitPos = 0;\n // Labels in scope.\n this.labels = [];\n\n // If enabled, skip leading hashbang line.\n if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === \"#!\")\n { this.skipLineComment(2); }\n\n // Scope tracking for duplicate variable names (see scope.js)\n this.scopeStack = [];\n this.enterFunctionScope();\n\n // For RegExp validation\n this.regexpState = null;\n};\n\n// DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them\nParser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) };\nParser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) };\n\nParser.prototype.extend = function extend (name, f) {\n this[name] = f(this[name]);\n};\n\nParser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {\n var this$1 = this;\n\n for (var name in pluginConfigs) {\n var plugin = plugins[name];\n if (!plugin) { throw new Error(\"Plugin '\" + name + \"' not found\") }\n plugin(this$1, pluginConfigs[name]);\n }\n};\n\nParser.prototype.parse = function parse () {\n var node = this.options.program || this.startNode();\n this.nextToken();\n return this.parseTopLevel(node)\n};\n\nvar pp = Parser.prototype;\n\n// ## Parser utilities\n\nvar literal = /^(?:'((?:\\\\.|[^'])*?)'|\"((?:\\\\.|[^\"])*?)\"|;)/;\npp.strictDirective = function(start) {\n var this$1 = this;\n\n for (;;) {\n skipWhiteSpace.lastIndex = start;\n start += skipWhiteSpace.exec(this$1.input)[0].length;\n var match = literal.exec(this$1.input.slice(start));\n if (!match) { return false }\n if ((match[1] || match[2]) === \"use strict\") { return true }\n start += match[0].length;\n }\n};\n\n// Predicate that tests whether the next token is of the given\n// type, and if yes, consumes it as a side effect.\n\npp.eat = function(type) {\n if (this.type === type) {\n this.next();\n return true\n } else {\n return false\n }\n};\n\n// Tests whether parsed token is a contextual keyword.\n\npp.isContextual = function(name) {\n return this.type === types.name && this.value === name && !this.containsEsc\n};\n\n// Consumes contextual keyword if possible.\n\npp.eatContextual = function(name) {\n if (!this.isContextual(name)) { return false }\n this.next();\n return true\n};\n\n// Asserts that following token is given contextual keyword.\n\npp.expectContextual = function(name) {\n if (!this.eatContextual(name)) { this.unexpected(); }\n};\n\n// Test whether a semicolon can be inserted at the current position.\n\npp.canInsertSemicolon = function() {\n return this.type === types.eof ||\n this.type === types.braceR ||\n lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\npp.insertSemicolon = function() {\n if (this.canInsertSemicolon()) {\n if (this.options.onInsertedSemicolon)\n { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }\n return true\n }\n};\n\n// Consume a semicolon, or, failing that, see if we are allowed to\n// pretend that there is a semicolon at this position.\n\npp.semicolon = function() {\n if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }\n};\n\npp.afterTrailingComma = function(tokType, notNext) {\n if (this.type === tokType) {\n if (this.options.onTrailingComma)\n { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }\n if (!notNext)\n { this.next(); }\n return true\n }\n};\n\n// Expect a token of a given type. If found, consume it, otherwise,\n// raise an unexpected token error.\n\npp.expect = function(type) {\n this.eat(type) || this.unexpected();\n};\n\n// Raise an unexpected token error.\n\npp.unexpected = function(pos) {\n this.raise(pos != null ? pos : this.start, \"Unexpected token\");\n};\n\nfunction DestructuringErrors() {\n this.shorthandAssign =\n this.trailingComma =\n this.parenthesizedAssign =\n this.parenthesizedBind =\n this.doubleProto =\n -1;\n}\n\npp.checkPatternErrors = function(refDestructuringErrors, isAssign) {\n if (!refDestructuringErrors) { return }\n if (refDestructuringErrors.trailingComma > -1)\n { this.raiseRecoverable(refDestructuringErrors.trailingComma, \"Comma is not permitted after the rest element\"); }\n var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;\n if (parens > -1) { this.raiseRecoverable(parens, \"Parenthesized pattern\"); }\n};\n\npp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {\n if (!refDestructuringErrors) { return false }\n var shorthandAssign = refDestructuringErrors.shorthandAssign;\n var doubleProto = refDestructuringErrors.doubleProto;\n if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }\n if (shorthandAssign >= 0)\n { this.raise(shorthandAssign, \"Shorthand property assignments are valid only in destructuring patterns\"); }\n if (doubleProto >= 0)\n { this.raiseRecoverable(doubleProto, \"Redefinition of __proto__ property\"); }\n};\n\npp.checkYieldAwaitInDefaultParams = function() {\n if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))\n { this.raise(this.yieldPos, \"Yield expression cannot be a default value\"); }\n if (this.awaitPos)\n { this.raise(this.awaitPos, \"Await expression cannot be a default value\"); }\n};\n\npp.isSimpleAssignTarget = function(expr) {\n if (expr.type === \"ParenthesizedExpression\")\n { return this.isSimpleAssignTarget(expr.expression) }\n return expr.type === \"Identifier\" || expr.type === \"MemberExpression\"\n};\n\nvar pp$1 = Parser.prototype;\n\n// ### Statement parsing\n\n// Parse a program. Initializes the parser, reads any number of\n// statements, and wraps them in a Program node. Optionally takes a\n// `program` argument. If present, the statements will be appended\n// to its body instead of creating a new node.\n\npp$1.parseTopLevel = function(node) {\n var this$1 = this;\n\n var exports = {};\n if (!node.body) { node.body = []; }\n while (this.type !== types.eof) {\n var stmt = this$1.parseStatement(true, true, exports);\n node.body.push(stmt);\n }\n this.adaptDirectivePrologue(node.body);\n this.next();\n if (this.options.ecmaVersion >= 6) {\n node.sourceType = this.options.sourceType;\n }\n return this.finishNode(node, \"Program\")\n};\n\nvar loopLabel = {kind: \"loop\"};\nvar switchLabel = {kind: \"switch\"};\n\npp$1.isLet = function() {\n if (this.options.ecmaVersion < 6 || !this.isContextual(\"let\")) { return false }\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);\n if (nextCh === 91 || nextCh === 123) { return true } // '{' and '['\n if (isIdentifierStart(nextCh, true)) {\n var pos = next + 1;\n while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }\n var ident = this.input.slice(next, pos);\n if (!keywordRelationalOperator.test(ident)) { return true }\n }\n return false\n};\n\n// check 'async [no LineTerminator here] function'\n// - 'async /*foo*/ function' is OK.\n// - 'async /*\\n*/ function' is invalid.\npp$1.isAsyncFunction = function() {\n if (this.options.ecmaVersion < 8 || !this.isContextual(\"async\"))\n { return false }\n\n skipWhiteSpace.lastIndex = this.pos;\n var skip = skipWhiteSpace.exec(this.input);\n var next = this.pos + skip[0].length;\n return !lineBreak.test(this.input.slice(this.pos, next)) &&\n this.input.slice(next, next + 8) === \"function\" &&\n (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))\n};\n\n// Parse a single statement.\n//\n// If expecting a statement and finding a slash operator, parse a\n// regular expression literal. This is to handle cases like\n// `if (foo) /blah/.exec(foo)`, where looking at the previous token\n// does not help.\n\npp$1.parseStatement = function(declaration, topLevel, exports) {\n var starttype = this.type, node = this.startNode(), kind;\n\n if (this.isLet()) {\n starttype = types._var;\n kind = \"let\";\n }\n\n // Most types of statements are recognized by the keyword they\n // start with. Many are trivial to parse, some require a bit of\n // complexity.\n\n switch (starttype) {\n case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)\n case types._debugger: return this.parseDebuggerStatement(node)\n case types._do: return this.parseDoStatement(node)\n case types._for: return this.parseForStatement(node)\n case types._function:\n if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); }\n return this.parseFunctionStatement(node, false)\n case types._class:\n if (!declaration) { this.unexpected(); }\n return this.parseClass(node, true)\n case types._if: return this.parseIfStatement(node)\n case types._return: return this.parseReturnStatement(node)\n case types._switch: return this.parseSwitchStatement(node)\n case types._throw: return this.parseThrowStatement(node)\n case types._try: return this.parseTryStatement(node)\n case types._const: case types._var:\n kind = kind || this.value;\n if (!declaration && kind !== \"var\") { this.unexpected(); }\n return this.parseVarStatement(node, kind)\n case types._while: return this.parseWhileStatement(node)\n case types._with: return this.parseWithStatement(node)\n case types.braceL: return this.parseBlock()\n case types.semi: return this.parseEmptyStatement(node)\n case types._export:\n case types._import:\n if (!this.options.allowImportExportEverywhere) {\n if (!topLevel)\n { this.raise(this.start, \"'import' and 'export' may only appear at the top level\"); }\n if (!this.inModule)\n { this.raise(this.start, \"'import' and 'export' may appear only with 'sourceType: module'\"); }\n }\n return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)\n\n // If the statement does not start with a statement keyword or a\n // brace, it's an ExpressionStatement or LabeledStatement. We\n // simply start parsing an expression, and afterwards, if the\n // next token is a colon and the expression was a simple\n // Identifier node, we switch to interpreting it as a label.\n default:\n if (this.isAsyncFunction()) {\n if (!declaration) { this.unexpected(); }\n this.next();\n return this.parseFunctionStatement(node, true)\n }\n\n var maybeName = this.value, expr = this.parseExpression();\n if (starttype === types.name && expr.type === \"Identifier\" && this.eat(types.colon))\n { return this.parseLabeledStatement(node, maybeName, expr) }\n else { return this.parseExpressionStatement(node, expr) }\n }\n};\n\npp$1.parseBreakContinueStatement = function(node, keyword) {\n var this$1 = this;\n\n var isBreak = keyword === \"break\";\n this.next();\n if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }\n else if (this.type !== types.name) { this.unexpected(); }\n else {\n node.label = this.parseIdent();\n this.semicolon();\n }\n\n // Verify that there is an actual destination to break or\n // continue to.\n var i = 0;\n for (; i < this.labels.length; ++i) {\n var lab = this$1.labels[i];\n if (node.label == null || lab.name === node.label.name) {\n if (lab.kind != null && (isBreak || lab.kind === \"loop\")) { break }\n if (node.label && isBreak) { break }\n }\n }\n if (i === this.labels.length) { this.raise(node.start, \"Unsyntactic \" + keyword); }\n return this.finishNode(node, isBreak ? \"BreakStatement\" : \"ContinueStatement\")\n};\n\npp$1.parseDebuggerStatement = function(node) {\n this.next();\n this.semicolon();\n return this.finishNode(node, \"DebuggerStatement\")\n};\n\npp$1.parseDoStatement = function(node) {\n this.next();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(false);\n this.labels.pop();\n this.expect(types._while);\n node.test = this.parseParenExpression();\n if (this.options.ecmaVersion >= 6)\n { this.eat(types.semi); }\n else\n { this.semicolon(); }\n return this.finishNode(node, \"DoWhileStatement\")\n};\n\n// Disambiguating between a `for` and a `for`/`in` or `for`/`of`\n// loop is non-trivial. Basically, we have to parse the init `var`\n// statement or expression, disallowing the `in` operator (see\n// the second parameter to `parseExpression`), and then check\n// whether the next token is `in` or `of`. When there is no init\n// part (semicolon immediately after the opening parenthesis), it\n// is a regular `for` loop.\n\npp$1.parseForStatement = function(node) {\n this.next();\n var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual(\"await\")) ? this.lastTokStart : -1;\n this.labels.push(loopLabel);\n this.enterLexicalScope();\n this.expect(types.parenL);\n if (this.type === types.semi) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, null)\n }\n var isLet = this.isLet();\n if (this.type === types._var || this.type === types._const || isLet) {\n var init$1 = this.startNode(), kind = isLet ? \"let\" : this.value;\n this.next();\n this.parseVar(init$1, true, kind);\n this.finishNode(init$1, \"VariableDeclaration\");\n if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) && init$1.declarations.length === 1 &&\n !(kind !== \"var\" && init$1.declarations[0].init)) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n return this.parseForIn(node, init$1)\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init$1)\n }\n var refDestructuringErrors = new DestructuringErrors;\n var init = this.parseExpression(true, refDestructuringErrors);\n if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual(\"of\"))) {\n if (this.options.ecmaVersion >= 9) {\n if (this.type === types._in) {\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n } else { node.await = awaitAt > -1; }\n }\n this.toAssignable(init, false, refDestructuringErrors);\n this.checkLVal(init);\n return this.parseForIn(node, init)\n } else {\n this.checkExpressionErrors(refDestructuringErrors, true);\n }\n if (awaitAt > -1) { this.unexpected(awaitAt); }\n return this.parseFor(node, init)\n};\n\npp$1.parseFunctionStatement = function(node, isAsync) {\n this.next();\n return this.parseFunction(node, true, false, isAsync)\n};\n\npp$1.parseIfStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n // allow function declarations in branches, but only in non-strict mode\n node.consequent = this.parseStatement(!this.strict && this.type === types._function);\n node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : null;\n return this.finishNode(node, \"IfStatement\")\n};\n\npp$1.parseReturnStatement = function(node) {\n if (!this.inFunction && !this.options.allowReturnOutsideFunction)\n { this.raise(this.start, \"'return' outside of function\"); }\n this.next();\n\n // In `return` (and `break`/`continue`), the keywords with\n // optional arguments, we eagerly look for a semicolon or the\n // possibility to insert one.\n\n if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }\n else { node.argument = this.parseExpression(); this.semicolon(); }\n return this.finishNode(node, \"ReturnStatement\")\n};\n\npp$1.parseSwitchStatement = function(node) {\n var this$1 = this;\n\n this.next();\n node.discriminant = this.parseParenExpression();\n node.cases = [];\n this.expect(types.braceL);\n this.labels.push(switchLabel);\n this.enterLexicalScope();\n\n // Statements under must be grouped (by label) in SwitchCase\n // nodes. `cur` is used to keep the node that we are currently\n // adding statements to.\n\n var cur;\n for (var sawDefault = false; this.type !== types.braceR;) {\n if (this$1.type === types._case || this$1.type === types._default) {\n var isCase = this$1.type === types._case;\n if (cur) { this$1.finishNode(cur, \"SwitchCase\"); }\n node.cases.push(cur = this$1.startNode());\n cur.consequent = [];\n this$1.next();\n if (isCase) {\n cur.test = this$1.parseExpression();\n } else {\n if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, \"Multiple default clauses\"); }\n sawDefault = true;\n cur.test = null;\n }\n this$1.expect(types.colon);\n } else {\n if (!cur) { this$1.unexpected(); }\n cur.consequent.push(this$1.parseStatement(true));\n }\n }\n this.exitLexicalScope();\n if (cur) { this.finishNode(cur, \"SwitchCase\"); }\n this.next(); // Closing brace\n this.labels.pop();\n return this.finishNode(node, \"SwitchStatement\")\n};\n\npp$1.parseThrowStatement = function(node) {\n this.next();\n if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))\n { this.raise(this.lastTokEnd, \"Illegal newline after throw\"); }\n node.argument = this.parseExpression();\n this.semicolon();\n return this.finishNode(node, \"ThrowStatement\")\n};\n\n// Reused empty array added for node fields that are always empty.\n\nvar empty = [];\n\npp$1.parseTryStatement = function(node) {\n this.next();\n node.block = this.parseBlock();\n node.handler = null;\n if (this.type === types._catch) {\n var clause = this.startNode();\n this.next();\n if (this.eat(types.parenL)) {\n clause.param = this.parseBindingAtom();\n this.enterLexicalScope();\n this.checkLVal(clause.param, \"let\");\n this.expect(types.parenR);\n } else {\n if (this.options.ecmaVersion < 10) { this.unexpected(); }\n clause.param = null;\n this.enterLexicalScope();\n }\n clause.body = this.parseBlock(false);\n this.exitLexicalScope();\n node.handler = this.finishNode(clause, \"CatchClause\");\n }\n node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;\n if (!node.handler && !node.finalizer)\n { this.raise(node.start, \"Missing catch or finally clause\"); }\n return this.finishNode(node, \"TryStatement\")\n};\n\npp$1.parseVarStatement = function(node, kind) {\n this.next();\n this.parseVar(node, false, kind);\n this.semicolon();\n return this.finishNode(node, \"VariableDeclaration\")\n};\n\npp$1.parseWhileStatement = function(node) {\n this.next();\n node.test = this.parseParenExpression();\n this.labels.push(loopLabel);\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, \"WhileStatement\")\n};\n\npp$1.parseWithStatement = function(node) {\n if (this.strict) { this.raise(this.start, \"'with' in strict mode\"); }\n this.next();\n node.object = this.parseParenExpression();\n node.body = this.parseStatement(false);\n return this.finishNode(node, \"WithStatement\")\n};\n\npp$1.parseEmptyStatement = function(node) {\n this.next();\n return this.finishNode(node, \"EmptyStatement\")\n};\n\npp$1.parseLabeledStatement = function(node, maybeName, expr) {\n var this$1 = this;\n\n for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1)\n {\n var label = list[i$1];\n\n if (label.name === maybeName)\n { this$1.raise(expr.start, \"Label '\" + maybeName + \"' is already declared\");\n } }\n var kind = this.type.isLoop ? \"loop\" : this.type === types._switch ? \"switch\" : null;\n for (var i = this.labels.length - 1; i >= 0; i--) {\n var label$1 = this$1.labels[i];\n if (label$1.statementStart === node.start) {\n // Update information about previous labels on this node\n label$1.statementStart = this$1.start;\n label$1.kind = kind;\n } else { break }\n }\n this.labels.push({name: maybeName, kind: kind, statementStart: this.start});\n node.body = this.parseStatement(true);\n if (node.body.type === \"ClassDeclaration\" ||\n node.body.type === \"VariableDeclaration\" && node.body.kind !== \"var\" ||\n node.body.type === \"FunctionDeclaration\" && (this.strict || node.body.generator || node.body.async))\n { this.raiseRecoverable(node.body.start, \"Invalid labeled declaration\"); }\n this.labels.pop();\n node.label = expr;\n return this.finishNode(node, \"LabeledStatement\")\n};\n\npp$1.parseExpressionStatement = function(node, expr) {\n node.expression = expr;\n this.semicolon();\n return this.finishNode(node, \"ExpressionStatement\")\n};\n\n// Parse a semicolon-enclosed block of statements, handling `\"use\n// strict\"` declarations when `allowStrict` is true (used for\n// function bodies).\n\npp$1.parseBlock = function(createNewLexicalScope) {\n var this$1 = this;\n if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;\n\n var node = this.startNode();\n node.body = [];\n this.expect(types.braceL);\n if (createNewLexicalScope) {\n this.enterLexicalScope();\n }\n while (!this.eat(types.braceR)) {\n var stmt = this$1.parseStatement(true);\n node.body.push(stmt);\n }\n if (createNewLexicalScope) {\n this.exitLexicalScope();\n }\n return this.finishNode(node, \"BlockStatement\")\n};\n\n// Parse a regular `for` loop. The disambiguation code in\n// `parseStatement` will already have parsed the init statement or\n// expression.\n\npp$1.parseFor = function(node, init) {\n node.init = init;\n this.expect(types.semi);\n node.test = this.type === types.semi ? null : this.parseExpression();\n this.expect(types.semi);\n node.update = this.type === types.parenR ? null : this.parseExpression();\n this.expect(types.parenR);\n this.exitLexicalScope();\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, \"ForStatement\")\n};\n\n// Parse a `for`/`in` and `for`/`of` loop, which are almost\n// same from parser's perspective.\n\npp$1.parseForIn = function(node, init) {\n var type = this.type === types._in ? \"ForInStatement\" : \"ForOfStatement\";\n this.next();\n if (type === \"ForInStatement\") {\n if (init.type === \"AssignmentPattern\" ||\n (init.type === \"VariableDeclaration\" && init.declarations[0].init != null &&\n (this.strict || init.declarations[0].id.type !== \"Identifier\")))\n { this.raise(init.start, \"Invalid assignment in for-in loop head\"); }\n }\n node.left = init;\n node.right = type === \"ForInStatement\" ? this.parseExpression() : this.parseMaybeAssign();\n this.expect(types.parenR);\n this.exitLexicalScope();\n node.body = this.parseStatement(false);\n this.labels.pop();\n return this.finishNode(node, type)\n};\n\n// Parse a list of variable declarations.\n\npp$1.parseVar = function(node, isFor, kind) {\n var this$1 = this;\n\n node.declarations = [];\n node.kind = kind;\n for (;;) {\n var decl = this$1.startNode();\n this$1.parseVarId(decl, kind);\n if (this$1.eat(types.eq)) {\n decl.init = this$1.parseMaybeAssign(isFor);\n } else if (kind === \"const\" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual(\"of\")))) {\n this$1.unexpected();\n } else if (decl.id.type !== \"Identifier\" && !(isFor && (this$1.type === types._in || this$1.isContextual(\"of\")))) {\n this$1.raise(this$1.lastTokEnd, \"Complex binding patterns require an initialization value\");\n } else {\n decl.init = null;\n }\n node.declarations.push(this$1.finishNode(decl, \"VariableDeclarator\"));\n if (!this$1.eat(types.comma)) { break }\n }\n return node\n};\n\npp$1.parseVarId = function(decl, kind) {\n decl.id = this.parseBindingAtom(kind);\n this.checkLVal(decl.id, kind, false);\n};\n\n// Parse a function declaration or literal (depending on the\n// `isStatement` parameter).\n\npp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) {\n this.initFunction(node);\n if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync)\n { node.generator = this.eat(types.star); }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n if (isStatement) {\n node.id = isStatement === \"nullableID\" && this.type !== types.name ? null : this.parseIdent();\n if (node.id) {\n this.checkLVal(node.id, this.inModule && !this.inFunction ? \"let\" : \"var\");\n }\n }\n\n var oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n this.inGenerator = node.generator;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n this.enterFunctionScope();\n\n if (!isStatement)\n { node.id = this.type === types.name ? this.parseIdent() : null; }\n\n this.parseFunctionParams(node);\n this.parseFunctionBody(node, allowExpressionBody);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, isStatement ? \"FunctionDeclaration\" : \"FunctionExpression\")\n};\n\npp$1.parseFunctionParams = function(node) {\n this.expect(types.parenL);\n node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n};\n\n// Parse a class declaration or literal (depending on the\n// `isStatement` parameter).\n\npp$1.parseClass = function(node, isStatement) {\n var this$1 = this;\n\n this.next();\n\n this.parseClassId(node, isStatement);\n this.parseClassSuper(node);\n var classBody = this.startNode();\n var hadConstructor = false;\n classBody.body = [];\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n var member = this$1.parseClassMember(classBody);\n if (member && member.type === \"MethodDefinition\" && member.kind === \"constructor\") {\n if (hadConstructor) { this$1.raise(member.start, \"Duplicate constructor in the same class\"); }\n hadConstructor = true;\n }\n }\n node.body = this.finishNode(classBody, \"ClassBody\");\n return this.finishNode(node, isStatement ? \"ClassDeclaration\" : \"ClassExpression\")\n};\n\npp$1.parseClassMember = function(classBody) {\n var this$1 = this;\n\n if (this.eat(types.semi)) { return null }\n\n var method = this.startNode();\n var tryContextual = function (k, noLineBreak) {\n if ( noLineBreak === void 0 ) noLineBreak = false;\n\n var start = this$1.start, startLoc = this$1.startLoc;\n if (!this$1.eatContextual(k)) { return false }\n if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }\n if (method.key) { this$1.unexpected(); }\n method.computed = false;\n method.key = this$1.startNodeAt(start, startLoc);\n method.key.name = k;\n this$1.finishNode(method.key, \"Identifier\");\n return false\n };\n\n method.kind = \"method\";\n method.static = tryContextual(\"static\");\n var isGenerator = this.eat(types.star);\n var isAsync = false;\n if (!isGenerator) {\n if (this.options.ecmaVersion >= 8 && tryContextual(\"async\", true)) {\n isAsync = true;\n isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);\n } else if (tryContextual(\"get\")) {\n method.kind = \"get\";\n } else if (tryContextual(\"set\")) {\n method.kind = \"set\";\n }\n }\n if (!method.key) { this.parsePropertyName(method); }\n var key = method.key;\n if (!method.computed && !method.static && (key.type === \"Identifier\" && key.name === \"constructor\" ||\n key.type === \"Literal\" && key.value === \"constructor\")) {\n if (method.kind !== \"method\") { this.raise(key.start, \"Constructor can't have get/set modifier\"); }\n if (isGenerator) { this.raise(key.start, \"Constructor can't be a generator\"); }\n if (isAsync) { this.raise(key.start, \"Constructor can't be an async method\"); }\n method.kind = \"constructor\";\n } else if (method.static && key.type === \"Identifier\" && key.name === \"prototype\") {\n this.raise(key.start, \"Classes may not have a static property named prototype\");\n }\n this.parseClassMethod(classBody, method, isGenerator, isAsync);\n if (method.kind === \"get\" && method.value.params.length !== 0)\n { this.raiseRecoverable(method.value.start, \"getter should have no params\"); }\n if (method.kind === \"set\" && method.value.params.length !== 1)\n { this.raiseRecoverable(method.value.start, \"setter should have exactly one param\"); }\n if (method.kind === \"set\" && method.value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(method.value.params[0].start, \"Setter cannot use rest params\"); }\n return method\n};\n\npp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) {\n method.value = this.parseMethod(isGenerator, isAsync);\n classBody.body.push(this.finishNode(method, \"MethodDefinition\"));\n};\n\npp$1.parseClassId = function(node, isStatement) {\n node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null;\n};\n\npp$1.parseClassSuper = function(node) {\n node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;\n};\n\n// Parses module export declaration.\n\npp$1.parseExport = function(node, exports) {\n var this$1 = this;\n\n this.next();\n // export * from '...'\n if (this.eat(types.star)) {\n this.expectContextual(\"from\");\n if (this.type !== types.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n this.semicolon();\n return this.finishNode(node, \"ExportAllDeclaration\")\n }\n if (this.eat(types._default)) { // export default ...\n this.checkExport(exports, \"default\", this.lastTokStart);\n var isAsync;\n if (this.type === types._function || (isAsync = this.isAsyncFunction())) {\n var fNode = this.startNode();\n this.next();\n if (isAsync) { this.next(); }\n node.declaration = this.parseFunction(fNode, \"nullableID\", false, isAsync);\n } else if (this.type === types._class) {\n var cNode = this.startNode();\n node.declaration = this.parseClass(cNode, \"nullableID\");\n } else {\n node.declaration = this.parseMaybeAssign();\n this.semicolon();\n }\n return this.finishNode(node, \"ExportDefaultDeclaration\")\n }\n // export var|const|let|function|class ...\n if (this.shouldParseExportStatement()) {\n node.declaration = this.parseStatement(true);\n if (node.declaration.type === \"VariableDeclaration\")\n { this.checkVariableExport(exports, node.declaration.declarations); }\n else\n { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }\n node.specifiers = [];\n node.source = null;\n } else { // export { x, y as z } [from '...']\n node.declaration = null;\n node.specifiers = this.parseExportSpecifiers(exports);\n if (this.eatContextual(\"from\")) {\n if (this.type !== types.string) { this.unexpected(); }\n node.source = this.parseExprAtom();\n } else {\n // check for keywords used as local names\n for (var i = 0, list = node.specifiers; i < list.length; i += 1) {\n var spec = list[i];\n\n this$1.checkUnreserved(spec.local);\n }\n\n node.source = null;\n }\n this.semicolon();\n }\n return this.finishNode(node, \"ExportNamedDeclaration\")\n};\n\npp$1.checkExport = function(exports, name, pos) {\n if (!exports) { return }\n if (has(exports, name))\n { this.raiseRecoverable(pos, \"Duplicate export '\" + name + \"'\"); }\n exports[name] = true;\n};\n\npp$1.checkPatternExport = function(exports, pat) {\n var this$1 = this;\n\n var type = pat.type;\n if (type === \"Identifier\")\n { this.checkExport(exports, pat.name, pat.start); }\n else if (type === \"ObjectPattern\")\n { for (var i = 0, list = pat.properties; i < list.length; i += 1)\n {\n var prop = list[i];\n\n this$1.checkPatternExport(exports, prop);\n } }\n else if (type === \"ArrayPattern\")\n { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {\n var elt = list$1[i$1];\n\n if (elt) { this$1.checkPatternExport(exports, elt); }\n } }\n else if (type === \"Property\")\n { this.checkPatternExport(exports, pat.value); }\n else if (type === \"AssignmentPattern\")\n { this.checkPatternExport(exports, pat.left); }\n else if (type === \"RestElement\")\n { this.checkPatternExport(exports, pat.argument); }\n else if (type === \"ParenthesizedExpression\")\n { this.checkPatternExport(exports, pat.expression); }\n};\n\npp$1.checkVariableExport = function(exports, decls) {\n var this$1 = this;\n\n if (!exports) { return }\n for (var i = 0, list = decls; i < list.length; i += 1)\n {\n var decl = list[i];\n\n this$1.checkPatternExport(exports, decl.id);\n }\n};\n\npp$1.shouldParseExportStatement = function() {\n return this.type.keyword === \"var\" ||\n this.type.keyword === \"const\" ||\n this.type.keyword === \"class\" ||\n this.type.keyword === \"function\" ||\n this.isLet() ||\n this.isAsyncFunction()\n};\n\n// Parses a comma-separated list of module exports.\n\npp$1.parseExportSpecifiers = function(exports) {\n var this$1 = this;\n\n var nodes = [], first = true;\n // export { x, y as z } [from '...']\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var node = this$1.startNode();\n node.local = this$1.parseIdent(true);\n node.exported = this$1.eatContextual(\"as\") ? this$1.parseIdent(true) : node.local;\n this$1.checkExport(exports, node.exported.name, node.exported.start);\n nodes.push(this$1.finishNode(node, \"ExportSpecifier\"));\n }\n return nodes\n};\n\n// Parses import declaration.\n\npp$1.parseImport = function(node) {\n this.next();\n // import '...'\n if (this.type === types.string) {\n node.specifiers = empty;\n node.source = this.parseExprAtom();\n } else {\n node.specifiers = this.parseImportSpecifiers();\n this.expectContextual(\"from\");\n node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();\n }\n this.semicolon();\n return this.finishNode(node, \"ImportDeclaration\")\n};\n\n// Parses a comma-separated list of module imports.\n\npp$1.parseImportSpecifiers = function() {\n var this$1 = this;\n\n var nodes = [], first = true;\n if (this.type === types.name) {\n // import defaultObj, { x, y as z } from '...'\n var node = this.startNode();\n node.local = this.parseIdent();\n this.checkLVal(node.local, \"let\");\n nodes.push(this.finishNode(node, \"ImportDefaultSpecifier\"));\n if (!this.eat(types.comma)) { return nodes }\n }\n if (this.type === types.star) {\n var node$1 = this.startNode();\n this.next();\n this.expectContextual(\"as\");\n node$1.local = this.parseIdent();\n this.checkLVal(node$1.local, \"let\");\n nodes.push(this.finishNode(node$1, \"ImportNamespaceSpecifier\"));\n return nodes\n }\n this.expect(types.braceL);\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var node$2 = this$1.startNode();\n node$2.imported = this$1.parseIdent(true);\n if (this$1.eatContextual(\"as\")) {\n node$2.local = this$1.parseIdent();\n } else {\n this$1.checkUnreserved(node$2.imported);\n node$2.local = node$2.imported;\n }\n this$1.checkLVal(node$2.local, \"let\");\n nodes.push(this$1.finishNode(node$2, \"ImportSpecifier\"));\n }\n return nodes\n};\n\n// Set `ExpressionStatement#directive` property for directive prologues.\npp$1.adaptDirectivePrologue = function(statements) {\n for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {\n statements[i].directive = statements[i].expression.raw.slice(1, -1);\n }\n};\npp$1.isDirectiveCandidate = function(statement) {\n return (\n statement.type === \"ExpressionStatement\" &&\n statement.expression.type === \"Literal\" &&\n typeof statement.expression.value === \"string\" &&\n // Reject parenthesized strings.\n (this.input[statement.start] === \"\\\"\" || this.input[statement.start] === \"'\")\n )\n};\n\nvar pp$2 = Parser.prototype;\n\n// Convert existing expression atom to assignable pattern\n// if possible.\n\npp$2.toAssignable = function(node, isBinding, refDestructuringErrors) {\n var this$1 = this;\n\n if (this.options.ecmaVersion >= 6 && node) {\n switch (node.type) {\n case \"Identifier\":\n if (this.inAsync && node.name === \"await\")\n { this.raise(node.start, \"Can not use 'await' as identifier inside an async function\"); }\n break\n\n case \"ObjectPattern\":\n case \"ArrayPattern\":\n case \"RestElement\":\n break\n\n case \"ObjectExpression\":\n node.type = \"ObjectPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n for (var i = 0, list = node.properties; i < list.length; i += 1) {\n var prop = list[i];\n\n this$1.toAssignable(prop, isBinding);\n // Early error:\n // AssignmentRestProperty[Yield, Await] :\n // `...` DestructuringAssignmentTarget[Yield, Await]\n //\n // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.\n if (\n prop.type === \"RestElement\" &&\n (prop.argument.type === \"ArrayPattern\" || prop.argument.type === \"ObjectPattern\")\n ) {\n this$1.raise(prop.argument.start, \"Unexpected token\");\n }\n }\n break\n\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n if (node.kind !== \"init\") { this.raise(node.key.start, \"Object pattern can't contain getter or setter\"); }\n this.toAssignable(node.value, isBinding);\n break\n\n case \"ArrayExpression\":\n node.type = \"ArrayPattern\";\n if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n this.toAssignableList(node.elements, isBinding);\n break\n\n case \"SpreadElement\":\n node.type = \"RestElement\";\n this.toAssignable(node.argument, isBinding);\n if (node.argument.type === \"AssignmentPattern\")\n { this.raise(node.argument.start, \"Rest elements cannot have a default value\"); }\n break\n\n case \"AssignmentExpression\":\n if (node.operator !== \"=\") { this.raise(node.left.end, \"Only '=' operator can be used for specifying default value.\"); }\n node.type = \"AssignmentPattern\";\n delete node.operator;\n this.toAssignable(node.left, isBinding);\n // falls through to AssignmentPattern\n\n case \"AssignmentPattern\":\n break\n\n case \"ParenthesizedExpression\":\n this.toAssignable(node.expression, isBinding);\n break\n\n case \"MemberExpression\":\n if (!isBinding) { break }\n\n default:\n this.raise(node.start, \"Assigning to rvalue\");\n }\n } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }\n return node\n};\n\n// Convert list of expression atoms to binding list.\n\npp$2.toAssignableList = function(exprList, isBinding) {\n var this$1 = this;\n\n var end = exprList.length;\n for (var i = 0; i < end; i++) {\n var elt = exprList[i];\n if (elt) { this$1.toAssignable(elt, isBinding); }\n }\n if (end) {\n var last = exprList[end - 1];\n if (this.options.ecmaVersion === 6 && isBinding && last && last.type === \"RestElement\" && last.argument.type !== \"Identifier\")\n { this.unexpected(last.argument.start); }\n }\n return exprList\n};\n\n// Parses spread element.\n\npp$2.parseSpread = function(refDestructuringErrors) {\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n return this.finishNode(node, \"SpreadElement\")\n};\n\npp$2.parseRestBinding = function() {\n var node = this.startNode();\n this.next();\n\n // RestElement inside of a function parameter must be an identifier\n if (this.options.ecmaVersion === 6 && this.type !== types.name)\n { this.unexpected(); }\n\n node.argument = this.parseBindingAtom();\n\n return this.finishNode(node, \"RestElement\")\n};\n\n// Parses lvalue (assignable) atom.\n\npp$2.parseBindingAtom = function() {\n if (this.options.ecmaVersion >= 6) {\n switch (this.type) {\n case types.bracketL:\n var node = this.startNode();\n this.next();\n node.elements = this.parseBindingList(types.bracketR, true, true);\n return this.finishNode(node, \"ArrayPattern\")\n\n case types.braceL:\n return this.parseObj(true)\n }\n }\n return this.parseIdent()\n};\n\npp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {\n var this$1 = this;\n\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (first) { first = false; }\n else { this$1.expect(types.comma); }\n if (allowEmpty && this$1.type === types.comma) {\n elts.push(null);\n } else if (allowTrailingComma && this$1.afterTrailingComma(close)) {\n break\n } else if (this$1.type === types.ellipsis) {\n var rest = this$1.parseRestBinding();\n this$1.parseBindingListItem(rest);\n elts.push(rest);\n if (this$1.type === types.comma) { this$1.raise(this$1.start, \"Comma is not permitted after the rest element\"); }\n this$1.expect(close);\n break\n } else {\n var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc);\n this$1.parseBindingListItem(elem);\n elts.push(elem);\n }\n }\n return elts\n};\n\npp$2.parseBindingListItem = function(param) {\n return param\n};\n\n// Parses assignment pattern around given atom if possible.\n\npp$2.parseMaybeDefault = function(startPos, startLoc, left) {\n left = left || this.parseBindingAtom();\n if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.right = this.parseMaybeAssign();\n return this.finishNode(node, \"AssignmentPattern\")\n};\n\n// Verify that a node is an lval — something that can be assigned\n// to.\n// bindingType can be either:\n// 'var' indicating that the lval creates a 'var' binding\n// 'let' indicating that the lval creates a lexical ('let' or 'const') binding\n// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references\n\npp$2.checkLVal = function(expr, bindingType, checkClashes) {\n var this$1 = this;\n\n switch (expr.type) {\n case \"Identifier\":\n if (this.strict && this.reservedWordsStrictBind.test(expr.name))\n { this.raiseRecoverable(expr.start, (bindingType ? \"Binding \" : \"Assigning to \") + expr.name + \" in strict mode\"); }\n if (checkClashes) {\n if (has(checkClashes, expr.name))\n { this.raiseRecoverable(expr.start, \"Argument name clash\"); }\n checkClashes[expr.name] = true;\n }\n if (bindingType && bindingType !== \"none\") {\n if (\n bindingType === \"var\" && !this.canDeclareVarName(expr.name) ||\n bindingType !== \"var\" && !this.canDeclareLexicalName(expr.name)\n ) {\n this.raiseRecoverable(expr.start, (\"Identifier '\" + (expr.name) + \"' has already been declared\"));\n }\n if (bindingType === \"var\") {\n this.declareVarName(expr.name);\n } else {\n this.declareLexicalName(expr.name);\n }\n }\n break\n\n case \"MemberExpression\":\n if (bindingType) { this.raiseRecoverable(expr.start, \"Binding member expression\"); }\n break\n\n case \"ObjectPattern\":\n for (var i = 0, list = expr.properties; i < list.length; i += 1)\n {\n var prop = list[i];\n\n this$1.checkLVal(prop, bindingType, checkClashes);\n }\n break\n\n case \"Property\":\n // AssignmentProperty has type === \"Property\"\n this.checkLVal(expr.value, bindingType, checkClashes);\n break\n\n case \"ArrayPattern\":\n for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {\n var elem = list$1[i$1];\n\n if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); }\n }\n break\n\n case \"AssignmentPattern\":\n this.checkLVal(expr.left, bindingType, checkClashes);\n break\n\n case \"RestElement\":\n this.checkLVal(expr.argument, bindingType, checkClashes);\n break\n\n case \"ParenthesizedExpression\":\n this.checkLVal(expr.expression, bindingType, checkClashes);\n break\n\n default:\n this.raise(expr.start, (bindingType ? \"Binding\" : \"Assigning to\") + \" rvalue\");\n }\n};\n\n// A recursive descent parser operates by defining functions for all\n// syntactic elements, and recursively calling those, each function\n// advancing the input stream and returning an AST node. Precedence\n// of constructs (for example, the fact that `!x[1]` means `!(x[1])`\n// instead of `(!x)[1]` is handled by the fact that the parser\n// function that parses unary prefix operators is called first, and\n// in turn calls the function that parses `[]` subscripts — that\n// way, it'll receive the node for `x[1]` already parsed, and wraps\n// *that* in the unary operator node.\n//\n// Acorn uses an [operator precedence parser][opp] to handle binary\n// operator precedence, because it is much more compact than using\n// the technique outlined above, which uses different, nesting\n// functions to specify precedence, for all of the ten binary\n// precedence levels that JavaScript defines.\n//\n// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser\n\nvar pp$3 = Parser.prototype;\n\n// Check if property name clashes with already added.\n// Object/class getters and setters are not allowed to clash —\n// either with each other or with an init property — and in\n// strict mode, init properties are also not allowed to be repeated.\n\npp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {\n if (this.options.ecmaVersion >= 9 && prop.type === \"SpreadElement\")\n { return }\n if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))\n { return }\n var key = prop.key;\n var name;\n switch (key.type) {\n case \"Identifier\": name = key.name; break\n case \"Literal\": name = String(key.value); break\n default: return\n }\n var kind = prop.kind;\n if (this.options.ecmaVersion >= 6) {\n if (name === \"__proto__\" && kind === \"init\") {\n if (propHash.proto) {\n if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; }\n // Backwards-compat kludge. Can be removed in version 6.0\n else { this.raiseRecoverable(key.start, \"Redefinition of __proto__ property\"); }\n }\n propHash.proto = true;\n }\n return\n }\n name = \"$\" + name;\n var other = propHash[name];\n if (other) {\n var redefinition;\n if (kind === \"init\") {\n redefinition = this.strict && other.init || other.get || other.set;\n } else {\n redefinition = other.init || other[kind];\n }\n if (redefinition)\n { this.raiseRecoverable(key.start, \"Redefinition of property\"); }\n } else {\n other = propHash[name] = {\n init: false,\n get: false,\n set: false\n };\n }\n other[kind] = true;\n};\n\n// ### Expression parsing\n\n// These nest, from the most general expression type at the top to\n// 'atomic', nondivisible expression types at the bottom. Most of\n// the functions will simply let the function(s) below them parse,\n// and, *if* the syntactic construct they handle is present, wrap\n// the AST node that the inner parser gave them in another node.\n\n// Parse a full expression. The optional arguments are used to\n// forbid the `in` operator (in for loops initalization expressions)\n// and provide reference for storing '=' operator inside shorthand\n// property assignment in contexts where both object expression\n// and object pattern might appear (so it's possible to raise\n// delayed syntax error at correct position).\n\npp$3.parseExpression = function(noIn, refDestructuringErrors) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);\n if (this.type === types.comma) {\n var node = this.startNodeAt(startPos, startLoc);\n node.expressions = [expr];\n while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); }\n return this.finishNode(node, \"SequenceExpression\")\n }\n return expr\n};\n\n// Parse an assignment expression. This includes applications of\n// operators like `+=`.\n\npp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {\n if (this.inGenerator && this.isContextual(\"yield\")) { return this.parseYield() }\n\n var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;\n if (refDestructuringErrors) {\n oldParenAssign = refDestructuringErrors.parenthesizedAssign;\n oldTrailingComma = refDestructuringErrors.trailingComma;\n refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;\n } else {\n refDestructuringErrors = new DestructuringErrors;\n ownDestructuringErrors = true;\n }\n\n var startPos = this.start, startLoc = this.startLoc;\n if (this.type === types.parenL || this.type === types.name)\n { this.potentialArrowAt = this.start; }\n var left = this.parseMaybeConditional(noIn, refDestructuringErrors);\n if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }\n if (this.type.isAssign) {\n var node = this.startNodeAt(startPos, startLoc);\n node.operator = this.value;\n node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;\n if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); }\n refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly\n this.checkLVal(left);\n this.next();\n node.right = this.parseMaybeAssign(noIn);\n return this.finishNode(node, \"AssignmentExpression\")\n } else {\n if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }\n }\n if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }\n if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }\n return left\n};\n\n// Parse a ternary conditional (`?:`) operator.\n\npp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprOps(noIn, refDestructuringErrors);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n if (this.eat(types.question)) {\n var node = this.startNodeAt(startPos, startLoc);\n node.test = expr;\n node.consequent = this.parseMaybeAssign();\n this.expect(types.colon);\n node.alternate = this.parseMaybeAssign(noIn);\n return this.finishNode(node, \"ConditionalExpression\")\n }\n return expr\n};\n\n// Start the precedence parser.\n\npp$3.parseExprOps = function(noIn, refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseMaybeUnary(refDestructuringErrors, false);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n return expr.start === startPos && expr.type === \"ArrowFunctionExpression\" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)\n};\n\n// Parse binary operators with the operator precedence parsing\n// algorithm. `left` is the left-hand side of the operator.\n// `minPrec` provides context that allows the function to stop and\n// defer further parser to one of its callers when it encounters an\n// operator that has a lower precedence than the set it is parsing.\n\npp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {\n var prec = this.type.binop;\n if (prec != null && (!noIn || this.type !== types._in)) {\n if (prec > minPrec) {\n var logical = this.type === types.logicalOR || this.type === types.logicalAND;\n var op = this.value;\n this.next();\n var startPos = this.start, startLoc = this.startLoc;\n var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);\n var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical);\n return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)\n }\n }\n return left\n};\n\npp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {\n var node = this.startNodeAt(startPos, startLoc);\n node.left = left;\n node.operator = op;\n node.right = right;\n return this.finishNode(node, logical ? \"LogicalExpression\" : \"BinaryExpression\")\n};\n\n// Parse unary operators, both prefix and postfix.\n\npp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc, expr;\n if (this.isContextual(\"await\") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {\n expr = this.parseAwait();\n sawUnary = true;\n } else if (this.type.prefix) {\n var node = this.startNode(), update = this.type === types.incDec;\n node.operator = this.value;\n node.prefix = true;\n this.next();\n node.argument = this.parseMaybeUnary(null, true);\n this.checkExpressionErrors(refDestructuringErrors, true);\n if (update) { this.checkLVal(node.argument); }\n else if (this.strict && node.operator === \"delete\" &&\n node.argument.type === \"Identifier\")\n { this.raiseRecoverable(node.start, \"Deleting local variable in strict mode\"); }\n else { sawUnary = true; }\n expr = this.finishNode(node, update ? \"UpdateExpression\" : \"UnaryExpression\");\n } else {\n expr = this.parseExprSubscripts(refDestructuringErrors);\n if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }\n while (this.type.postfix && !this.canInsertSemicolon()) {\n var node$1 = this$1.startNodeAt(startPos, startLoc);\n node$1.operator = this$1.value;\n node$1.prefix = false;\n node$1.argument = expr;\n this$1.checkLVal(expr);\n this$1.next();\n expr = this$1.finishNode(node$1, \"UpdateExpression\");\n }\n }\n\n if (!sawUnary && this.eat(types.starstar))\n { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), \"**\", false) }\n else\n { return expr }\n};\n\n// Parse call, dot, and `[]`-subscript expressions.\n\npp$3.parseExprSubscripts = function(refDestructuringErrors) {\n var startPos = this.start, startLoc = this.startLoc;\n var expr = this.parseExprAtom(refDestructuringErrors);\n var skipArrowSubscripts = expr.type === \"ArrowFunctionExpression\" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== \")\";\n if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr }\n var result = this.parseSubscripts(expr, startPos, startLoc);\n if (refDestructuringErrors && result.type === \"MemberExpression\") {\n if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }\n if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }\n }\n return result\n};\n\npp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {\n var this$1 = this;\n\n var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === \"Identifier\" && base.name === \"async\" &&\n this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === \"async\";\n for (var computed = (void 0);;) {\n if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) {\n var node = this$1.startNodeAt(startPos, startLoc);\n node.object = base;\n node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true);\n node.computed = !!computed;\n if (computed) { this$1.expect(types.bracketR); }\n base = this$1.finishNode(node, \"MemberExpression\");\n } else if (!noCalls && this$1.eat(types.parenL)) {\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos;\n this$1.yieldPos = 0;\n this$1.awaitPos = 0;\n var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors);\n if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) {\n this$1.checkPatternErrors(refDestructuringErrors, false);\n this$1.checkYieldAwaitInDefaultParams();\n this$1.yieldPos = oldYieldPos;\n this$1.awaitPos = oldAwaitPos;\n return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true)\n }\n this$1.checkExpressionErrors(refDestructuringErrors, true);\n this$1.yieldPos = oldYieldPos || this$1.yieldPos;\n this$1.awaitPos = oldAwaitPos || this$1.awaitPos;\n var node$1 = this$1.startNodeAt(startPos, startLoc);\n node$1.callee = base;\n node$1.arguments = exprList;\n base = this$1.finishNode(node$1, \"CallExpression\");\n } else if (this$1.type === types.backQuote) {\n var node$2 = this$1.startNodeAt(startPos, startLoc);\n node$2.tag = base;\n node$2.quasi = this$1.parseTemplate({isTagged: true});\n base = this$1.finishNode(node$2, \"TaggedTemplateExpression\");\n } else {\n return base\n }\n }\n};\n\n// Parse an atomic expression — either a single token that is an\n// expression, an expression started by a keyword like `function` or\n// `new`, or an expression wrapped in punctuation like `()`, `[]`,\n// or `{}`.\n\npp$3.parseExprAtom = function(refDestructuringErrors) {\n var node, canBeArrow = this.potentialArrowAt === this.start;\n switch (this.type) {\n case types._super:\n if (!this.inFunction)\n { this.raise(this.start, \"'super' outside of function or class\"); }\n node = this.startNode();\n this.next();\n // The `super` keyword can appear at below:\n // SuperProperty:\n // super [ Expression ]\n // super . IdentifierName\n // SuperCall:\n // super Arguments\n if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)\n { this.unexpected(); }\n return this.finishNode(node, \"Super\")\n\n case types._this:\n node = this.startNode();\n this.next();\n return this.finishNode(node, \"ThisExpression\")\n\n case types.name:\n var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;\n var id = this.parseIdent(this.type !== types.name);\n if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === \"async\" && !this.canInsertSemicolon() && this.eat(types._function))\n { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) }\n if (canBeArrow && !this.canInsertSemicolon()) {\n if (this.eat(types.arrow))\n { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }\n if (this.options.ecmaVersion >= 8 && id.name === \"async\" && this.type === types.name && !containsEsc) {\n id = this.parseIdent();\n if (this.canInsertSemicolon() || !this.eat(types.arrow))\n { this.unexpected(); }\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)\n }\n }\n return id\n\n case types.regexp:\n var value = this.value;\n node = this.parseLiteral(value.value);\n node.regex = {pattern: value.pattern, flags: value.flags};\n return node\n\n case types.num: case types.string:\n return this.parseLiteral(this.value)\n\n case types._null: case types._true: case types._false:\n node = this.startNode();\n node.value = this.type === types._null ? null : this.type === types._true;\n node.raw = this.type.keyword;\n this.next();\n return this.finishNode(node, \"Literal\")\n\n case types.parenL:\n var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);\n if (refDestructuringErrors) {\n if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))\n { refDestructuringErrors.parenthesizedAssign = start; }\n if (refDestructuringErrors.parenthesizedBind < 0)\n { refDestructuringErrors.parenthesizedBind = start; }\n }\n return expr\n\n case types.bracketL:\n node = this.startNode();\n this.next();\n node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);\n return this.finishNode(node, \"ArrayExpression\")\n\n case types.braceL:\n return this.parseObj(false, refDestructuringErrors)\n\n case types._function:\n node = this.startNode();\n this.next();\n return this.parseFunction(node, false)\n\n case types._class:\n return this.parseClass(this.startNode(), false)\n\n case types._new:\n return this.parseNew()\n\n case types.backQuote:\n return this.parseTemplate()\n\n default:\n this.unexpected();\n }\n};\n\npp$3.parseLiteral = function(value) {\n var node = this.startNode();\n node.value = value;\n node.raw = this.input.slice(this.start, this.end);\n this.next();\n return this.finishNode(node, \"Literal\")\n};\n\npp$3.parseParenExpression = function() {\n this.expect(types.parenL);\n var val = this.parseExpression();\n this.expect(types.parenR);\n return val\n};\n\npp$3.parseParenAndDistinguishExpression = function(canBeArrow) {\n var this$1 = this;\n\n var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;\n if (this.options.ecmaVersion >= 6) {\n this.next();\n\n var innerStartPos = this.start, innerStartLoc = this.startLoc;\n var exprList = [], first = true, lastIsComma = false;\n var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;\n this.yieldPos = 0;\n this.awaitPos = 0;\n while (this.type !== types.parenR) {\n first ? first = false : this$1.expect(types.comma);\n if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) {\n lastIsComma = true;\n break\n } else if (this$1.type === types.ellipsis) {\n spreadStart = this$1.start;\n exprList.push(this$1.parseParenItem(this$1.parseRestBinding()));\n if (this$1.type === types.comma) { this$1.raise(this$1.start, \"Comma is not permitted after the rest element\"); }\n break\n } else {\n exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem));\n }\n }\n var innerEndPos = this.start, innerEndLoc = this.startLoc;\n this.expect(types.parenR);\n\n if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {\n this.checkPatternErrors(refDestructuringErrors, false);\n this.checkYieldAwaitInDefaultParams();\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n return this.parseParenArrowList(startPos, startLoc, exprList)\n }\n\n if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }\n if (spreadStart) { this.unexpected(spreadStart); }\n this.checkExpressionErrors(refDestructuringErrors, true);\n this.yieldPos = oldYieldPos || this.yieldPos;\n this.awaitPos = oldAwaitPos || this.awaitPos;\n\n if (exprList.length > 1) {\n val = this.startNodeAt(innerStartPos, innerStartLoc);\n val.expressions = exprList;\n this.finishNodeAt(val, \"SequenceExpression\", innerEndPos, innerEndLoc);\n } else {\n val = exprList[0];\n }\n } else {\n val = this.parseParenExpression();\n }\n\n if (this.options.preserveParens) {\n var par = this.startNodeAt(startPos, startLoc);\n par.expression = val;\n return this.finishNode(par, \"ParenthesizedExpression\")\n } else {\n return val\n }\n};\n\npp$3.parseParenItem = function(item) {\n return item\n};\n\npp$3.parseParenArrowList = function(startPos, startLoc, exprList) {\n return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)\n};\n\n// New's precedence is slightly tricky. It must allow its argument to\n// be a `[]` or dot subscript expression, but not a call — at least,\n// not without wrapping it in parentheses. Thus, it uses the noCalls\n// argument to parseSubscripts to prevent it from consuming the\n// argument list.\n\nvar empty$1 = [];\n\npp$3.parseNew = function() {\n var node = this.startNode();\n var meta = this.parseIdent(true);\n if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {\n node.meta = meta;\n var containsEsc = this.containsEsc;\n node.property = this.parseIdent(true);\n if (node.property.name !== \"target\" || containsEsc)\n { this.raiseRecoverable(node.property.start, \"The only valid meta property for new is new.target\"); }\n if (!this.inFunction)\n { this.raiseRecoverable(node.start, \"new.target can only be used in functions\"); }\n return this.finishNode(node, \"MetaProperty\")\n }\n var startPos = this.start, startLoc = this.startLoc;\n node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);\n if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }\n else { node.arguments = empty$1; }\n return this.finishNode(node, \"NewExpression\")\n};\n\n// Parse template expression.\n\npp$3.parseTemplateElement = function(ref) {\n var isTagged = ref.isTagged;\n\n var elem = this.startNode();\n if (this.type === types.invalidTemplate) {\n if (!isTagged) {\n this.raiseRecoverable(this.start, \"Bad escape sequence in untagged template literal\");\n }\n elem.value = {\n raw: this.value,\n cooked: null\n };\n } else {\n elem.value = {\n raw: this.input.slice(this.start, this.end).replace(/\\r\\n?/g, \"\\n\"),\n cooked: this.value\n };\n }\n this.next();\n elem.tail = this.type === types.backQuote;\n return this.finishNode(elem, \"TemplateElement\")\n};\n\npp$3.parseTemplate = function(ref) {\n var this$1 = this;\n if ( ref === void 0 ) ref = {};\n var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;\n\n var node = this.startNode();\n this.next();\n node.expressions = [];\n var curElt = this.parseTemplateElement({isTagged: isTagged});\n node.quasis = [curElt];\n while (!curElt.tail) {\n if (this$1.type === types.eof) { this$1.raise(this$1.pos, \"Unterminated template literal\"); }\n this$1.expect(types.dollarBraceL);\n node.expressions.push(this$1.parseExpression());\n this$1.expect(types.braceR);\n node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged}));\n }\n this.next();\n return this.finishNode(node, \"TemplateLiteral\")\n};\n\npp$3.isAsyncProp = function(prop) {\n return !prop.computed && prop.key.type === \"Identifier\" && prop.key.name === \"async\" &&\n (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) &&\n !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))\n};\n\n// Parse an object literal or binding pattern.\n\npp$3.parseObj = function(isPattern, refDestructuringErrors) {\n var this$1 = this;\n\n var node = this.startNode(), first = true, propHash = {};\n node.properties = [];\n this.next();\n while (!this.eat(types.braceR)) {\n if (!first) {\n this$1.expect(types.comma);\n if (this$1.afterTrailingComma(types.braceR)) { break }\n } else { first = false; }\n\n var prop = this$1.parseProperty(isPattern, refDestructuringErrors);\n if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); }\n node.properties.push(prop);\n }\n return this.finishNode(node, isPattern ? \"ObjectPattern\" : \"ObjectExpression\")\n};\n\npp$3.parseProperty = function(isPattern, refDestructuringErrors) {\n var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;\n if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) {\n if (isPattern) {\n prop.argument = this.parseIdent(false);\n if (this.type === types.comma) {\n this.raise(this.start, \"Comma is not permitted after the rest element\");\n }\n return this.finishNode(prop, \"RestElement\")\n }\n // To disallow parenthesized identifier via `this.toAssignable()`.\n if (this.type === types.parenL && refDestructuringErrors) {\n if (refDestructuringErrors.parenthesizedAssign < 0) {\n refDestructuringErrors.parenthesizedAssign = this.start;\n }\n if (refDestructuringErrors.parenthesizedBind < 0) {\n refDestructuringErrors.parenthesizedBind = this.start;\n }\n }\n // Parse argument.\n prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);\n // To disallow trailing comma via `this.toAssignable()`.\n if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {\n refDestructuringErrors.trailingComma = this.start;\n }\n // Finish\n return this.finishNode(prop, \"SpreadElement\")\n }\n if (this.options.ecmaVersion >= 6) {\n prop.method = false;\n prop.shorthand = false;\n if (isPattern || refDestructuringErrors) {\n startPos = this.start;\n startLoc = this.startLoc;\n }\n if (!isPattern)\n { isGenerator = this.eat(types.star); }\n }\n var containsEsc = this.containsEsc;\n this.parsePropertyName(prop);\n if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {\n isAsync = true;\n isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);\n this.parsePropertyName(prop, refDestructuringErrors);\n } else {\n isAsync = false;\n }\n this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);\n return this.finishNode(prop, \"Property\")\n};\n\npp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {\n if ((isGenerator || isAsync) && this.type === types.colon)\n { this.unexpected(); }\n\n if (this.eat(types.colon)) {\n prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);\n prop.kind = \"init\";\n } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {\n if (isPattern) { this.unexpected(); }\n prop.kind = \"init\";\n prop.method = true;\n prop.value = this.parseMethod(isGenerator, isAsync);\n } else if (!isPattern && !containsEsc &&\n this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === \"Identifier\" &&\n (prop.key.name === \"get\" || prop.key.name === \"set\") &&\n (this.type !== types.comma && this.type !== types.braceR)) {\n if (isGenerator || isAsync) { this.unexpected(); }\n prop.kind = prop.key.name;\n this.parsePropertyName(prop);\n prop.value = this.parseMethod(false);\n var paramCount = prop.kind === \"get\" ? 0 : 1;\n if (prop.value.params.length !== paramCount) {\n var start = prop.value.start;\n if (prop.kind === \"get\")\n { this.raiseRecoverable(start, \"getter should have no params\"); }\n else\n { this.raiseRecoverable(start, \"setter should have exactly one param\"); }\n } else {\n if (prop.kind === \"set\" && prop.value.params[0].type === \"RestElement\")\n { this.raiseRecoverable(prop.value.params[0].start, \"Setter cannot use rest params\"); }\n }\n } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === \"Identifier\") {\n this.checkUnreserved(prop.key);\n prop.kind = \"init\";\n if (isPattern) {\n prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);\n } else if (this.type === types.eq && refDestructuringErrors) {\n if (refDestructuringErrors.shorthandAssign < 0)\n { refDestructuringErrors.shorthandAssign = this.start; }\n prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);\n } else {\n prop.value = prop.key;\n }\n prop.shorthand = true;\n } else { this.unexpected(); }\n};\n\npp$3.parsePropertyName = function(prop) {\n if (this.options.ecmaVersion >= 6) {\n if (this.eat(types.bracketL)) {\n prop.computed = true;\n prop.key = this.parseMaybeAssign();\n this.expect(types.bracketR);\n return prop.key\n } else {\n prop.computed = false;\n }\n }\n return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true)\n};\n\n// Initialize empty function node.\n\npp$3.initFunction = function(node) {\n node.id = null;\n if (this.options.ecmaVersion >= 6) {\n node.generator = false;\n node.expression = false;\n }\n if (this.options.ecmaVersion >= 8)\n { node.async = false; }\n};\n\n// Parse object or class method.\n\npp$3.parseMethod = function(isGenerator, isAsync) {\n var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n\n this.initFunction(node);\n if (this.options.ecmaVersion >= 6)\n { node.generator = isGenerator; }\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n this.inGenerator = node.generator;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n this.enterFunctionScope();\n\n this.expect(types.parenL);\n node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);\n this.checkYieldAwaitInDefaultParams();\n this.parseFunctionBody(node, false);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, \"FunctionExpression\")\n};\n\n// Parse arrow function expression with given parameters.\n\npp$3.parseArrowExpression = function(node, params, isAsync) {\n var oldInGen = this.inGenerator, oldInAsync = this.inAsync,\n oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;\n\n this.enterFunctionScope();\n this.initFunction(node);\n if (this.options.ecmaVersion >= 8)\n { node.async = !!isAsync; }\n\n this.inGenerator = false;\n this.inAsync = node.async;\n this.yieldPos = 0;\n this.awaitPos = 0;\n this.inFunction = true;\n\n node.params = this.toAssignableList(params, true);\n this.parseFunctionBody(node, true);\n\n this.inGenerator = oldInGen;\n this.inAsync = oldInAsync;\n this.yieldPos = oldYieldPos;\n this.awaitPos = oldAwaitPos;\n this.inFunction = oldInFunc;\n return this.finishNode(node, \"ArrowFunctionExpression\")\n};\n\n// Parse function body and check parameters.\n\npp$3.parseFunctionBody = function(node, isArrowFunction) {\n var isExpression = isArrowFunction && this.type !== types.braceL;\n var oldStrict = this.strict, useStrict = false;\n\n if (isExpression) {\n node.body = this.parseMaybeAssign();\n node.expression = true;\n this.checkParams(node, false);\n } else {\n var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);\n if (!oldStrict || nonSimple) {\n useStrict = this.strictDirective(this.end);\n // If this is a strict mode function, verify that argument names\n // are not repeated, and it does not try to bind the words `eval`\n // or `arguments`.\n if (useStrict && nonSimple)\n { this.raiseRecoverable(node.start, \"Illegal 'use strict' directive in function with non-simple parameter list\"); }\n }\n // Start a new scope with regard to labels and the `inFunction`\n // flag (restore them to their old value afterwards).\n var oldLabels = this.labels;\n this.labels = [];\n if (useStrict) { this.strict = true; }\n\n // Add the params to varDeclaredNames to ensure that an error is thrown\n // if a let/const declaration in the function clashes with one of the params.\n this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params));\n node.body = this.parseBlock(false);\n node.expression = false;\n this.adaptDirectivePrologue(node.body.body);\n this.labels = oldLabels;\n }\n this.exitFunctionScope();\n\n if (this.strict && node.id) {\n // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'\n this.checkLVal(node.id, \"none\");\n }\n this.strict = oldStrict;\n};\n\npp$3.isSimpleParamList = function(params) {\n for (var i = 0, list = params; i < list.length; i += 1)\n {\n var param = list[i];\n\n if (param.type !== \"Identifier\") { return false\n } }\n return true\n};\n\n// Checks function params for various disallowed patterns such as using \"eval\"\n// or \"arguments\" and duplicate parameters.\n\npp$3.checkParams = function(node, allowDuplicates) {\n var this$1 = this;\n\n var nameHash = {};\n for (var i = 0, list = node.params; i < list.length; i += 1)\n {\n var param = list[i];\n\n this$1.checkLVal(param, \"var\", allowDuplicates ? null : nameHash);\n }\n};\n\n// Parses a comma-separated list of expressions, and returns them as\n// an array. `close` is the token type that ends the list, and\n// `allowEmpty` can be turned on to allow subsequent commas with\n// nothing in between them to be parsed as `null` (which is needed\n// for array literals).\n\npp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {\n var this$1 = this;\n\n var elts = [], first = true;\n while (!this.eat(close)) {\n if (!first) {\n this$1.expect(types.comma);\n if (allowTrailingComma && this$1.afterTrailingComma(close)) { break }\n } else { first = false; }\n\n var elt = (void 0);\n if (allowEmpty && this$1.type === types.comma)\n { elt = null; }\n else if (this$1.type === types.ellipsis) {\n elt = this$1.parseSpread(refDestructuringErrors);\n if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0)\n { refDestructuringErrors.trailingComma = this$1.start; }\n } else {\n elt = this$1.parseMaybeAssign(false, refDestructuringErrors);\n }\n elts.push(elt);\n }\n return elts\n};\n\npp$3.checkUnreserved = function(ref) {\n var start = ref.start;\n var end = ref.end;\n var name = ref.name;\n\n if (this.inGenerator && name === \"yield\")\n { this.raiseRecoverable(start, \"Can not use 'yield' as identifier inside a generator\"); }\n if (this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Can not use 'await' as identifier inside an async function\"); }\n if (this.isKeyword(name))\n { this.raise(start, (\"Unexpected keyword '\" + name + \"'\")); }\n if (this.options.ecmaVersion < 6 &&\n this.input.slice(start, end).indexOf(\"\\\\\") !== -1) { return }\n var re = this.strict ? this.reservedWordsStrict : this.reservedWords;\n if (re.test(name)) {\n if (!this.inAsync && name === \"await\")\n { this.raiseRecoverable(start, \"Can not use keyword 'await' outside an async function\"); }\n this.raiseRecoverable(start, (\"The keyword '\" + name + \"' is reserved\"));\n }\n};\n\n// Parse the next token as an identifier. If `liberal` is true (used\n// when parsing properties), it will also convert keywords into\n// identifiers.\n\npp$3.parseIdent = function(liberal, isBinding) {\n var node = this.startNode();\n if (liberal && this.options.allowReserved === \"never\") { liberal = false; }\n if (this.type === types.name) {\n node.name = this.value;\n } else if (this.type.keyword) {\n node.name = this.type.keyword;\n\n // To fix https://github.com/acornjs/acorn/issues/575\n // `class` and `function` keywords push new context into this.context.\n // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.\n // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword\n if ((node.name === \"class\" || node.name === \"function\") &&\n (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {\n this.context.pop();\n }\n } else {\n this.unexpected();\n }\n this.next();\n this.finishNode(node, \"Identifier\");\n if (!liberal) { this.checkUnreserved(node); }\n return node\n};\n\n// Parses yield expression inside generator.\n\npp$3.parseYield = function() {\n if (!this.yieldPos) { this.yieldPos = this.start; }\n\n var node = this.startNode();\n this.next();\n if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) {\n node.delegate = false;\n node.argument = null;\n } else {\n node.delegate = this.eat(types.star);\n node.argument = this.parseMaybeAssign();\n }\n return this.finishNode(node, \"YieldExpression\")\n};\n\npp$3.parseAwait = function() {\n if (!this.awaitPos) { this.awaitPos = this.start; }\n\n var node = this.startNode();\n this.next();\n node.argument = this.parseMaybeUnary(null, true);\n return this.finishNode(node, \"AwaitExpression\")\n};\n\nvar pp$4 = Parser.prototype;\n\n// This function is used to raise exceptions on parse errors. It\n// takes an offset integer (into the current `input`) to indicate\n// the location of the error, attaches the position to the end\n// of the error message, and then raises a `SyntaxError` with that\n// message.\n\npp$4.raise = function(pos, message) {\n var loc = getLineInfo(this.input, pos);\n message += \" (\" + loc.line + \":\" + loc.column + \")\";\n var err = new SyntaxError(message);\n err.pos = pos; err.loc = loc; err.raisedAt = this.pos;\n throw err\n};\n\npp$4.raiseRecoverable = pp$4.raise;\n\npp$4.curPosition = function() {\n if (this.options.locations) {\n return new Position(this.curLine, this.pos - this.lineStart)\n }\n};\n\nvar pp$5 = Parser.prototype;\n\n// Object.assign polyfill\nvar assign = Object.assign || function(target) {\n var sources = [], len = arguments.length - 1;\n while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];\n\n for (var i = 0, list = sources; i < list.length; i += 1) {\n var source = list[i];\n\n for (var key in source) {\n if (has(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target\n};\n\n// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.\n\npp$5.enterFunctionScope = function() {\n // var: a hash of var-declared names in the current lexical scope\n // lexical: a hash of lexically-declared names in the current lexical scope\n // childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope)\n // parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope)\n this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}});\n};\n\npp$5.exitFunctionScope = function() {\n this.scopeStack.pop();\n};\n\npp$5.enterLexicalScope = function() {\n var parentScope = this.scopeStack[this.scopeStack.length - 1];\n var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}};\n\n this.scopeStack.push(childScope);\n assign(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical);\n};\n\npp$5.exitLexicalScope = function() {\n var childScope = this.scopeStack.pop();\n var parentScope = this.scopeStack[this.scopeStack.length - 1];\n\n assign(parentScope.childVar, childScope.var, childScope.childVar);\n};\n\n/**\n * A name can be declared with `var` if there are no variables with the same name declared with `let`/`const`\n * in the current lexical scope or any of the parent lexical scopes in this function.\n */\npp$5.canDeclareVarName = function(name) {\n var currentScope = this.scopeStack[this.scopeStack.length - 1];\n\n return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name)\n};\n\n/**\n * A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const`\n * in the current scope, and there are no variables with the same name declared with `var` in the current scope or in\n * any child lexical scopes in this function.\n */\npp$5.canDeclareLexicalName = function(name) {\n var currentScope = this.scopeStack[this.scopeStack.length - 1];\n\n return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name)\n};\n\npp$5.declareVarName = function(name) {\n this.scopeStack[this.scopeStack.length - 1].var[name] = true;\n};\n\npp$5.declareLexicalName = function(name) {\n this.scopeStack[this.scopeStack.length - 1].lexical[name] = true;\n};\n\nvar Node = function Node(parser, pos, loc) {\n this.type = \"\";\n this.start = pos;\n this.end = 0;\n if (parser.options.locations)\n { this.loc = new SourceLocation(parser, loc); }\n if (parser.options.directSourceFile)\n { this.sourceFile = parser.options.directSourceFile; }\n if (parser.options.ranges)\n { this.range = [pos, 0]; }\n};\n\n// Start an AST node, attaching a start offset.\n\nvar pp$6 = Parser.prototype;\n\npp$6.startNode = function() {\n return new Node(this, this.start, this.startLoc)\n};\n\npp$6.startNodeAt = function(pos, loc) {\n return new Node(this, pos, loc)\n};\n\n// Finish an AST node, adding `type` and `end` properties.\n\nfunction finishNodeAt(node, type, pos, loc) {\n node.type = type;\n node.end = pos;\n if (this.options.locations)\n { node.loc.end = loc; }\n if (this.options.ranges)\n { node.range[1] = pos; }\n return node\n}\n\npp$6.finishNode = function(node, type) {\n return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)\n};\n\n// Finish node at given position\n\npp$6.finishNodeAt = function(node, type, pos, loc) {\n return finishNodeAt.call(this, node, type, pos, loc)\n};\n\n// The algorithm used to determine whether a regexp can appear at a\n// given point in the program is loosely based on sweet.js' approach.\n// See https://github.com/mozilla/sweet.js/wiki/design\n\nvar TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {\n this.token = token;\n this.isExpr = !!isExpr;\n this.preserveSpace = !!preserveSpace;\n this.override = override;\n this.generator = !!generator;\n};\n\nvar types$1 = {\n b_stat: new TokContext(\"{\", false),\n b_expr: new TokContext(\"{\", true),\n b_tmpl: new TokContext(\"${\", false),\n p_stat: new TokContext(\"(\", false),\n p_expr: new TokContext(\"(\", true),\n q_tmpl: new TokContext(\"`\", true, true, function (p) { return p.tryReadTemplateToken(); }),\n f_stat: new TokContext(\"function\", false),\n f_expr: new TokContext(\"function\", true),\n f_expr_gen: new TokContext(\"function\", true, false, null, true),\n f_gen: new TokContext(\"function\", false, false, null, true)\n};\n\nvar pp$7 = Parser.prototype;\n\npp$7.initialContext = function() {\n return [types$1.b_stat]\n};\n\npp$7.braceIsBlock = function(prevType) {\n var parent = this.curContext();\n if (parent === types$1.f_expr || parent === types$1.f_stat)\n { return true }\n if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))\n { return !parent.isExpr }\n\n // The check for `tt.name && exprAllowed` detects whether we are\n // after a `yield` or `of` construct. See the `updateContext` for\n // `tt.name`.\n if (prevType === types._return || prevType === types.name && this.exprAllowed)\n { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }\n if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow)\n { return true }\n if (prevType === types.braceL)\n { return parent === types$1.b_stat }\n if (prevType === types._var || prevType === types.name)\n { return false }\n return !this.exprAllowed\n};\n\npp$7.inGeneratorContext = function() {\n var this$1 = this;\n\n for (var i = this.context.length - 1; i >= 1; i--) {\n var context = this$1.context[i];\n if (context.token === \"function\")\n { return context.generator }\n }\n return false\n};\n\npp$7.updateContext = function(prevType) {\n var update, type = this.type;\n if (type.keyword && prevType === types.dot)\n { this.exprAllowed = false; }\n else if (update = type.updateContext)\n { update.call(this, prevType); }\n else\n { this.exprAllowed = type.beforeExpr; }\n};\n\n// Token-specific context update code\n\ntypes.parenR.updateContext = types.braceR.updateContext = function() {\n if (this.context.length === 1) {\n this.exprAllowed = true;\n return\n }\n var out = this.context.pop();\n if (out === types$1.b_stat && this.curContext().token === \"function\") {\n out = this.context.pop();\n }\n this.exprAllowed = !out.isExpr;\n};\n\ntypes.braceL.updateContext = function(prevType) {\n this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);\n this.exprAllowed = true;\n};\n\ntypes.dollarBraceL.updateContext = function() {\n this.context.push(types$1.b_tmpl);\n this.exprAllowed = true;\n};\n\ntypes.parenL.updateContext = function(prevType) {\n var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;\n this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);\n this.exprAllowed = true;\n};\n\ntypes.incDec.updateContext = function() {\n // tokExprAllowed stays unchanged\n};\n\ntypes._function.updateContext = types._class.updateContext = function(prevType) {\n if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&\n !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))\n { this.context.push(types$1.f_expr); }\n else\n { this.context.push(types$1.f_stat); }\n this.exprAllowed = false;\n};\n\ntypes.backQuote.updateContext = function() {\n if (this.curContext() === types$1.q_tmpl)\n { this.context.pop(); }\n else\n { this.context.push(types$1.q_tmpl); }\n this.exprAllowed = false;\n};\n\ntypes.star.updateContext = function(prevType) {\n if (prevType === types._function) {\n var index = this.context.length - 1;\n if (this.context[index] === types$1.f_expr)\n { this.context[index] = types$1.f_expr_gen; }\n else\n { this.context[index] = types$1.f_gen; }\n }\n this.exprAllowed = true;\n};\n\ntypes.name.updateContext = function(prevType) {\n var allowed = false;\n if (this.options.ecmaVersion >= 6 && prevType !== types.dot) {\n if (this.value === \"of\" && !this.exprAllowed ||\n this.value === \"yield\" && this.inGeneratorContext())\n { allowed = true; }\n }\n this.exprAllowed = allowed;\n};\n\nvar data = {\n \"$LONE\": [\n \"ASCII\",\n \"ASCII_Hex_Digit\",\n \"AHex\",\n \"Alphabetic\",\n \"Alpha\",\n \"Any\",\n \"Assigned\",\n \"Bidi_Control\",\n \"Bidi_C\",\n \"Bidi_Mirrored\",\n \"Bidi_M\",\n \"Case_Ignorable\",\n \"CI\",\n \"Cased\",\n \"Changes_When_Casefolded\",\n \"CWCF\",\n \"Changes_When_Casemapped\",\n \"CWCM\",\n \"Changes_When_Lowercased\",\n \"CWL\",\n \"Changes_When_NFKC_Casefolded\",\n \"CWKCF\",\n \"Changes_When_Titlecased\",\n \"CWT\",\n \"Changes_When_Uppercased\",\n \"CWU\",\n \"Dash\",\n \"Default_Ignorable_Code_Point\",\n \"DI\",\n \"Deprecated\",\n \"Dep\",\n \"Diacritic\",\n \"Dia\",\n \"Emoji\",\n \"Emoji_Component\",\n \"Emoji_Modifier\",\n \"Emoji_Modifier_Base\",\n \"Emoji_Presentation\",\n \"Extender\",\n \"Ext\",\n \"Grapheme_Base\",\n \"Gr_Base\",\n \"Grapheme_Extend\",\n \"Gr_Ext\",\n \"Hex_Digit\",\n \"Hex\",\n \"IDS_Binary_Operator\",\n \"IDSB\",\n \"IDS_Trinary_Operator\",\n \"IDST\",\n \"ID_Continue\",\n \"IDC\",\n \"ID_Start\",\n \"IDS\",\n \"Ideographic\",\n \"Ideo\",\n \"Join_Control\",\n \"Join_C\",\n \"Logical_Order_Exception\",\n \"LOE\",\n \"Lowercase\",\n \"Lower\",\n \"Math\",\n \"Noncharacter_Code_Point\",\n \"NChar\",\n \"Pattern_Syntax\",\n \"Pat_Syn\",\n \"Pattern_White_Space\",\n \"Pat_WS\",\n \"Quotation_Mark\",\n \"QMark\",\n \"Radical\",\n \"Regional_Indicator\",\n \"RI\",\n \"Sentence_Terminal\",\n \"STerm\",\n \"Soft_Dotted\",\n \"SD\",\n \"Terminal_Punctuation\",\n \"Term\",\n \"Unified_Ideograph\",\n \"UIdeo\",\n \"Uppercase\",\n \"Upper\",\n \"Variation_Selector\",\n \"VS\",\n \"White_Space\",\n \"space\",\n \"XID_Continue\",\n \"XIDC\",\n \"XID_Start\",\n \"XIDS\"\n ],\n \"General_Category\": [\n \"Cased_Letter\",\n \"LC\",\n \"Close_Punctuation\",\n \"Pe\",\n \"Connector_Punctuation\",\n \"Pc\",\n \"Control\",\n \"Cc\",\n \"cntrl\",\n \"Currency_Symbol\",\n \"Sc\",\n \"Dash_Punctuation\",\n \"Pd\",\n \"Decimal_Number\",\n \"Nd\",\n \"digit\",\n \"Enclosing_Mark\",\n \"Me\",\n \"Final_Punctuation\",\n \"Pf\",\n \"Format\",\n \"Cf\",\n \"Initial_Punctuation\",\n \"Pi\",\n \"Letter\",\n \"L\",\n \"Letter_Number\",\n \"Nl\",\n \"Line_Separator\",\n \"Zl\",\n \"Lowercase_Letter\",\n \"Ll\",\n \"Mark\",\n \"M\",\n \"Combining_Mark\",\n \"Math_Symbol\",\n \"Sm\",\n \"Modifier_Letter\",\n \"Lm\",\n \"Modifier_Symbol\",\n \"Sk\",\n \"Nonspacing_Mark\",\n \"Mn\",\n \"Number\",\n \"N\",\n \"Open_Punctuation\",\n \"Ps\",\n \"Other\",\n \"C\",\n \"Other_Letter\",\n \"Lo\",\n \"Other_Number\",\n \"No\",\n \"Other_Punctuation\",\n \"Po\",\n \"Other_Symbol\",\n \"So\",\n \"Paragraph_Separator\",\n \"Zp\",\n \"Private_Use\",\n \"Co\",\n \"Punctuation\",\n \"P\",\n \"punct\",\n \"Separator\",\n \"Z\",\n \"Space_Separator\",\n \"Zs\",\n \"Spacing_Mark\",\n \"Mc\",\n \"Surrogate\",\n \"Cs\",\n \"Symbol\",\n \"S\",\n \"Titlecase_Letter\",\n \"Lt\",\n \"Unassigned\",\n \"Cn\",\n \"Uppercase_Letter\",\n \"Lu\"\n ],\n \"Script\": [\n \"Adlam\",\n \"Adlm\",\n \"Ahom\",\n \"Anatolian_Hieroglyphs\",\n \"Hluw\",\n \"Arabic\",\n \"Arab\",\n \"Armenian\",\n \"Armn\",\n \"Avestan\",\n \"Avst\",\n \"Balinese\",\n \"Bali\",\n \"Bamum\",\n \"Bamu\",\n \"Bassa_Vah\",\n \"Bass\",\n \"Batak\",\n \"Batk\",\n \"Bengali\",\n \"Beng\",\n \"Bhaiksuki\",\n \"Bhks\",\n \"Bopomofo\",\n \"Bopo\",\n \"Brahmi\",\n \"Brah\",\n \"Braille\",\n \"Brai\",\n \"Buginese\",\n \"Bugi\",\n \"Buhid\",\n \"Buhd\",\n \"Canadian_Aboriginal\",\n \"Cans\",\n \"Carian\",\n \"Cari\",\n \"Caucasian_Albanian\",\n \"Aghb\",\n \"Chakma\",\n \"Cakm\",\n \"Cham\",\n \"Cherokee\",\n \"Cher\",\n \"Common\",\n \"Zyyy\",\n \"Coptic\",\n \"Copt\",\n \"Qaac\",\n \"Cuneiform\",\n \"Xsux\",\n \"Cypriot\",\n \"Cprt\",\n \"Cyrillic\",\n \"Cyrl\",\n \"Deseret\",\n \"Dsrt\",\n \"Devanagari\",\n \"Deva\",\n \"Duployan\",\n \"Dupl\",\n \"Egyptian_Hieroglyphs\",\n \"Egyp\",\n \"Elbasan\",\n \"Elba\",\n \"Ethiopic\",\n \"Ethi\",\n \"Georgian\",\n \"Geor\",\n \"Glagolitic\",\n \"Glag\",\n \"Gothic\",\n \"Goth\",\n \"Grantha\",\n \"Gran\",\n \"Greek\",\n \"Grek\",\n \"Gujarati\",\n \"Gujr\",\n \"Gurmukhi\",\n \"Guru\",\n \"Han\",\n \"Hani\",\n \"Hangul\",\n \"Hang\",\n \"Hanunoo\",\n \"Hano\",\n \"Hatran\",\n \"Hatr\",\n \"Hebrew\",\n \"Hebr\",\n \"Hiragana\",\n \"Hira\",\n \"Imperial_Aramaic\",\n \"Armi\",\n \"Inherited\",\n \"Zinh\",\n \"Qaai\",\n \"Inscriptional_Pahlavi\",\n \"Phli\",\n \"Inscriptional_Parthian\",\n \"Prti\",\n \"Javanese\",\n \"Java\",\n \"Kaithi\",\n \"Kthi\",\n \"Kannada\",\n \"Knda\",\n \"Katakana\",\n \"Kana\",\n \"Kayah_Li\",\n \"Kali\",\n \"Kharoshthi\",\n \"Khar\",\n \"Khmer\",\n \"Khmr\",\n \"Khojki\",\n \"Khoj\",\n \"Khudawadi\",\n \"Sind\",\n \"Lao\",\n \"Laoo\",\n \"Latin\",\n \"Latn\",\n \"Lepcha\",\n \"Lepc\",\n \"Limbu\",\n \"Limb\",\n \"Linear_A\",\n \"Lina\",\n \"Linear_B\",\n \"Linb\",\n \"Lisu\",\n \"Lycian\",\n \"Lyci\",\n \"Lydian\",\n \"Lydi\",\n \"Mahajani\",\n \"Mahj\",\n \"Malayalam\",\n \"Mlym\",\n \"Mandaic\",\n \"Mand\",\n \"Manichaean\",\n \"Mani\",\n \"Marchen\",\n \"Marc\",\n \"Masaram_Gondi\",\n \"Gonm\",\n \"Meetei_Mayek\",\n \"Mtei\",\n \"Mende_Kikakui\",\n \"Mend\",\n \"Meroitic_Cursive\",\n \"Merc\",\n \"Meroitic_Hieroglyphs\",\n \"Mero\",\n \"Miao\",\n \"Plrd\",\n \"Modi\",\n \"Mongolian\",\n \"Mong\",\n \"Mro\",\n \"Mroo\",\n \"Multani\",\n \"Mult\",\n \"Myanmar\",\n \"Mymr\",\n \"Nabataean\",\n \"Nbat\",\n \"New_Tai_Lue\",\n \"Talu\",\n \"Newa\",\n \"Nko\",\n \"Nkoo\",\n \"Nushu\",\n \"Nshu\",\n \"Ogham\",\n \"Ogam\",\n \"Ol_Chiki\",\n \"Olck\",\n \"Old_Hungarian\",\n \"Hung\",\n \"Old_Italic\",\n \"Ital\",\n \"Old_North_Arabian\",\n \"Narb\",\n \"Old_Permic\",\n \"Perm\",\n \"Old_Persian\",\n \"Xpeo\",\n \"Old_South_Arabian\",\n \"Sarb\",\n \"Old_Turkic\",\n \"Orkh\",\n \"Oriya\",\n \"Orya\",\n \"Osage\",\n \"Osge\",\n \"Osmanya\",\n \"Osma\",\n \"Pahawh_Hmong\",\n \"Hmng\",\n \"Palmyrene\",\n \"Palm\",\n \"Pau_Cin_Hau\",\n \"Pauc\",\n \"Phags_Pa\",\n \"Phag\",\n \"Phoenician\",\n \"Phnx\",\n \"Psalter_Pahlavi\",\n \"Phlp\",\n \"Rejang\",\n \"Rjng\",\n \"Runic\",\n \"Runr\",\n \"Samaritan\",\n \"Samr\",\n \"Saurashtra\",\n \"Saur\",\n \"Sharada\",\n \"Shrd\",\n \"Shavian\",\n \"Shaw\",\n \"Siddham\",\n \"Sidd\",\n \"SignWriting\",\n \"Sgnw\",\n \"Sinhala\",\n \"Sinh\",\n \"Sora_Sompeng\",\n \"Sora\",\n \"Soyombo\",\n \"Soyo\",\n \"Sundanese\",\n \"Sund\",\n \"Syloti_Nagri\",\n \"Sylo\",\n \"Syriac\",\n \"Syrc\",\n \"Tagalog\",\n \"Tglg\",\n \"Tagbanwa\",\n \"Tagb\",\n \"Tai_Le\",\n \"Tale\",\n \"Tai_Tham\",\n \"Lana\",\n \"Tai_Viet\",\n \"Tavt\",\n \"Takri\",\n \"Takr\",\n \"Tamil\",\n \"Taml\",\n \"Tangut\",\n \"Tang\",\n \"Telugu\",\n \"Telu\",\n \"Thaana\",\n \"Thaa\",\n \"Thai\",\n \"Tibetan\",\n \"Tibt\",\n \"Tifinagh\",\n \"Tfng\",\n \"Tirhuta\",\n \"Tirh\",\n \"Ugaritic\",\n \"Ugar\",\n \"Vai\",\n \"Vaii\",\n \"Warang_Citi\",\n \"Wara\",\n \"Yi\",\n \"Yiii\",\n \"Zanabazar_Square\",\n \"Zanb\"\n ]\n};\nArray.prototype.push.apply(data.$LONE, data.General_Category);\ndata.gc = data.General_Category;\ndata.sc = data.Script_Extensions = data.scx = data.Script;\n\nvar pp$9 = Parser.prototype;\n\nvar RegExpValidationState = function RegExpValidationState(parser) {\n this.parser = parser;\n this.validFlags = \"gim\" + (parser.options.ecmaVersion >= 6 ? \"uy\" : \"\") + (parser.options.ecmaVersion >= 9 ? \"s\" : \"\");\n this.source = \"\";\n this.flags = \"\";\n this.start = 0;\n this.switchU = false;\n this.switchN = false;\n this.pos = 0;\n this.lastIntValue = 0;\n this.lastStringValue = \"\";\n this.lastAssertionIsQuantifiable = false;\n this.numCapturingParens = 0;\n this.maxBackReference = 0;\n this.groupNames = [];\n this.backReferenceNames = [];\n};\n\nRegExpValidationState.prototype.reset = function reset (start, pattern, flags) {\n var unicode = flags.indexOf(\"u\") !== -1;\n this.start = start | 0;\n this.source = pattern + \"\";\n this.flags = flags;\n this.switchU = unicode && this.parser.options.ecmaVersion >= 6;\n this.switchN = unicode && this.parser.options.ecmaVersion >= 9;\n};\n\nRegExpValidationState.prototype.raise = function raise (message) {\n this.parser.raiseRecoverable(this.start, (\"Invalid regular expression: /\" + (this.source) + \"/: \" + message));\n};\n\n// If u flag is given, this returns the code point at the index (it combines a surrogate pair).\n// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).\nRegExpValidationState.prototype.at = function at (i) {\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return -1\n }\n var c = s.charCodeAt(i);\n if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {\n return c\n }\n return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00\n};\n\nRegExpValidationState.prototype.nextIndex = function nextIndex (i) {\n var s = this.source;\n var l = s.length;\n if (i >= l) {\n return l\n }\n var c = s.charCodeAt(i);\n if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {\n return i + 1\n }\n return i + 2\n};\n\nRegExpValidationState.prototype.current = function current () {\n return this.at(this.pos)\n};\n\nRegExpValidationState.prototype.lookahead = function lookahead () {\n return this.at(this.nextIndex(this.pos))\n};\n\nRegExpValidationState.prototype.advance = function advance () {\n this.pos = this.nextIndex(this.pos);\n};\n\nRegExpValidationState.prototype.eat = function eat (ch) {\n if (this.current() === ch) {\n this.advance();\n return true\n }\n return false\n};\n\nfunction codePointToString$1(ch) {\n if (ch <= 0xFFFF) { return String.fromCharCode(ch) }\n ch -= 0x10000;\n return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)\n}\n\n/**\n * Validate the flags part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$9.validateRegExpFlags = function(state) {\n var this$1 = this;\n\n var validFlags = state.validFlags;\n var flags = state.flags;\n\n for (var i = 0; i < flags.length; i++) {\n var flag = flags.charAt(i);\n if (validFlags.indexOf(flag) === -1) {\n this$1.raise(state.start, \"Invalid regular expression flag\");\n }\n if (flags.indexOf(flag, i + 1) > -1) {\n this$1.raise(state.start, \"Duplicate regular expression flag\");\n }\n }\n};\n\n/**\n * Validate the pattern part of a given RegExpLiteral.\n *\n * @param {RegExpValidationState} state The state to validate RegExp.\n * @returns {void}\n */\npp$9.validateRegExpPattern = function(state) {\n this.regexp_pattern(state);\n\n // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of\n // parsing contains a |GroupName|, reparse with the goal symbol\n // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*\n // exception if _P_ did not conform to the grammar, if any elements of _P_\n // were not matched by the parse, or if any Early Error conditions exist.\n if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {\n state.switchN = true;\n this.regexp_pattern(state);\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern\npp$9.regexp_pattern = function(state) {\n state.pos = 0;\n state.lastIntValue = 0;\n state.lastStringValue = \"\";\n state.lastAssertionIsQuantifiable = false;\n state.numCapturingParens = 0;\n state.maxBackReference = 0;\n state.groupNames.length = 0;\n state.backReferenceNames.length = 0;\n\n this.regexp_disjunction(state);\n\n if (state.pos !== state.source.length) {\n // Make the same messages as V8.\n if (state.eat(0x29 /* ) */)) {\n state.raise(\"Unmatched ')'\");\n }\n if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n }\n if (state.maxBackReference > state.numCapturingParens) {\n state.raise(\"Invalid escape\");\n }\n for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {\n var name = list[i];\n\n if (state.groupNames.indexOf(name) === -1) {\n state.raise(\"Invalid named capture referenced\");\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction\npp$9.regexp_disjunction = function(state) {\n var this$1 = this;\n\n this.regexp_alternative(state);\n while (state.eat(0x7C /* | */)) {\n this$1.regexp_alternative(state);\n }\n\n // Make the same message as V8.\n if (this.regexp_eatQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n if (state.eat(0x7B /* { */)) {\n state.raise(\"Lone quantifier brackets\");\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative\npp$9.regexp_alternative = function(state) {\n while (state.pos < state.source.length && this.regexp_eatTerm(state))\n { }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term\npp$9.regexp_eatTerm = function(state) {\n if (this.regexp_eatAssertion(state)) {\n // Handle `QuantifiableAssertion Quantifier` alternative.\n // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion\n // is a QuantifiableAssertion.\n if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {\n // Make the same message as V8.\n if (state.switchU) {\n state.raise(\"Invalid quantifier\");\n }\n }\n return true\n }\n\n if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {\n this.regexp_eatQuantifier(state);\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion\npp$9.regexp_eatAssertion = function(state) {\n var start = state.pos;\n state.lastAssertionIsQuantifiable = false;\n\n // ^, $\n if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {\n return true\n }\n\n // \\b \\B\n if (state.eat(0x5C /* \\ */)) {\n if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {\n return true\n }\n state.pos = start;\n }\n\n // Lookahead / Lookbehind\n if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {\n var lookbehind = false;\n if (this.options.ecmaVersion >= 9) {\n lookbehind = state.eat(0x3C /* < */);\n }\n if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {\n this.regexp_disjunction(state);\n if (!state.eat(0x29 /* ) */)) {\n state.raise(\"Unterminated group\");\n }\n state.lastAssertionIsQuantifiable = !lookbehind;\n return true\n }\n }\n\n state.pos = start;\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier\npp$9.regexp_eatQuantifier = function(state, noError) {\n if ( noError === void 0 ) noError = false;\n\n if (this.regexp_eatQuantifierPrefix(state, noError)) {\n state.eat(0x3F /* ? */);\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix\npp$9.regexp_eatQuantifierPrefix = function(state, noError) {\n return (\n state.eat(0x2A /* * */) ||\n state.eat(0x2B /* + */) ||\n state.eat(0x3F /* ? */) ||\n this.regexp_eatBracedQuantifier(state, noError)\n )\n};\npp$9.regexp_eatBracedQuantifier = function(state, noError) {\n var start = state.pos;\n if (state.eat(0x7B /* { */)) {\n var min = 0, max = -1;\n if (this.regexp_eatDecimalDigits(state)) {\n min = state.lastIntValue;\n if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {\n max = state.lastIntValue;\n }\n if (state.eat(0x7D /* } */)) {\n // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term\n if (max !== -1 && max < min && !noError) {\n state.raise(\"numbers out of order in {} quantifier\");\n }\n return true\n }\n }\n if (state.switchU && !noError) {\n state.raise(\"Incomplete quantifier\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom\npp$9.regexp_eatAtom = function(state) {\n return (\n this.regexp_eatPatternCharacters(state) ||\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state)\n )\n};\npp$9.regexp_eatReverseSolidusAtomEscape = function(state) {\n var start = state.pos;\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatAtomEscape(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatUncapturingGroup = function(state) {\n var start = state.pos;\n if (state.eat(0x28 /* ( */)) {\n if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n return true\n }\n state.raise(\"Unterminated group\");\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatCapturingGroup = function(state) {\n if (state.eat(0x28 /* ( */)) {\n if (this.options.ecmaVersion >= 9) {\n this.regexp_groupSpecifier(state);\n } else if (state.current() === 0x3F /* ? */) {\n state.raise(\"Invalid group\");\n }\n this.regexp_disjunction(state);\n if (state.eat(0x29 /* ) */)) {\n state.numCapturingParens += 1;\n return true\n }\n state.raise(\"Unterminated group\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom\npp$9.regexp_eatExtendedAtom = function(state) {\n return (\n state.eat(0x2E /* . */) ||\n this.regexp_eatReverseSolidusAtomEscape(state) ||\n this.regexp_eatCharacterClass(state) ||\n this.regexp_eatUncapturingGroup(state) ||\n this.regexp_eatCapturingGroup(state) ||\n this.regexp_eatInvalidBracedQuantifier(state) ||\n this.regexp_eatExtendedPatternCharacter(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier\npp$9.regexp_eatInvalidBracedQuantifier = function(state) {\n if (this.regexp_eatBracedQuantifier(state, true)) {\n state.raise(\"Nothing to repeat\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter\npp$9.regexp_eatSyntaxCharacter = function(state) {\n var ch = state.current();\n if (isSyntaxCharacter(ch)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n return false\n};\nfunction isSyntaxCharacter(ch) {\n return (\n ch === 0x24 /* $ */ ||\n ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||\n ch === 0x2E /* . */ ||\n ch === 0x3F /* ? */ ||\n ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||\n ch >= 0x7B /* { */ && ch <= 0x7D /* } */\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter\n// But eat eager.\npp$9.regexp_eatPatternCharacters = function(state) {\n var start = state.pos;\n var ch = 0;\n while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {\n state.advance();\n }\n return state.pos !== start\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter\npp$9.regexp_eatExtendedPatternCharacter = function(state) {\n var ch = state.current();\n if (\n ch !== -1 &&\n ch !== 0x24 /* $ */ &&\n !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&\n ch !== 0x2E /* . */ &&\n ch !== 0x3F /* ? */ &&\n ch !== 0x5B /* [ */ &&\n ch !== 0x5E /* ^ */ &&\n ch !== 0x7C /* | */\n ) {\n state.advance();\n return true\n }\n return false\n};\n\n// GroupSpecifier[U] ::\n// [empty]\n// `?` GroupName[?U]\npp$9.regexp_groupSpecifier = function(state) {\n if (state.eat(0x3F /* ? */)) {\n if (this.regexp_eatGroupName(state)) {\n if (state.groupNames.indexOf(state.lastStringValue) !== -1) {\n state.raise(\"Duplicate capture group name\");\n }\n state.groupNames.push(state.lastStringValue);\n return\n }\n state.raise(\"Invalid group\");\n }\n};\n\n// GroupName[U] ::\n// `<` RegExpIdentifierName[?U] `>`\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$9.regexp_eatGroupName = function(state) {\n state.lastStringValue = \"\";\n if (state.eat(0x3C /* < */)) {\n if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {\n return true\n }\n state.raise(\"Invalid capture group name\");\n }\n return false\n};\n\n// RegExpIdentifierName[U] ::\n// RegExpIdentifierStart[?U]\n// RegExpIdentifierName[?U] RegExpIdentifierPart[?U]\n// Note: this updates `state.lastStringValue` property with the eaten name.\npp$9.regexp_eatRegExpIdentifierName = function(state) {\n state.lastStringValue = \"\";\n if (this.regexp_eatRegExpIdentifierStart(state)) {\n state.lastStringValue += codePointToString$1(state.lastIntValue);\n while (this.regexp_eatRegExpIdentifierPart(state)) {\n state.lastStringValue += codePointToString$1(state.lastIntValue);\n }\n return true\n }\n return false\n};\n\n// RegExpIdentifierStart[U] ::\n// UnicodeIDStart\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[?U]\npp$9.regexp_eatRegExpIdentifierStart = function(state) {\n var start = state.pos;\n var ch = state.current();\n state.advance();\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierStart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierStart(ch) {\n return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */\n}\n\n// RegExpIdentifierPart[U] ::\n// UnicodeIDContinue\n// `$`\n// `_`\n// `\\` RegExpUnicodeEscapeSequence[?U]\n// \n// \npp$9.regexp_eatRegExpIdentifierPart = function(state) {\n var start = state.pos;\n var ch = state.current();\n state.advance();\n\n if (ch === 0x5C /* \\ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {\n ch = state.lastIntValue;\n }\n if (isRegExpIdentifierPart(ch)) {\n state.lastIntValue = ch;\n return true\n }\n\n state.pos = start;\n return false\n};\nfunction isRegExpIdentifierPart(ch) {\n return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* */ || ch === 0x200D /* */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape\npp$9.regexp_eatAtomEscape = function(state) {\n if (\n this.regexp_eatBackReference(state) ||\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state) ||\n (state.switchN && this.regexp_eatKGroupName(state))\n ) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n if (state.current() === 0x63 /* c */) {\n state.raise(\"Invalid unicode escape\");\n }\n state.raise(\"Invalid escape\");\n }\n return false\n};\npp$9.regexp_eatBackReference = function(state) {\n var start = state.pos;\n if (this.regexp_eatDecimalEscape(state)) {\n var n = state.lastIntValue;\n if (state.switchU) {\n // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape\n if (n > state.maxBackReference) {\n state.maxBackReference = n;\n }\n return true\n }\n if (n <= state.numCapturingParens) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatKGroupName = function(state) {\n if (state.eat(0x6B /* k */)) {\n if (this.regexp_eatGroupName(state)) {\n state.backReferenceNames.push(state.lastStringValue);\n return true\n }\n state.raise(\"Invalid named reference\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape\npp$9.regexp_eatCharacterEscape = function(state) {\n return (\n this.regexp_eatControlEscape(state) ||\n this.regexp_eatCControlLetter(state) ||\n this.regexp_eatZero(state) ||\n this.regexp_eatHexEscapeSequence(state) ||\n this.regexp_eatRegExpUnicodeEscapeSequence(state) ||\n (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||\n this.regexp_eatIdentityEscape(state)\n )\n};\npp$9.regexp_eatCControlLetter = function(state) {\n var start = state.pos;\n if (state.eat(0x63 /* c */)) {\n if (this.regexp_eatControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n return false\n};\npp$9.regexp_eatZero = function(state) {\n if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {\n state.lastIntValue = 0;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape\npp$9.regexp_eatControlEscape = function(state) {\n var ch = state.current();\n if (ch === 0x74 /* t */) {\n state.lastIntValue = 0x09; /* \\t */\n state.advance();\n return true\n }\n if (ch === 0x6E /* n */) {\n state.lastIntValue = 0x0A; /* \\n */\n state.advance();\n return true\n }\n if (ch === 0x76 /* v */) {\n state.lastIntValue = 0x0B; /* \\v */\n state.advance();\n return true\n }\n if (ch === 0x66 /* f */) {\n state.lastIntValue = 0x0C; /* \\f */\n state.advance();\n return true\n }\n if (ch === 0x72 /* r */) {\n state.lastIntValue = 0x0D; /* \\r */\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter\npp$9.regexp_eatControlLetter = function(state) {\n var ch = state.current();\n if (isControlLetter(ch)) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\nfunction isControlLetter(ch) {\n return (\n (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||\n (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)\n )\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence\npp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) {\n var start = state.pos;\n\n if (state.eat(0x75 /* u */)) {\n if (this.regexp_eatFixedHexDigits(state, 4)) {\n var lead = state.lastIntValue;\n if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) {\n var leadSurrogateEnd = state.pos;\n if (state.eat(0x5C /* \\ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {\n var trail = state.lastIntValue;\n if (trail >= 0xDC00 && trail <= 0xDFFF) {\n state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;\n return true\n }\n }\n state.pos = leadSurrogateEnd;\n state.lastIntValue = lead;\n }\n return true\n }\n if (\n state.switchU &&\n state.eat(0x7B /* { */) &&\n this.regexp_eatHexDigits(state) &&\n state.eat(0x7D /* } */) &&\n isValidUnicode(state.lastIntValue)\n ) {\n return true\n }\n if (state.switchU) {\n state.raise(\"Invalid unicode escape\");\n }\n state.pos = start;\n }\n\n return false\n};\nfunction isValidUnicode(ch) {\n return ch >= 0 && ch <= 0x10FFFF\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape\npp$9.regexp_eatIdentityEscape = function(state) {\n if (state.switchU) {\n if (this.regexp_eatSyntaxCharacter(state)) {\n return true\n }\n if (state.eat(0x2F /* / */)) {\n state.lastIntValue = 0x2F; /* / */\n return true\n }\n return false\n }\n\n var ch = state.current();\n if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape\npp$9.regexp_eatDecimalEscape = function(state) {\n state.lastIntValue = 0;\n var ch = state.current();\n if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {\n do {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape\npp$9.regexp_eatCharacterClassEscape = function(state) {\n var ch = state.current();\n\n if (isCharacterClassEscape(ch)) {\n state.lastIntValue = -1;\n state.advance();\n return true\n }\n\n if (\n state.switchU &&\n this.options.ecmaVersion >= 9 &&\n (ch === 0x50 /* P */ || ch === 0x70 /* p */)\n ) {\n state.lastIntValue = -1;\n state.advance();\n if (\n state.eat(0x7B /* { */) &&\n this.regexp_eatUnicodePropertyValueExpression(state) &&\n state.eat(0x7D /* } */)\n ) {\n return true\n }\n state.raise(\"Invalid property name\");\n }\n\n return false\n};\nfunction isCharacterClassEscape(ch) {\n return (\n ch === 0x64 /* d */ ||\n ch === 0x44 /* D */ ||\n ch === 0x73 /* s */ ||\n ch === 0x53 /* S */ ||\n ch === 0x77 /* w */ ||\n ch === 0x57 /* W */\n )\n}\n\n// UnicodePropertyValueExpression ::\n// UnicodePropertyName `=` UnicodePropertyValue\n// LoneUnicodePropertyNameOrValue\npp$9.regexp_eatUnicodePropertyValueExpression = function(state) {\n var start = state.pos;\n\n // UnicodePropertyName `=` UnicodePropertyValue\n if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {\n var name = state.lastStringValue;\n if (this.regexp_eatUnicodePropertyValue(state)) {\n var value = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameAndValue(state, name, value);\n return true\n }\n }\n state.pos = start;\n\n // LoneUnicodePropertyNameOrValue\n if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {\n var nameOrValue = state.lastStringValue;\n this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);\n return true\n }\n return false\n};\npp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {\n if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) {\n state.raise(\"Invalid property name\");\n }\n};\npp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {\n if (data.$LONE.indexOf(nameOrValue) === -1) {\n state.raise(\"Invalid property name\");\n }\n};\n\n// UnicodePropertyName ::\n// UnicodePropertyNameCharacters\npp$9.regexp_eatUnicodePropertyName = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyNameCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString$1(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyNameCharacter(ch) {\n return isControlLetter(ch) || ch === 0x5F /* _ */\n}\n\n// UnicodePropertyValue ::\n// UnicodePropertyValueCharacters\npp$9.regexp_eatUnicodePropertyValue = function(state) {\n var ch = 0;\n state.lastStringValue = \"\";\n while (isUnicodePropertyValueCharacter(ch = state.current())) {\n state.lastStringValue += codePointToString$1(ch);\n state.advance();\n }\n return state.lastStringValue !== \"\"\n};\nfunction isUnicodePropertyValueCharacter(ch) {\n return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)\n}\n\n// LoneUnicodePropertyNameOrValue ::\n// UnicodePropertyValueCharacters\npp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {\n return this.regexp_eatUnicodePropertyValue(state)\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass\npp$9.regexp_eatCharacterClass = function(state) {\n if (state.eat(0x5B /* [ */)) {\n state.eat(0x5E /* ^ */);\n this.regexp_classRanges(state);\n if (state.eat(0x5D /* [ */)) {\n return true\n }\n // Unreachable since it threw \"unterminated regular expression\" error before.\n state.raise(\"Unterminated character class\");\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges\n// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash\npp$9.regexp_classRanges = function(state) {\n var this$1 = this;\n\n while (this.regexp_eatClassAtom(state)) {\n var left = state.lastIntValue;\n if (state.eat(0x2D /* - */) && this$1.regexp_eatClassAtom(state)) {\n var right = state.lastIntValue;\n if (state.switchU && (left === -1 || right === -1)) {\n state.raise(\"Invalid character class\");\n }\n if (left !== -1 && right !== -1 && left > right) {\n state.raise(\"Range out of order in character class\");\n }\n }\n }\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom\n// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash\npp$9.regexp_eatClassAtom = function(state) {\n var start = state.pos;\n\n if (state.eat(0x5C /* \\ */)) {\n if (this.regexp_eatClassEscape(state)) {\n return true\n }\n if (state.switchU) {\n // Make the same message as V8.\n var ch$1 = state.current();\n if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {\n state.raise(\"Invalid class escape\");\n }\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n\n var ch = state.current();\n if (ch !== 0x5D /* [ */) {\n state.lastIntValue = ch;\n state.advance();\n return true\n }\n\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape\npp$9.regexp_eatClassEscape = function(state) {\n var start = state.pos;\n\n if (state.eat(0x62 /* b */)) {\n state.lastIntValue = 0x08; /* */\n return true\n }\n\n if (state.switchU && state.eat(0x2D /* - */)) {\n state.lastIntValue = 0x2D; /* - */\n return true\n }\n\n if (!state.switchU && state.eat(0x63 /* c */)) {\n if (this.regexp_eatClassControlLetter(state)) {\n return true\n }\n state.pos = start;\n }\n\n return (\n this.regexp_eatCharacterClassEscape(state) ||\n this.regexp_eatCharacterEscape(state)\n )\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter\npp$9.regexp_eatClassControlLetter = function(state) {\n var ch = state.current();\n if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {\n state.lastIntValue = ch % 0x20;\n state.advance();\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$9.regexp_eatHexEscapeSequence = function(state) {\n var start = state.pos;\n if (state.eat(0x78 /* x */)) {\n if (this.regexp_eatFixedHexDigits(state, 2)) {\n return true\n }\n if (state.switchU) {\n state.raise(\"Invalid escape\");\n }\n state.pos = start;\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits\npp$9.regexp_eatDecimalDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isDecimalDigit(ch = state.current())) {\n state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isDecimalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits\npp$9.regexp_eatHexDigits = function(state) {\n var start = state.pos;\n var ch = 0;\n state.lastIntValue = 0;\n while (isHexDigit(ch = state.current())) {\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return state.pos !== start\n};\nfunction isHexDigit(ch) {\n return (\n (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||\n (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||\n (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)\n )\n}\nfunction hexToInt(ch) {\n if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {\n return 10 + (ch - 0x41 /* A */)\n }\n if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {\n return 10 + (ch - 0x61 /* a */)\n }\n return ch - 0x30 /* 0 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence\n// Allows only 0-377(octal) i.e. 0-255(decimal).\npp$9.regexp_eatLegacyOctalEscapeSequence = function(state) {\n if (this.regexp_eatOctalDigit(state)) {\n var n1 = state.lastIntValue;\n if (this.regexp_eatOctalDigit(state)) {\n var n2 = state.lastIntValue;\n if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {\n state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;\n } else {\n state.lastIntValue = n1 * 8 + n2;\n }\n } else {\n state.lastIntValue = n1;\n }\n return true\n }\n return false\n};\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit\npp$9.regexp_eatOctalDigit = function(state) {\n var ch = state.current();\n if (isOctalDigit(ch)) {\n state.lastIntValue = ch - 0x30; /* 0 */\n state.advance();\n return true\n }\n state.lastIntValue = 0;\n return false\n};\nfunction isOctalDigit(ch) {\n return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */\n}\n\n// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits\n// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit\n// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence\npp$9.regexp_eatFixedHexDigits = function(state, length) {\n var start = state.pos;\n state.lastIntValue = 0;\n for (var i = 0; i < length; ++i) {\n var ch = state.current();\n if (!isHexDigit(ch)) {\n state.pos = start;\n return false\n }\n state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);\n state.advance();\n }\n return true\n};\n\n// Object type used to represent tokens. Note that normally, tokens\n// simply exist as properties on the parser object. This is only\n// used for the onToken callback and the external tokenizer.\n\nvar Token = function Token(p) {\n this.type = p.type;\n this.value = p.value;\n this.start = p.start;\n this.end = p.end;\n if (p.options.locations)\n { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }\n if (p.options.ranges)\n { this.range = [p.start, p.end]; }\n};\n\n// ## Tokenizer\n\nvar pp$8 = Parser.prototype;\n\n// Move to the next token\n\npp$8.next = function() {\n if (this.options.onToken)\n { this.options.onToken(new Token(this)); }\n\n this.lastTokEnd = this.end;\n this.lastTokStart = this.start;\n this.lastTokEndLoc = this.endLoc;\n this.lastTokStartLoc = this.startLoc;\n this.nextToken();\n};\n\npp$8.getToken = function() {\n this.next();\n return new Token(this)\n};\n\n// If we're in an ES6 environment, make parsers iterable\nif (typeof Symbol !== \"undefined\")\n { pp$8[Symbol.iterator] = function() {\n var this$1 = this;\n\n return {\n next: function () {\n var token = this$1.getToken();\n return {\n done: token.type === types.eof,\n value: token\n }\n }\n }\n }; }\n\n// Toggle strict mode. Re-reads the next number or string to please\n// pedantic tests (`\"use strict\"; 010;` should fail).\n\npp$8.curContext = function() {\n return this.context[this.context.length - 1]\n};\n\n// Read a single token, updating the parser object's token-related\n// properties.\n\npp$8.nextToken = function() {\n var curContext = this.curContext();\n if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }\n\n this.start = this.pos;\n if (this.options.locations) { this.startLoc = this.curPosition(); }\n if (this.pos >= this.input.length) { return this.finishToken(types.eof) }\n\n if (curContext.override) { return curContext.override(this) }\n else { this.readToken(this.fullCharCodeAtPos()); }\n};\n\npp$8.readToken = function(code) {\n // Identifier or keyword. '\\uXXXX' sequences are allowed in\n // identifiers, so '\\' also dispatches to that.\n if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\\' */)\n { return this.readWord() }\n\n return this.getTokenFromCode(code)\n};\n\npp$8.fullCharCodeAtPos = function() {\n var code = this.input.charCodeAt(this.pos);\n if (code <= 0xd7ff || code >= 0xe000) { return code }\n var next = this.input.charCodeAt(this.pos + 1);\n return (code << 10) + next - 0x35fdc00\n};\n\npp$8.skipBlockComment = function() {\n var this$1 = this;\n\n var startLoc = this.options.onComment && this.curPosition();\n var start = this.pos, end = this.input.indexOf(\"*/\", this.pos += 2);\n if (end === -1) { this.raise(this.pos - 2, \"Unterminated comment\"); }\n this.pos = end + 2;\n if (this.options.locations) {\n lineBreakG.lastIndex = start;\n var match;\n while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {\n ++this$1.curLine;\n this$1.lineStart = match.index + match[0].length;\n }\n }\n if (this.options.onComment)\n { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\npp$8.skipLineComment = function(startSkip) {\n var this$1 = this;\n\n var start = this.pos;\n var startLoc = this.options.onComment && this.curPosition();\n var ch = this.input.charCodeAt(this.pos += startSkip);\n while (this.pos < this.input.length && !isNewLine(ch)) {\n ch = this$1.input.charCodeAt(++this$1.pos);\n }\n if (this.options.onComment)\n { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,\n startLoc, this.curPosition()); }\n};\n\n// Called at the start of the parse and after every token. Skips\n// whitespace and comments, and.\n\npp$8.skipSpace = function() {\n var this$1 = this;\n\n loop: while (this.pos < this.input.length) {\n var ch = this$1.input.charCodeAt(this$1.pos);\n switch (ch) {\n case 32: case 160: // ' '\n ++this$1.pos;\n break\n case 13:\n if (this$1.input.charCodeAt(this$1.pos + 1) === 10) {\n ++this$1.pos;\n }\n case 10: case 8232: case 8233:\n ++this$1.pos;\n if (this$1.options.locations) {\n ++this$1.curLine;\n this$1.lineStart = this$1.pos;\n }\n break\n case 47: // '/'\n switch (this$1.input.charCodeAt(this$1.pos + 1)) {\n case 42: // '*'\n this$1.skipBlockComment();\n break\n case 47:\n this$1.skipLineComment(2);\n break\n default:\n break loop\n }\n break\n default:\n if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {\n ++this$1.pos;\n } else {\n break loop\n }\n }\n }\n};\n\n// Called at the end of every token. Sets `end`, `val`, and\n// maintains `context` and `exprAllowed`, and skips the space after\n// the token, so that the next one's `start` will point at the\n// right position.\n\npp$8.finishToken = function(type, val) {\n this.end = this.pos;\n if (this.options.locations) { this.endLoc = this.curPosition(); }\n var prevType = this.type;\n this.type = type;\n this.value = val;\n\n this.updateContext(prevType);\n};\n\n// ### Token reading\n\n// This is the function that is called to fetch the next token. It\n// is somewhat obscure, because it works in character codes rather\n// than characters, and because operator parsing has been inlined\n// into it.\n//\n// All in the name of speed.\n//\npp$8.readToken_dot = function() {\n var next = this.input.charCodeAt(this.pos + 1);\n if (next >= 48 && next <= 57) { return this.readNumber(true) }\n var next2 = this.input.charCodeAt(this.pos + 2);\n if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'\n this.pos += 3;\n return this.finishToken(types.ellipsis)\n } else {\n ++this.pos;\n return this.finishToken(types.dot)\n }\n};\n\npp$8.readToken_slash = function() { // '/'\n var next = this.input.charCodeAt(this.pos + 1);\n if (this.exprAllowed) { ++this.pos; return this.readRegexp() }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.slash, 1)\n};\n\npp$8.readToken_mult_modulo_exp = function(code) { // '%*'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n var tokentype = code === 42 ? types.star : types.modulo;\n\n // exponentiation operator ** and **=\n if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {\n ++size;\n tokentype = types.starstar;\n next = this.input.charCodeAt(this.pos + 2);\n }\n\n if (next === 61) { return this.finishOp(types.assign, size + 1) }\n return this.finishOp(tokentype, size)\n};\n\npp$8.readToken_pipe_amp = function(code) { // '|&'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)\n};\n\npp$8.readToken_caret = function() { // '^'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.bitwiseXOR, 1)\n};\n\npp$8.readToken_plus_min = function(code) { // '+-'\n var next = this.input.charCodeAt(this.pos + 1);\n if (next === code) {\n if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&\n (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {\n // A `-->` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.plusMin, 1)\n};\n\npp$8.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }\n return this.finishOp(types.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `` line comment\n this.skipLineComment(3);\n this.skipSpace();\n return this.nextToken()\n }\n return this.finishOp(types.incDec, 2)\n }\n if (next === 61) { return this.finishOp(types.assign, 2) }\n return this.finishOp(types.plusMin, 1)\n};\n\npp$8.readToken_lt_gt = function(code) { // '<>'\n var next = this.input.charCodeAt(this.pos + 1);\n var size = 1;\n if (next === code) {\n size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;\n if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }\n return this.finishOp(types.bitShift, size)\n }\n if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&\n this.input.charCodeAt(this.pos + 3) === 45) {\n // `\n'; - const files = readDirDeepSync(rootPath, { - patterns: [ - '**/*.js' - ], - ignore: [ - '*.js' - ] - }) - .map(file => file.replace(/^test\//, '')); - return gulp.src(`${folder}/all-template.html`) - .pipe(replace('{{test-files}}', warning + files.map(file => ``).join('\n'))) - .pipe(rename(testFile)) - .pipe(gulp.dest(folder)); -}); - -gulp.task('make', gulp.series('build', 'beautify', 'minify', 'build-tests')); - diff --git a/package-lock.json b/package-lock.json index ef8e266d..7f2c6ed4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8573 +1,5381 @@ -{ - "name": "gpu.js", - "version": "2.0.4", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@nodelib/fs.scandir": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz", - "integrity": "sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.1", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz", - "integrity": "sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz", - "integrity": "sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.1", - "fastq": "^1.6.0" - } - }, - "@sinonjs/commons": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", - "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/formatio": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", - "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "@sinonjs/samsam": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.2.tgz", - "integrity": "sha512-ILO/rR8LfAb60Y1Yfp9vxfYAASK43NFC2mLzpvLUbCQY/Qu8YwReboseu8aheCEkyElZF2L2T9mHcR2bgdvZyA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.0.2", - "array-from": "^2.1.1", - "lodash": "^4.17.11" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", - "dev": true - }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "12.6.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", - "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==", - "dev": true - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" - }, - "acorn-dynamic-import": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", - "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", - "dev": true - }, - "acorn-node": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.7.0.tgz", - "integrity": "sha512-XhahLSsCB6X6CJbe+uNu3Mn9sJBNFxtBN9NLgAOQovfS6Kh0lDUtmlclhjn9CvEK7A7YyRU13PXlNcpSiLI9Yw==", - "dev": true, - "requires": { - "acorn": "^6.1.1", - "acorn-dynamic-import": "^4.0.0", - "acorn-walk": "^6.1.1", - "xtend": "^4.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", - "dev": true - } - } - }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", - "dev": true - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-filter": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", - "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", - "dev": true - }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", - "dev": true - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-map": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", - "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", - "dev": true - }, - "array-reduce": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", - "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", - "dev": true - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-each-series": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", - "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=", - "dev": true - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", - "dev": true, - "requires": { - "async-done": "^1.2.2" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" - }, - "axios": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", - "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", - "dev": true, - "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", - "dev": true - } - } - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", - "dev": true, - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "benchmark": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", - "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", - "dev": true, - "requires": { - "lodash": "^4.17.4", - "platform": "^1.3.3" - } - }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "binaryextensions": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.1.2.tgz", - "integrity": "sha512-xVNN69YGDghOqCCtA6FI7avYrr02mTJjOgB0/f1VPD3pJC8QEvjTKWc4epDx8AqxxA75NI0QpVM2gPJXUbE4Tg==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bit-twiddle": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", - "integrity": "sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4=" - }, - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-pack": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", - "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "dev": true, - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } - } - }, - "browser-sync": { - "version": "2.26.7", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.7.tgz", - "integrity": "sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w==", - "dev": true, - "requires": { - "browser-sync-client": "^2.26.6", - "browser-sync-ui": "^2.26.4", - "bs-recipes": "1.3.4", - "bs-snippet-injector": "^2.0.1", - "chokidar": "^2.0.4", - "connect": "3.6.6", - "connect-history-api-fallback": "^1", - "dev-ip": "^1.0.1", - "easy-extender": "^2.3.4", - "eazy-logger": "^3", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "3.0.1", - "http-proxy": "1.15.2", - "immutable": "^3", - "localtunnel": "1.9.2", - "micromatch": "^3.1.10", - "opn": "5.3.0", - "portscanner": "2.1.1", - "qs": "6.2.3", - "raw-body": "^2.3.2", - "resp-modifier": "6.0.2", - "rx": "4.1.0", - "send": "0.16.2", - "serve-index": "1.9.1", - "serve-static": "1.13.2", - "server-destroy": "1.0.1", - "socket.io": "2.1.1", - "ua-parser-js": "0.7.17", - "yargs": "6.4.0" - }, - "dependencies": { - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", - "dev": true - } - } - }, - "browser-sync-client": { - "version": "2.26.6", - "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.6.tgz", - "integrity": "sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw==", - "dev": true, - "requires": { - "etag": "1.8.1", - "fresh": "0.5.2", - "mitt": "^1.1.3", - "rxjs": "^5.5.6" - } - }, - "browser-sync-ui": { - "version": "2.26.4", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz", - "integrity": "sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA==", - "dev": true, - "requires": { - "async-each-series": "0.1.1", - "connect-history-api-fallback": "^1", - "immutable": "^3", - "server-destroy": "1.0.1", - "socket.io-client": "^2.0.4", - "stream-throttle": "^0.1.3" - } - }, - "browserify": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.3.0.tgz", - "integrity": "sha512-BWaaD7alyGZVEBBwSTYx4iJF5DswIGzK17o8ai9w4iKRbYpk3EOiprRHMRRA8DCZFmFeOdx7A385w2XdFvxWmg==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^1.11.0", - "browserify-zlib": "~0.2.0", - "buffer": "^5.0.2", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.0.0", - "labeled-stream-splicer": "^2.0.0", - "mkdirp": "^0.5.0", - "module-deps": "^6.0.0", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^2.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", - "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "bs-recipes": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", - "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", - "dev": true - }, - "bs-snippet-injector": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz", - "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=", - "dev": true - }, - "buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cached-path-relative": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", - "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", - "dev": true - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chokidar": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", - "dev": true, - "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "config-chain": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", - "dev": true - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-props": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", - "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", - "dev": true, - "requires": { - "each-props": "^1.3.0", - "is-plain-object": "^2.0.1" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dash-ast": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", - "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", - "dev": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "decomment": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/decomment/-/decomment-0.9.2.tgz", - "integrity": "sha512-sblyUmOJZxiL7oJ2ogJS6jtl/67+CTOW87SrYE/96u3PhDYikYoLCdLzcnceToiQejOLlqNnLCkaxx/+nE/ehg==", - "dev": true, - "requires": { - "esprima": "4.0.1" - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "deps-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", - "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "shasum": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" - }, - "detective": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", - "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", - "dev": true, - "requires": { - "acorn-node": "^1.6.1", - "defined": "^1.0.0", - "minimist": "^1.1.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "dev-ip": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", - "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - }, - "dependencies": { - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "easy-extender": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz", - "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "eazy-logger": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz", - "integrity": "sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=", - "dev": true, - "requires": { - "tfunk": "^3.0.1" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "editions": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz", - "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==", - "dev": true - }, - "editorconfig": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", - "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", - "dev": true, - "requires": { - "commander": "^2.19.0", - "lru-cache": "^4.1.5", - "semver": "^5.6.0", - "sigmund": "^1.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "elliptic": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", - "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", - "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "ws": "~3.3.1" - }, - "dependencies": { - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "engine.io-client": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", - "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~6.1.0", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - } - }, - "engine.io-parser": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", - "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.5", - "has-binary2": "~1.0.2" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es5-ext": { - "version": "0.10.50", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.50.tgz", - "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.1", - "next-tick": "^1.0.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", - "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", - "dev": true - }, - "events": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz", - "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.1", - "@nodelib/fs.walk": "^1.2.1", - "glob-parent": "^5.0.0", - "is-glob": "^4.0.1", - "merge2": "^1.2.3", - "micromatch": "^4.0.2" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", - "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fastq": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", - "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", - "dev": true, - "requires": { - "reusify": "^1.0.0" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" - }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" - } - }, - "fs-minipass": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", - "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", - "requires": { - "minipass": "^2.2.1" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "get-assigned-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", - "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" - }, - "gl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/gl/-/gl-4.4.0.tgz", - "integrity": "sha512-4FIq5tqiltTsadrLh6DGY4R9+aQwj25OM2WlXEv81N6YN1q1C0qR7ct0SKp1uUJdnBqbKhUJP3zQ1td40AVeJg==", - "requires": { - "bindings": "^1.5.0", - "bit-twiddle": "^1.0.2", - "glsl-tokenizer": "^2.0.2", - "nan": "^2.14.0", - "node-gyp": "^4.0.0", - "prebuild-install": "^5.1.0" - } - }, - "gl-wiretap": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/gl-wiretap/-/gl-wiretap-0.6.2.tgz", - "integrity": "sha512-fxy1XGiPkfzK+T3XKDbY7yaqMBmozCGvAFyTwaZA3imeZH83w7Hr3r3bYlMRWIyzMI/lDUvUMM/92LE2OwqFyQ==" - }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "glob-watcher": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", - "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "object.defaults": "^1.1.0" - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globby": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", - "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - } - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "glsl-tokenizer": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz", - "integrity": "sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==", - "requires": { - "through2": "^0.6.3" - } - }, - "gpu-mock.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/gpu-mock.js/-/gpu-mock.js-1.1.0.tgz", - "integrity": "sha512-kDMvQ04qIqbrpGyYCShx8NhZYMiolb1XUkjnJn92/jcMsxjcPF7KFfDMJEg0VUwxVJzD4djzJNWbmJCs00YEVg==" - }, - "graceful-fs": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", - "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "dependencies": { - "gulp-cli": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz", - "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.1.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.0.1", - "yargs": "^7.1.0" - } - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - } - }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", - "dev": true, - "requires": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-header": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/gulp-header/-/gulp-header-1.8.12.tgz", - "integrity": "sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==", - "dev": true, - "requires": { - "concat-with-sourcemaps": "*", - "lodash.template": "^4.4.0", - "through2": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-jsbeautifier": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/gulp-jsbeautifier/-/gulp-jsbeautifier-2.1.2.tgz", - "integrity": "sha512-tZUk4c11zF8xzCCTOEmktxGitv/H2vpAcflZNVU8nxL+G5XxQyLJUJVUKylz7/dax+FXb3YwQYByaJ+yxmo8iw==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "fancy-log": "^1.3.2", - "js-beautify": "^1.7.5", - "lodash": "^4.17.4", - "plugin-error": "^0.1.2", - "rc": "^1.2.2", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-rename": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz", - "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==", - "dev": true - }, - "gulp-replace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.0.0.tgz", - "integrity": "sha512-lgdmrFSI1SdhNMXZQbrC75MOl1UjYWlOWNbNRnz+F/KHmgxt3l6XstBoAYIdadwETFyG/6i+vWUSCawdC3pqOw==", - "dev": true, - "requires": { - "istextorbinary": "2.2.1", - "readable-stream": "^2.0.1", - "replacestream": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "gulp-strip-comments": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/gulp-strip-comments/-/gulp-strip-comments-2.5.2.tgz", - "integrity": "sha512-lb1bW7rsPWDD8f4ZPSguDvmCdjKmjr5HR4yZb9ros3sLl5AfW7oUj8KzY9/VRisT7dG8dL7hVHzNpQEVxfwZGQ==", - "dev": true, - "requires": { - "decomment": "^0.9.0", - "plugin-error": "^0.1.2", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gulp-uglify-es": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/gulp-uglify-es/-/gulp-uglify-es-1.0.4.tgz", - "integrity": "sha512-UMRufZsBmQizCYpftutaiVoLswpbzFEfY90EJLU4YlTgculeHnanb794s88TMd5tpCZVC638sAX6JrLVYTP/Wg==", - "dev": true, - "requires": { - "o-stream": "^0.2.2", - "plugin-error": "^1.0.1", - "terser": "^3.7.5", - "vinyl": "^2.1.0", - "vinyl-sourcemaps-apply": "^0.2.1" - }, - "dependencies": { - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "^1.0.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "dev": true, - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true - }, - "htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", - "dev": true - }, - "http-errors": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", - "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz", - "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=", - "dev": true, - "requires": { - "eventemitter3": "1.x.x", - "requires-port": "1.x.x" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "ignore": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", - "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", - "dev": true - }, - "immutable": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", - "dev": true, - "requires": { - "source-map": "~0.5.3" - } - }, - "insert-module-globals": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", - "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "acorn-node": "^1.5.2", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "undeclared-identifiers": "^1.1.2", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-number-like": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", - "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", - "dev": true, - "requires": { - "lodash.isfinite": "^3.3.2" - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-3.0.0.tgz", - "integrity": "sha512-QGuLYLNfpHI/xLQ8ctyeD9mMCf2eBqrtxYWKQxlExrD0l3wBSDcplKYfV55lnTDB4MDvh9SRDt/VnDwVn0dYOw==", - "dev": true, - "requires": { - "is-path-inside": "^3.0.1" - } - }, - "is-path-inside": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.1.tgz", - "integrity": "sha512-CKstxrctq1kUesU6WhtZDbYKzzYBuRH0UYInAVrkc/EYdB9ltbfE0gOoayG9nhohG6447sOOVGhHqsdmBvkbNg==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istextorbinary": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz", - "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==", - "dev": true, - "requires": { - "binaryextensions": "2", - "editions": "^1.3.3", - "textextensions": "2" - } - }, - "js-beautify": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.10.1.tgz", - "integrity": "sha512-4y8SHOIRC+/YQ2gs3zJEKBUraQerq49FJYyXRpdzUGYQzCq8q9xtIh0YXial1S5KmonVui4aiUb6XaGyjE51XA==", - "dev": true, - "requires": { - "config-chain": "^1.1.12", - "editorconfig": "^0.15.3", - "glob": "^7.1.3", - "mkdirp": "~0.5.1", - "nopt": "~4.0.1" - }, - "dependencies": { - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, - "js-reporters": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-1.2.1.tgz", - "integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", - "dev": true, - "requires": { - "jsonify": "~0.0.0" - } - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "just-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", - "dev": true - }, - "just-extend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", - "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "labeled-stream-splicer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", - "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "stream-splicer": "^2.0.0" - } - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - } - }, - "limiter": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.4.tgz", - "integrity": "sha512-XCpr5bElgDI65vVgstP8TWjv6/QKWm9GU5UG0Pr5sLQ3QLo8NVKsioe+Jed5/3vFOe3IQuqE7DKwTvKQkjTHvg==", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "localtunnel": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.2.tgz", - "integrity": "sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg==", - "dev": true, - "requires": { - "axios": "0.19.0", - "debug": "4.1.1", - "openurl": "1.1.1", - "yargs": "6.6.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^4.2.0" - } - } - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.isfinite": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", - "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", - "dev": true - }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lolex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.1.0.tgz", - "integrity": "sha512-BYxIEXiVq5lGIXeVHnsFzqa1TxN5acnKnPCdlZSpzm8viNEOhiigupA4vTQ9HEFQ6nLTQ9wQOgBknJgzUYQ9Aw==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - }, - "dependencies": { - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "merge2": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", - "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "requires": { - "mime-db": "1.40.0" - } - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "minipass": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.5.1.tgz", - "integrity": "sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "requires": { - "minipass": "^2.2.1" - } - }, - "mitt": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz", - "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==", - "dev": true - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "module-deps": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.1.tgz", - "integrity": "sha512-UnEn6Ah36Tu4jFiBbJVUtt0h+iXqxpLqDvPS8nllbw5RZFmNJ1+Mz5BjYnM9ieH80zyxHkARGLnMIHlPK5bu6A==", - "dev": true, - "requires": { - "JSONStream": "^1.0.3", - "browser-resolve": "^1.7.0", - "cached-path-relative": "^1.0.2", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.0.2", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "napi-build-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz", - "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==" - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "nise": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.0.tgz", - "integrity": "sha512-Z3sfYEkLFzFmL8KY6xnSJLRxwQwYBjOXi/24lb62ZnZiGA0JUzGGTI6TBIgfCSMIDl9Jlu8SRmHNACLTemDHww==", - "dev": true, - "requires": { - "@sinonjs/formatio": "^3.1.0", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "lolex": "^4.1.0", - "path-to-regexp": "^1.7.0" - } - }, - "node-abi": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.11.0.tgz", - "integrity": "sha512-kuy/aEg75u40v378WRllQ4ZexaXJiCvB68D2scDXclp/I4cRq6togpbOoKhmN07tns9Zldu51NNERo0wehfX9g==", - "requires": { - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "node-gyp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", - "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", - "requires": { - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^4.4.8", - "which": "1" - } - }, - "node-watch": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.0.tgz", - "integrity": "sha512-XAgTL05z75ptd7JSVejH1a2Dm1zmXYhuDr9l230Qk6Z7/7GPcnAs/UyJJ4ggsXSvWil8iOzwQLW0zuGUvHpG8g==", - "dev": true - }, - "noop-logger": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", - "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "o-stream": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/o-stream/-/o-stream-0.2.2.tgz", - "integrity": "sha512-V3j76KU3g/Gyl8rpdi2z72rn5zguMvTCQgAXfBe3pxEefKqXmOUOD7mvx/mNjykdxGqDVfpSoo8r+WdrkWg/1Q==", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-path": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz", - "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "openurl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", - "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=", - "dev": true - }, - "opn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", - "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true - }, - "parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", - "dev": true, - "requires": { - "path-platform": "~0.11.15" - } - }, - "parse-asn1": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", - "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "path-sort2": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-sort2/-/path-sort2-1.0.0.tgz", - "integrity": "sha512-OwUzmr3+avyEANhpUkUv+nlwAM/sCX5y9Ylok8fj3OK3SmLclq7jyEoqSL5qi+5bJAOskWGZPtdtjnoRGy5lxA==", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", - "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "platform": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", - "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", - "dev": true - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "^1.1.0" - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - } - } - }, - "portscanner": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", - "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", - "dev": true, - "requires": { - "async": "1.5.2", - "is-number-like": "^1.0.3" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "prebuild-install": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.1.tgz", - "integrity": "sha512-lRLBU0JPXBbpC/ER9PtVYYk1y9Rme1WiMA3WKEQ4v78A5kTsqQtrEyYlbghvXCA6Uhr/769SkhibQznjDBRZpg==", - "requires": { - "detect-libc": "^1.0.3", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "napi-build-utils": "^1.0.1", - "node-abi": "^2.7.0", - "noop-logger": "^0.1.1", - "npmlog": "^4.0.1", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^3.0.3", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", - "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "qunit": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.9.2.tgz", - "integrity": "sha512-wTOYHnioWHcx5wa85Wl15IE7D6zTZe2CQlsodS14yj7s2FZ3MviRnQluspBZsueIDEO7doiuzKlv05yfky1R7w==", - "dev": true, - "requires": { - "commander": "2.12.2", - "js-reporters": "1.2.1", - "minimatch": "3.0.4", - "node-watch": "0.6.0", - "resolve": "1.9.0" - }, - "dependencies": { - "commander": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", - "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", - "dev": true - }, - "resolve": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", - "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", - "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.3", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "read-dir-deep": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-dir-deep/-/read-dir-deep-7.0.1.tgz", - "integrity": "sha512-w99fvgqJm3cJ5Vb7b3oGKRDnm/m11q7w5LQ9uBCXe+repIEf1rFtkXLlPAxNrSwlp4skyPyvKd4DNNiIuc0geg==", - "dev": true, - "requires": { - "globby": "^10.0.1", - "is-path-cwd": "^2.2.0", - "is-path-in-cwd": "^3.0.0", - "path-sort2": "^1.0.0", - "slash": "^3.0.0" - } - }, - "read-only-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "replacestream": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz", - "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.3", - "object-assign": "^4.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", - "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "resp-modifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", - "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", - "dev": true, - "requires": { - "debug": "^2.2.0", - "minimatch": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", - "dev": true - }, - "rxjs": { - "version": "5.5.12", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", - "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", - "dev": true, - "requires": { - "symbol-observable": "1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", - "dev": true, - "requires": { - "sver-compat": "^1.5.0" - } - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true - } - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - } - } - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - } - }, - "server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shasum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", - "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", - "dev": true, - "requires": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" - } - }, - "shell-quote": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", - "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", - "dev": true, - "requires": { - "array-filter": "~0.0.0", - "array-map": "~0.0.0", - "array-reduce": "~0.0.0", - "jsonify": "~0.0.0" - } - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "simple-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", - "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" - }, - "simple-get": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.0.3.tgz", - "integrity": "sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw==", - "requires": { - "decompress-response": "^3.3.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "sinon": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.3.2.tgz", - "integrity": "sha512-thErC1z64BeyGiPvF8aoSg0LEnptSaWE7YhdWWbWXgelOyThent7uKOnnEh9zBxDbKixtr5dEko+ws1sZMuFMA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.4.0", - "@sinonjs/formatio": "^3.2.1", - "@sinonjs/samsam": "^3.3.1", - "diff": "^3.5.0", - "lolex": "^4.0.1", - "nise": "^1.4.10", - "supports-color": "^5.5.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "socket.io": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", - "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", - "dev": true, - "requires": { - "debug": "~3.1.0", - "engine.io": "~3.2.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.1.1", - "socket.io-parser": "~3.2.0" - }, - "dependencies": { - "engine.io-client": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", - "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - }, - "socket.io-client": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", - "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.2.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.2.0", - "to-array": "0.1.4" - } - }, - "socket.io-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", - "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - } - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" - } - } - } - }, - "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", - "dev": true - }, - "socket.io-client": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", - "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.3.1", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.3.0", - "to-array": "0.1.4" - } - }, - "socket.io-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", - "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", - "dev": true, - "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "stream-splicer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", - "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "stream-throttle": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", - "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=", - "dev": true, - "requires": { - "commander": "^2.2.0", - "limiter": "^1.0.5" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", - "dev": true, - "requires": { - "minimist": "^1.1.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", - "dev": true, - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", - "dev": true - }, - "syntax-error": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", - "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", - "dev": true, - "requires": { - "acorn-node": "^1.2.0" - } - }, - "tar": { - "version": "4.4.10", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", - "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==", - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.5", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "tar-fs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", - "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", - "requires": { - "chownr": "^1.1.1", - "mkdirp": "^0.5.1", - "pump": "^3.0.0", - "tar-stream": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "tar-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", - "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", - "requires": { - "bl": "^3.0.0", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "bl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", - "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", - "requires": { - "readable-stream": "^3.0.1" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "terser": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", - "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", - "dev": true, - "requires": { - "commander": "^2.19.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.10" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "textextensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.4.0.tgz", - "integrity": "sha512-qftQXnX1DzpSV8EddtHIT0eDDEiBF8ywhFYR2lI9xrGtxqKN+CvLXhACeCIGbCpQfxxERbrkZEFb8cZcDKbVZA==", - "dev": true - }, - "tfunk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz", - "integrity": "sha1-OORBT8ZJd9h6/apy+sttKfgve1s=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "object-path": "^0.9.0" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", - "dev": true, - "requires": { - "process": "~0.11.0" - } - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "dev": true, - "requires": { - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/type/-/type-1.0.1.tgz", - "integrity": "sha512-MAM5dBMJCJNKs9E7JXo4CXRAansRfG0nlJxW7Wf6GZzSOvH31zClSaHdIMWLehe/EGMBkqeC55rrkaOr5Oo7Nw==", - "dev": true - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.17", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", - "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", - "dev": true - }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "umd": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "undeclared-identifiers": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", - "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", - "dev": true, - "requires": { - "acorn-node": "^1.3.0", - "dash-ast": "^1.0.0", - "get-assigned-identifiers": "^1.2.0", - "simple-concat": "^1.0.0", - "xtend": "^4.0.1" - } - }, - "undertaker": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", - "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - } - } - }, - "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", - "dev": true - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" - }, - "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vinyl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", - "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, - "vinyl-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/vinyl-buffer/-/vinyl-buffer-1.0.1.tgz", - "integrity": "sha1-lsGjR5uMU5JULGEgKQE7Wyf4i78=", - "dev": true, - "requires": { - "bl": "^1.2.1", - "through2": "^2.0.3" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-source-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-2.0.0.tgz", - "integrity": "sha1-84pa+53R6Ttl1VBGmsYYKsT1S44=", - "dev": true, - "requires": { - "through2": "^2.0.3", - "vinyl": "^2.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "dev": true, - "requires": { - "source-map": "^0.5.1" - } - }, - "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "window-size": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", - "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" - }, - "yargs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", - "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^4.1.0" - } - }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true - } - } -} +{ + "name": "gpu.js", + "version": "2.0.5", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz", + "integrity": "sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.1", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz", + "integrity": "sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz", + "integrity": "sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.1", + "fastq": "^1.6.0" + } + }, + "@sinonjs/commons": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.6.0.tgz", + "integrity": "sha512-w4/WHG7C4WWFyE5geCieFJF6MZkbW4VAriol5KlmQXpAQdxvV0p26sqNZOW6Qyw6Y0l9K4g+cHvvczR2sEEpqg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", + "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "array-from": "^2.1.1", + "lodash": "^4.17.15" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.6.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.6.8.tgz", + "integrity": "sha512-aX+gFgA5GHcDi89KG5keey2zf0WfZk/HAQotEamsK2kbey+8yGKcson0hbK8E+v0NArlCJQCqMP161YhV6ZXLg==", + "dev": true + }, + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-each-series": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", + "integrity": "sha1-dhfBkXQB/Yykooqtzj266Yr+tDI=", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axios": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", + "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", + "dev": true, + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "dev": true + } + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "dev": true + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", + "dev": true, + "requires": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dev": true, + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bit-twiddle": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bit-twiddle/-/bit-twiddle-1.0.2.tgz", + "integrity": "sha1-DGwfq+KyPRcXPZpht7cJPrnhdp4=" + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "browser-sync": { + "version": "2.26.7", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.7.tgz", + "integrity": "sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w==", + "dev": true, + "requires": { + "browser-sync-client": "^2.26.6", + "browser-sync-ui": "^2.26.4", + "bs-recipes": "1.3.4", + "bs-snippet-injector": "^2.0.1", + "chokidar": "^2.0.4", + "connect": "3.6.6", + "connect-history-api-fallback": "^1", + "dev-ip": "^1.0.1", + "easy-extender": "^2.3.4", + "eazy-logger": "^3", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "fs-extra": "3.0.1", + "http-proxy": "1.15.2", + "immutable": "^3", + "localtunnel": "1.9.2", + "micromatch": "^3.1.10", + "opn": "5.3.0", + "portscanner": "2.1.1", + "qs": "6.2.3", + "raw-body": "^2.3.2", + "resp-modifier": "6.0.2", + "rx": "4.1.0", + "send": "0.16.2", + "serve-index": "1.9.1", + "serve-static": "1.13.2", + "server-destroy": "1.0.1", + "socket.io": "2.1.1", + "ua-parser-js": "0.7.17", + "yargs": "6.4.0" + }, + "dependencies": { + "qs": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", + "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", + "dev": true + } + } + }, + "browser-sync-client": { + "version": "2.26.6", + "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.6.tgz", + "integrity": "sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw==", + "dev": true, + "requires": { + "etag": "1.8.1", + "fresh": "0.5.2", + "mitt": "^1.1.3", + "rxjs": "^5.5.6" + } + }, + "browser-sync-ui": { + "version": "2.26.4", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz", + "integrity": "sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA==", + "dev": true, + "requires": { + "async-each-series": "0.1.1", + "connect-history-api-fallback": "^1", + "immutable": "^3", + "server-destroy": "1.0.1", + "socket.io-client": "^2.0.4", + "stream-throttle": "^0.1.3" + } + }, + "bs-recipes": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", + "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", + "dev": true + }, + "bs-snippet-injector": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz", + "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "dev": true + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "connect": { + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", + "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", + "dev": true, + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.0", + "parseurl": "~1.3.2", + "utils-merge": "1.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "requires": { + "mimic-response": "^2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "dev-ip": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", + "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, + "easy-extender": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz", + "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "eazy-logger": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.0.2.tgz", + "integrity": "sha1-oyWqXlPROiIliJsqxBE7K5Y29Pw=", + "dev": true, + "requires": { + "tfunk": "^3.0.1" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "engine.io": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "base64id": "1.0.0", + "cookie": "0.3.1", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.0", + "ws": "~3.3.1" + }, + "dependencies": { + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "engine.io-client": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz", + "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", + "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.0.0", + "string.prototype.trimright": "^2.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", + "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz", + "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.1", + "@nodelib/fs.walk": "^1.2.1", + "glob-parent": "^5.0.0", + "is-glob": "^4.0.1", + "merge2": "^1.2.3", + "micromatch": "^4.0.2" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.1", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.2", + "statuses": "~1.3.1", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dev": true, + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + }, + "gl": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/gl/-/gl-4.4.0.tgz", + "integrity": "sha512-4FIq5tqiltTsadrLh6DGY4R9+aQwj25OM2WlXEv81N6YN1q1C0qR7ct0SKp1uUJdnBqbKhUJP3zQ1td40AVeJg==", + "requires": { + "bindings": "^1.5.0", + "bit-twiddle": "^1.0.2", + "glsl-tokenizer": "^2.0.2", + "nan": "^2.14.0", + "node-gyp": "^4.0.0", + "prebuild-install": "^5.1.0" + } + }, + "gl-wiretap": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/gl-wiretap/-/gl-wiretap-0.6.2.tgz", + "integrity": "sha512-fxy1XGiPkfzK+T3XKDbY7yaqMBmozCGvAFyTwaZA3imeZH83w7Hr3r3bYlMRWIyzMI/lDUvUMM/92LE2OwqFyQ==" + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + } + }, + "glsl-tokenizer": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/glsl-tokenizer/-/glsl-tokenizer-2.1.5.tgz", + "integrity": "sha512-XSZEJ/i4dmz3Pmbnpsy3cKh7cotvFlBiZnDOwnj/05EwNp2XrhQ4XKJxT7/pDt4kp4YcpRSKz8eTV7S+mwV6MA==", + "requires": { + "through2": "^0.6.3" + } + }, + "gpu-mock.js": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gpu-mock.js/-/gpu-mock.js-1.1.0.tgz", + "integrity": "sha512-kDMvQ04qIqbrpGyYCShx8NhZYMiolb1XUkjnJn92/jcMsxjcPF7KFfDMJEg0VUwxVJzD4djzJNWbmJCs00YEVg==" + }, + "graceful-fs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + } + } + }, + "http-proxy": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.15.2.tgz", + "integrity": "sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE=", + "dev": true, + "requires": { + "eventemitter3": "1.x.x", + "requires-port": "1.x.x" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", + "dev": true + }, + "immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=", + "dev": true + }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-number-like": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", + "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", + "dev": true, + "requires": { + "lodash.isfinite": "^3.3.2" + } + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-3.0.0.tgz", + "integrity": "sha512-QGuLYLNfpHI/xLQ8ctyeD9mMCf2eBqrtxYWKQxlExrD0l3wBSDcplKYfV55lnTDB4MDvh9SRDt/VnDwVn0dYOw==", + "dev": true, + "requires": { + "is-path-inside": "^3.0.1" + } + }, + "is-path-inside": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.1.tgz", + "integrity": "sha512-CKstxrctq1kUesU6WhtZDbYKzzYBuRH0UYInAVrkc/EYdB9ltbfE0gOoayG9nhohG6447sOOVGhHqsdmBvkbNg==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-reference": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.3.tgz", + "integrity": "sha512-W1iHHv/oyBb2pPxkBxtaewxa1BC58Pn5J0hogyCdefwUIvb6R+TGbAcIa4qPNYLqLhb3EnOgUf2MQkkF76BcKw==", + "dev": true, + "requires": { + "@types/estree": "0.0.39" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jest-worker": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "js-cleanup": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-cleanup/-/js-cleanup-1.0.1.tgz", + "integrity": "sha512-wyHeWKqbcQV78/tiMJ6pgJrkG7p2u3b2xX9IJFvvurpJL9/++89dHfkUebhWvSMS84LG0uQ7BnG5GGyAzY21Ag==", + "dev": true, + "requires": { + "magic-string": "^0.25.1", + "perf-regexes": "^1.0.1", + "skip-regex": "^1.0.2" + } + }, + "js-reporters": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/js-reporters/-/js-reporters-1.2.1.tgz", + "integrity": "sha1-+IxgjjJKM3OpW8xFrTBeXJecRZs=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "limiter": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.4.tgz", + "integrity": "sha512-XCpr5bElgDI65vVgstP8TWjv6/QKWm9GU5UG0Pr5sLQ3QLo8NVKsioe+Jed5/3vFOe3IQuqE7DKwTvKQkjTHvg==", + "dev": true + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "localtunnel": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.2.tgz", + "integrity": "sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg==", + "dev": true, + "requires": { + "axios": "0.19.0", + "debug": "4.1.1", + "openurl": "1.1.1", + "yargs": "6.6.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "yargs": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^4.2.0" + } + } + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.isfinite": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", + "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", + "dev": true + }, + "lolex": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", + "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", + "dev": true + }, + "magic-string": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", + "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=", + "dev": true + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", + "dev": true + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-response": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.0.0.tgz", + "integrity": "sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "minipass": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.6.5.tgz", + "integrity": "sha512-ewSKOPFH9blOLXx0YSE+mbrNMBFPS+11a2b03QZ+P4LVrUHW/GAlqeYC7DBknDyMWkHzrzTpDhUvy7MUxqyrPA==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.2.tgz", + "integrity": "sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ==", + "requires": { + "minipass": "^2.2.1" + } + }, + "mitt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz", + "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==", + "dev": true + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "napi-build-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.1.tgz", + "integrity": "sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nise": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.2.tgz", + "integrity": "sha512-/6RhOUlicRCbE9s+94qCUsyE+pKlVJ5AhIv+jEE7ESKwnbXqulKZ1FYU+XAtHHWE9TinYvAxDUJAb912PwPoWA==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^4.1.0", + "path-to-regexp": "^1.7.0" + } + }, + "node-abi": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.11.0.tgz", + "integrity": "sha512-kuy/aEg75u40v378WRllQ4ZexaXJiCvB68D2scDXclp/I4cRq6togpbOoKhmN07tns9Zldu51NNERo0wehfX9g==", + "requires": { + "semver": "^5.4.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "requires": { + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^4.4.8", + "which": "1" + } + }, + "node-watch": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.6.0.tgz", + "integrity": "sha512-XAgTL05z75ptd7JSVejH1a2Dm1zmXYhuDr9l230Qk6Z7/7GPcnAs/UyJJ4ggsXSvWil8iOzwQLW0zuGUvHpG8g==", + "dev": true + }, + "noop-logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", + "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-path": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz", + "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "openurl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", + "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=", + "dev": true + }, + "opn": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dev": true, + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dev": true, + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-sort2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-sort2/-/path-sort2-1.0.0.tgz", + "integrity": "sha512-OwUzmr3+avyEANhpUkUv+nlwAM/sCX5y9Ylok8fj3OK3SmLclq7jyEoqSL5qi+5bJAOskWGZPtdtjnoRGy5lxA==", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "perf-regexes": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/perf-regexes/-/perf-regexes-1.0.1.tgz", + "integrity": "sha512-L7MXxUDtqr4PUaLFCDCXBfGV/6KLIuSEccizDI7JxT+c9x1G1v04BQ4+4oag84SHaCdrBgQAIs/Cqn+flwFPng==", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "picomatch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", + "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", + "dev": true + }, + "pidtree": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.0.tgz", + "integrity": "sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "platform": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", + "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", + "dev": true + }, + "portscanner": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", + "integrity": "sha1-6rtAnk3iSVD1oqUW01rnaTQ/u5Y=", + "dev": true, + "requires": { + "async": "1.5.2", + "is-number-like": "^1.0.3" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prebuild-install": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.2.tgz", + "integrity": "sha512-INDfXzTPnhT+WYQemqnAXlP7SvfiFMopMozSgXCZ+RDLb279gKfIuLk4o7PgEawLp3WrMgIYGBpkxpraROHsSA==", + "requires": { + "detect-libc": "^1.0.3", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "napi-build-utils": "^1.0.1", + "node-abi": "^2.7.0", + "noop-logger": "^0.1.1", + "npmlog": "^4.0.1", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^3.0.3", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "psl": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", + "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "qunit": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.9.2.tgz", + "integrity": "sha512-wTOYHnioWHcx5wa85Wl15IE7D6zTZe2CQlsodS14yj7s2FZ3MviRnQluspBZsueIDEO7doiuzKlv05yfky1R7w==", + "dev": true, + "requires": { + "commander": "2.12.2", + "js-reporters": "1.2.1", + "minimatch": "3.0.4", + "node-watch": "0.6.0", + "resolve": "1.9.0" + }, + "dependencies": { + "commander": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz", + "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==", + "dev": true + }, + "resolve": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", + "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.1.tgz", + "integrity": "sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.3", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "read-dir-deep": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-dir-deep/-/read-dir-deep-7.0.1.tgz", + "integrity": "sha512-w99fvgqJm3cJ5Vb7b3oGKRDnm/m11q7w5LQ9uBCXe+repIEf1rFtkXLlPAxNrSwlp4skyPyvKd4DNNiIuc0geg==", + "dev": true, + "requires": { + "globby": "^10.0.1", + "is-path-cwd": "^2.2.0", + "is-path-in-cwd": "^3.0.0", + "path-sort2": "^1.0.0", + "slash": "^3.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "resp-modifier": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", + "integrity": "sha1-sSTeXE+6/LpUH0j/pzlw9KpFa08=", + "dev": true, + "requires": { + "debug": "^2.2.0", + "minimatch": "^3.0.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "1.21.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.21.4.tgz", + "integrity": "sha512-Pl512XVCmVzgcBz5h/3Li4oTaoDcmpuFZ+kdhS/wLreALz//WuDAMfomD3QEYl84NkDu6Z6wV9twlcREb4qQsw==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "@types/node": "^12.7.5", + "acorn": "^7.0.0" + }, + "dependencies": { + "@types/node": { + "version": "12.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz", + "integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==", + "dev": true + }, + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + } + } + }, + "rollup-plugin-cleanup": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-cleanup/-/rollup-plugin-cleanup-3.1.1.tgz", + "integrity": "sha512-wMS9JQm4ShvlMqno1pOfqvh0yYgNLO2ZgmzDsVvKuDt4XCn+9DcMoUwRQ5t9p9b113dR5FhPFFUHnvvQ/yuEtA==", + "dev": true, + "requires": { + "js-cleanup": "^1.0.1", + "rollup-pluginutils": "^2.3.3" + } + }, + "rollup-plugin-commonjs": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz", + "integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1", + "is-reference": "^1.1.2", + "magic-string": "^0.25.2", + "resolve": "^1.11.0", + "rollup-pluginutils": "^2.8.1" + } + }, + "rollup-plugin-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-json/-/rollup-plugin-json-4.0.0.tgz", + "integrity": "sha512-hgb8N7Cgfw5SZAkb3jf0QXii6QX/FOkiIq2M7BAQIEydjHvTyxXHQiIzZaTFgx1GK0cRCHOCBHIyEkkLdWKxow==", + "dev": true, + "requires": { + "rollup-pluginutils": "^2.5.0" + } + }, + "rollup-plugin-node-resolve": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", + "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", + "dev": true, + "requires": { + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.11.1", + "rollup-pluginutils": "^2.8.1" + } + }, + "rollup-plugin-terser": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.1.2.tgz", + "integrity": "sha512-sWKBCOS+vUkRtHtEiJPAf+WnBqk/C402fBD9AVHxSIXMqjsY7MnYWKYEUqGixtr0c8+1DjzUEPlNgOYQPVrS1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "jest-worker": "^24.6.0", + "rollup-pluginutils": "^2.8.1", + "serialize-javascript": "^1.7.0", + "terser": "^4.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "terser": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz", + "integrity": "sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + } + } + }, + "rollup-pluginutils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz", + "integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==", + "dev": true, + "requires": { + "estree-walker": "^0.6.1" + } + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "dev": true, + "requires": { + "symbol-observable": "1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "send": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", + "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "~2.3.0", + "range-parser": "~1.2.0", + "statuses": "~1.4.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", + "dev": true + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + } + } + }, + "serve-static": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", + "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.2", + "send": "0.16.2" + } + }, + "server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" + }, + "simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "requires": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "sinon": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.4.2.tgz", + "integrity": "sha512-pY5RY99DKelU3pjNxcWo6XqeB1S118GBcVIIdDi6V+h6hevn1izcg2xv1hTHW/sViRXU7sUOxt4wTUJ3gsW2CQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.4.0", + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/samsam": "^3.3.3", + "diff": "^3.5.0", + "lolex": "^4.2.0", + "nise": "^1.5.2", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "skip-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/skip-regex/-/skip-regex-1.0.2.tgz", + "integrity": "sha512-pEjMUbwJ5Pl/6Vn6FsamXHXItJXSRftcibixDmNCWbWhic0hzHrwkMZo0IZ7fMRH9KxcWDFSkzhccB4285PutA==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "socket.io": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", + "dev": true, + "requires": { + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" + }, + "dependencies": { + "engine.io-client": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~3.3.1", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + }, + "socket.io-client": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.2.0", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "socket.io-adapter": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", + "dev": true + }, + "socket.io-client": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz", + "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==", + "dev": true, + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "engine.io-client": "~3.3.1", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "dev": true, + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "sourcemap-codec": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", + "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", + "dev": true + }, + "stream-throttle": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", + "integrity": "sha1-rdV8jXzHOoFjDTHNVdOWHPr7qcM=", + "dev": true, + "requires": { + "commander": "^2.2.0", + "limiter": "^1.0.5" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.padend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "integrity": "sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.4.3", + "function-bind": "^1.0.2" + } + }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + }, + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", + "dev": true + }, + "tar": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.11.tgz", + "integrity": "sha512-iI4zh3ktLJKaDNZKZc+fUONiQrSn9HkCFzamtb7k8FFmVilHVob7QsLX/VySAW8lAviMzMbFw4QtFb4errwgYA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.6.4", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "tar-fs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", + "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", + "requires": { + "chownr": "^1.1.1", + "mkdirp": "^0.5.1", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "tar-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz", + "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==", + "requires": { + "bl": "^3.0.0", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "bl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz", + "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==", + "requires": { + "readable-stream": "^3.0.1" + } + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "tfunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz", + "integrity": "sha1-OORBT8ZJd9h6/apy+sttKfgve1s=", + "dev": true, + "requires": { + "chalk": "^1.1.1", + "object-path": "^0.9.0" + } + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "ua-parser-js": { + "version": "0.7.17", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", + "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", + "dev": true + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", + "dev": true + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + }, + "yargs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.4.0.tgz", + "integrity": "sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ=", + "dev": true, + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^4.1.0" + } + }, + "yargs-parser": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", + "dev": true, + "requires": { + "camelcase": "^3.0.0" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 730f872c..e421fc55 100644 --- a/package.json +++ b/package.json @@ -1,65 +1,60 @@ -{ - "name": "gpu.js", - "version": "2.0.5", - "description": "GPU Accelerated JavaScript", - "engines": { - "node": ">=8.0.0" - }, - "main": "./src/index.js", - "files": [ - "src", - "dist" - ], - "unpkg": "./dist/gpu-browser.min.js", - "jsdelivr": "./dist/gpu-browser.min.js", - "browser": "./dist/gpu-browser.js", - "directories": { - "doc": "doc", - "test": "test" - }, - "dependencies": { - "acorn": "^5.1.1", - "gl": "^4.4.0", - "gl-wiretap": "^0.6.2", - "gpu-mock.js": "^1.1.0" - }, - "devDependencies": { - "benchmark": "^2.1.4", - "browser-sync": "^2.26.7", - "browserify": "^16.2.3", - "gulp": "^4.0.0", - "gulp-concat": "^2.6.0", - "gulp-header": "^1.7.1", - "gulp-jsbeautifier": "^2.1.0", - "gulp-rename": "^1.2.2", - "gulp-replace": "^1.0.0", - "gulp-strip-comments": "^2.4.5", - "gulp-uglify-es": "^1.0.4", - "merge-stream": "^1.0.1", - "qunit": "^2.9.1", - "read-dir-deep": "^7.0.1", - "sinon": "^7.3.2", - "vinyl-buffer": "^1.0.0", - "vinyl-source-stream": "^2.0.0" - }, - "scripts": { - "test": "qunit", - "setup": "npm i -g gulp-cli", - "make": "gulp make" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/gpujs/gpu.js.git" - }, - "keywords": [ - "gpgpu", - "webgl" - ], - "author": "The gpu.js Team", - "license": "MIT", - "bugs": { - "url": "https://github.com/gpujs/gpu.js/issues" - }, - "homepage": "http://gpu.rocks/", - "typings": "./src/index.d.ts" -} +{ + "name": "gpu.js", + "version": "2.0.5", + "description": "GPU Accelerated JavaScript", + "author": "The gpu.js Team", + "license": "MIT", + "homepage": "https://gpu.rocks/", + "main": "./dist/gpu.js", + "browser": "./dist/gpu-browser.min.js", + "unpkg": "./dist/gpu-browser.min.js", + "jsdelivr": "./dist/gpu-browser.min.js", + "module": "./dist/gpu.mjs", + "typings": "./src/index.d.ts", + "files": [ + "dist" + ], + "engines": { + "node": ">=8.0.0" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/gpujs/gpu.js.git" + }, + "keywords": [ + "gpgpu", + "webgl" + ], + "bugs": { + "url": "https://github.com/gpujs/gpu.js/issues" + }, + "scripts": { + "build-tests": "node build-tests", + "build": "rollup -c", + "pretest": "npm run build && npm run build-tests", + "prewatch": "npm run build-tests", + "test": "qunit", + "watch": "rollup -c -w" + }, + "dependencies": { + "acorn": "^5.1.1", + "gl": "^4.4.0", + "gl-wiretap": "^0.6.2", + "gpu-mock.js": "^1.1.0" + }, + "devDependencies": { + "benchmark": "^2.1.4", + "browser-sync": "^2.26.7", + "chai": "^4.2.0", + "npm-run-all": "^4.1.5", + "qunit": "^2.9.1", + "read-dir-deep": "^7.0.1", + "rollup": "^1.21.4", + "rollup-plugin-cleanup": "^3.1.1", + "rollup-plugin-commonjs": "^10.1.0", + "rollup-plugin-json": "^4.0.0", + "rollup-plugin-node-resolve": "^5.2.0", + "rollup-plugin-terser": "^5.1.2", + "sinon": "^7.4.2" + } +} diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000..ea33ec50 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,113 @@ +import BrowserSync from 'browser-sync'; +import cleanup from 'rollup-plugin-cleanup'; +import commonjs from 'rollup-plugin-commonjs'; +import json from 'rollup-plugin-json'; +import pkg from './package.json'; +import resolve from 'rollup-plugin-node-resolve'; +import { terser } from 'rollup-plugin-terser'; + +const production = !process.env.ROLLUP_WATCH; + +const browsersyncOptions = { + server: '.', + open: true, + startPath: './test/all.html', + host: '0.0.0.0', + port: 9005, + tunnel: true +}; + +const bs = BrowserSync.create('rollup'); + +function browsersync(options) { + if (!bs.active) { + bs.init(options || { server: '.' }); + process.on('SIGTERM', () => { + bs.exit(); + process.exit(0); + }); + } + + return { + name: 'browsersync', + generateBundle: function({}, bundle, isWrite) { + if (isWrite) { + bs.io && bs.reload(bundle.dest); + } + } + } +}; + +const terserOptions = { + include: [/^.+\.min\.js$/] +}; + +const banner = `/** + * ${pkg.name} + * ${pkg.homepage} + * + * ${pkg.description} + * + * @version ${pkg.version} + * @date ${new Date()} + * + * @license ${pkg.license} + * The MIT License + * + * Copyright (c) ${new Date().getFullYear()} gpu.js Team + */`; + +const output = (file, format, core = false) => ({ + 'esm': { file, format, banner, sourcemap: true }, + 'cjs': { file, format, banner, sourcemap: true }, + 'iife': { file, format, banner, sourcemap: true, name: 'GPU', globals: core ? { acorn: 'acorn' } : {} } +}[format]); + +const main = { + input: './src/index.js', + output: [ + output('./dist/gpu.js', 'cjs'), + output('./dist/gpu.mjs', 'esm') + ], + external: [ 'gl', 'acorn' ], + plugins: [ + json(), + resolve(), + commonjs(), + cleanup(), + terser(terserOptions), + ] +} + +const browser = { + input: './src/browser.js', + output: [ + output('./dist/gpu-browser.js', 'iife'), + output('./dist/gpu-browser.min.js', 'iife') + ], + plugins: [ + json(), + resolve(), + commonjs(), + production && cleanup(), + production ? terser(terserOptions) : browsersync(browsersyncOptions) + ] +} + +const core = { + input: './src/browser.js', + output: [ + output('./dist/gpu-browser-core.js', 'iife', true), + output('./dist/gpu-browser-core.min.js', 'iife', true) + ], + external: [ 'acorn' ], + plugins: [ + json(), + resolve(), + commonjs(), + cleanup(), + terser(terserOptions) + ] +} + +export default production ? [ main, browser, core ] : browser diff --git a/src/alias.js b/src/alias.js index 4a279099..958431ac 100644 --- a/src/alias.js +++ b/src/alias.js @@ -1,18 +1,13 @@ -const { utils } = require('./utils'); - -/** - * - * @param name - * @param source - * @returns {Function} - */ -function alias(name, source) { - const fnString = source.toString(); - return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) { - ${ utils.getFunctionBodyFromString(fnString) } -}`)(); -} - -module.exports = { - alias -}; \ No newline at end of file +import { utils } from './utils'; + +/** + * @param name + * @param source + * @returns {Function} + */ +export function alias(name, source) { + const fnString = source.toString(); + return new Function(`return function ${ name } (${ utils.getArgumentNamesFromString(fnString).join(', ') }) { + ${ utils.getFunctionBodyFromString(fnString) } +}`)(); +} diff --git a/src/backend/cpu/function-node.js b/src/backend/cpu/function-node.js index b3c38d12..bd48ed3f 100644 --- a/src/backend/cpu/function-node.js +++ b/src/backend/cpu/function-node.js @@ -1,649 +1,645 @@ -const { FunctionNode } = require('../function-node'); - -/** - * @desc [INTERNAL] Represents a single function, inside JS - * - *

This handles all the raw state, converted state, etc. Of a single function.

- */ -class CPUFunctionNode extends FunctionNode { - /** - * @desc Parses the abstract syntax tree for to its *named function* - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astFunction(ast, retArr) { - - // Setup function return type and name - if (!this.isRootKernel) { - retArr.push('function'); - retArr.push(' '); - retArr.push(this.name); - retArr.push('('); - - // Arguments handling - for (let i = 0; i < this.argumentNames.length; ++i) { - const argumentName = this.argumentNames[i]; - - if (i > 0) { - retArr.push(', '); - } - retArr.push('user_'); - retArr.push(argumentName); - } - - // Function opening - retArr.push(') {\n'); - } - - // Body statement iteration - for (let i = 0; i < ast.body.body.length; ++i) { - this.astGeneric(ast.body.body[i], retArr); - retArr.push('\n'); - } - - if (!this.isRootKernel) { - // Function closing - retArr.push('}\n'); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for to *return* statement - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astReturnStatement(ast, retArr) { - const type = this.returnType || this.getType(ast.argument); - - if (!this.returnType) { - this.returnType = type; - } - - if (this.isRootKernel) { - retArr.push(this.leadingReturnStatement); - this.astGeneric(ast.argument, retArr); - retArr.push(';\n'); - retArr.push(this.followingReturnStatement); - retArr.push('continue;\n'); - } else if (this.isSubKernel) { - retArr.push(`subKernelResult_${ this.name } = `); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - retArr.push(`return subKernelResult_${ this.name };`); - } else { - retArr.push('return '); - this.astGeneric(ast.argument, retArr); - retArr.push(';'); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *literal value* - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astLiteral(ast, retArr) { - - // Reject non numeric literals - if (isNaN(ast.value)) { - throw this.astErrorOutput( - 'Non-numeric literal not supported : ' + ast.value, - ast - ); - } - - retArr.push(ast.value); - - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *binary* expression - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astBinaryExpression(ast, retArr) { - retArr.push('('); - this.astGeneric(ast.left, retArr); - retArr.push(ast.operator); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *identifier* expression - * @param {Object} idtNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput( - 'IdentifierExpression - not an Identifier', - idtNode - ); - } - - switch (idtNode.name) { - case 'Infinity': - retArr.push('Infinity'); - break; - default: - if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { - retArr.push('constants_' + idtNode.name); - } else { - retArr.push('user_' + idtNode.name); - } - } - - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *for-loop* expression - * @param {Object} forNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the parsed webgl string - */ - astForStatement(forNode, retArr) { - if (forNode.type !== 'ForStatement') { - throw this.astErrorOutput('Invalid for statement', forNode); - } - - const initArr = []; - const testArr = []; - const updateArr = []; - const bodyArr = []; - let isSafe = null; - - if (forNode.init) { - this.pushState('in-for-loop-init'); - this.astGeneric(forNode.init, initArr); - for (let i = 0; i < initArr.length; i++) { - if (initArr[i].includes && initArr[i].includes(',')) { - isSafe = false; - } - } - this.popState('in-for-loop-init'); - } else { - isSafe = false; - } - - if (forNode.test) { - this.astGeneric(forNode.test, testArr); - } else { - isSafe = false; - } - - if (forNode.update) { - this.astGeneric(forNode.update, updateArr); - } else { - isSafe = false; - } - - if (forNode.body) { - this.pushState('loop-body'); - this.astGeneric(forNode.body, bodyArr); - this.popState('loop-body'); - } - - // have all parts, now make them safe - if (isSafe === null) { - isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); - } - - if (isSafe) { - retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); - retArr.push(bodyArr.join('')); - retArr.push('}\n'); - } else { - const iVariableName = this.getInternalVariableName('safeI'); - if (initArr.length > 0) { - retArr.push(initArr.join(''), ';\n'); - } - retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) { - retArr.push(`if (!${testArr.join('')}) break;\n`); - } - retArr.push(bodyArr.join('')); - retArr.push(`\n${updateArr.join('')};`); - retArr.push('}\n'); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *while* loop - * @param {Object} whileNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the parsed javascript string - */ - astWhileStatement(whileNode, retArr) { - if (whileNode.type !== 'WhileStatement') { - throw this.astErrorOutput( - 'Invalid while statement', - whileNode - ); - } - - retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); - retArr.push('if ('); - this.astGeneric(whileNode.test, retArr); - retArr.push(') {\n'); - this.astGeneric(whileNode.body, retArr); - retArr.push('} else {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *do while* loop - * @param {Object} doWhileNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the parsed webgl string - */ - astDoWhileStatement(doWhileNode, retArr) { - if (doWhileNode.type !== 'DoWhileStatement') { - throw this.astErrorOutput( - 'Invalid while statement', - doWhileNode - ); - } - - retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); - this.astGeneric(doWhileNode.body, retArr); - retArr.push('if (!'); - this.astGeneric(doWhileNode.test, retArr); - retArr.push(') {\n'); - retArr.push('break;\n'); - retArr.push('}\n'); - retArr.push('}\n'); - - return retArr; - - } - - /** - * @desc Parses the abstract syntax tree for *Assignment* Expression - * @param {Object} assNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astAssignmentExpression(assNode, retArr) { - const declaration = this.getDeclaration(assNode.left); - if (declaration && !declaration.assignable) { - throw this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode); - } - this.astGeneric(assNode.left, retArr); - retArr.push(assNode.operator); - this.astGeneric(assNode.right, retArr); - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *Block* statement - * @param {Object} bNode - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astBlockStatement(bNode, retArr) { - if (this.isState('loop-body')) { - this.pushState('block-body'); // this prevents recursive removal of braces - for (let i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); - } - this.popState('block-body'); - } else { - retArr.push('{\n'); - for (let i = 0; i < bNode.body.length; i++) { - this.astGeneric(bNode.body[i], retArr); - } - retArr.push('}\n'); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *Variable Declaration* - * @param {Object} varDecNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astVariableDeclaration(varDecNode, retArr) { - if (varDecNode.kind === 'var' && this.warnVarUsage) { - this.varWarn(); - } - retArr.push(`${varDecNode.kind} `); - const { declarations } = varDecNode; - for (let i = 0; i < declarations.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(declarations[i], retArr); - } - if (!this.isState('in-for-loop-init')) { - retArr.push(';'); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *If* Statement - * @param {Object} ifNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astIfStatement(ifNode, retArr) { - retArr.push('if ('); - this.astGeneric(ifNode.test, retArr); - retArr.push(')'); - if (ifNode.consequent.type === 'BlockStatement') { - this.astGeneric(ifNode.consequent, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.consequent, retArr); - retArr.push('\n}\n'); - } - - if (ifNode.alternate) { - retArr.push('else '); - if (ifNode.alternate.type === 'BlockStatement') { - this.astGeneric(ifNode.alternate, retArr); - } else { - retArr.push(' {\n'); - this.astGeneric(ifNode.alternate, retArr); - retArr.push('\n}\n'); - } - } - return retArr; - - } - - astSwitchStatement(ast, retArr) { - const { discriminant, cases } = ast; - retArr.push('switch ('); - this.astGeneric(discriminant, retArr); - retArr.push(') {\n'); - for (let i = 0; i < cases.length; i++) { - if (cases[i].test === null) { - retArr.push('default:\n'); - this.astGeneric(cases[i].consequent, retArr); - if (cases[i].consequent && cases[i].consequent.length > 0) { - retArr.push('break;\n'); - } - continue; - } - retArr.push('case '); - this.astGeneric(cases[i].test, retArr); - retArr.push(':\n'); - if (cases[i].consequent && cases[i].consequent.length > 0) { - this.astGeneric(cases[i].consequent, retArr); - retArr.push('break;\n'); - } - } - retArr.push('\n}'); - } - - /** - * @desc Parses the abstract syntax tree for *This* expression - * @param {Object} tNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astThisExpression(tNode, retArr) { - retArr.push('_this'); - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *Member* Expression - * @param {Object} mNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astMemberExpression(mNode, retArr) { - const { - signature, - type, - property, - xProperty, - yProperty, - zProperty, - name, - origin - } = this.getMemberExpressionDetails(mNode); - switch (signature) { - case 'this.thread.value': - retArr.push(`_this.thread.${ name }`); - return retArr; - case 'this.output.value': - switch (name) { - case 'x': - retArr.push('outputX'); - break; - case 'y': - retArr.push('outputY'); - break; - case 'z': - retArr.push('outputZ'); - break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - return retArr; - case 'value': - throw this.astErrorOutput('Unexpected expression', mNode); - case 'value[]': - case 'value[][]': - case 'value[][][]': - case 'value.value': - if (origin === 'Math') { - retArr.push(Math[name]); - return retArr; - } - switch (property) { - case 'r': - retArr.push(`user_${ name }[0]`); - return retArr; - case 'g': - retArr.push(`user_${ name }[1]`); - return retArr; - case 'b': - retArr.push(`user_${ name }[2]`); - return retArr; - case 'a': - retArr.push(`user_${ name }[3]`); - return retArr; - } - break; - case 'this.constants.value': - case 'this.constants.value[]': - case 'this.constants.value[][]': - case 'this.constants.value[][][]': - break; - case 'fn()[]': - this.astGeneric(mNode.object, retArr); - retArr.push('['); - this.astGeneric(mNode.property, retArr); - retArr.push(']'); - return retArr; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - - if (!mNode.computed) { - // handle simple types - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - retArr.push(`${origin}_${name}`); - return retArr; - } - } - - // handle more complex types - // argument may have come from a parent - const markupName = `${origin}_${name}`; - - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - case 'HTMLImageArray': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'HTMLImage': - default: - let size; - let isInput; - if (origin === 'constants') { - const constant = this.constants[name]; - isInput = this.constantTypes[name] === 'Input'; - size = isInput ? constant.size : null; - } else { - isInput = this.isInput(name); - size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null; - } - retArr.push(`${ markupName }`); - if (zProperty && yProperty) { - if (isInput) { - retArr.push('[('); - this.astGeneric(zProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`); - this.astGeneric(yProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); - this.astGeneric(xProperty, retArr); - retArr.push(']'); - } else { - retArr.push('['); - this.astGeneric(zProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(yProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); - } - } else if (yProperty) { - if (isInput) { - retArr.push('[('); - this.astGeneric(yProperty, retArr); - retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); - this.astGeneric(xProperty, retArr); - retArr.push(']'); - } else { - retArr.push('['); - this.astGeneric(yProperty, retArr); - retArr.push(']'); - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); - } - } else if (typeof xProperty !== 'undefined') { - retArr.push('['); - this.astGeneric(xProperty, retArr); - retArr.push(']'); - } - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *call* expression - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astCallExpression(ast, retArr) { - if (ast.type !== 'CallExpression') { - // Failure, unknown expression - throw this.astErrorOutput('Unknown CallExpression', ast); - } - // Get the full function call, unrolled - let functionName = this.astMemberExpressionUnroll(ast.callee); - - // Register the function into the called registry - if (this.calledFunctions.indexOf(functionName) < 0) { - this.calledFunctions.push(functionName); - } - - const isMathFunction = this.isAstMathFunction(ast); - - // track the function was called - if (this.onFunctionCall) { - this.onFunctionCall(this.name, functionName, ast.arguments); - } - - // Call the function - retArr.push(functionName); - - // Open arguments space - retArr.push('('); - const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; - // Add the arguments - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - - // in order to track return type, even though this is CPU - let argumentType = this.getType(argument); - if (!targetTypes[i]) { - this.triggerImplyArgumentType(functionName, i, argumentType, this); - } - - if (i > 0) { - retArr.push(', '); - } - this.astGeneric(argument, retArr); - } - // Close arguments space - retArr.push(')'); - - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *Array* Expression - * @param {Object} arrNode - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('new Float32Array(['); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - const subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr) - } - retArr.push('])'); - - return retArr; - } - - astDebuggerStatement(arrNode, retArr) { - retArr.push('debugger;'); - return retArr; - } -} - -module.exports = { - CPUFunctionNode -}; \ No newline at end of file +import { FunctionNode } from '../function-node'; + +/** + * @desc [INTERNAL] Represents a single function, inside JS + * + *

This handles all the raw state, converted state, etc. Of a single function.

+ */ +export class CPUFunctionNode extends FunctionNode { + /** + * @desc Parses the abstract syntax tree for to its *named function* + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astFunction(ast, retArr) { + + // Setup function return type and name + if (!this.isRootKernel) { + retArr.push('function'); + retArr.push(' '); + retArr.push(this.name); + retArr.push('('); + + // Arguments handling + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + + if (i > 0) { + retArr.push(', '); + } + retArr.push('user_'); + retArr.push(argumentName); + } + + // Function opening + retArr.push(') {\n'); + } + + // Body statement iteration + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); + } + + if (!this.isRootKernel) { + // Function closing + retArr.push('}\n'); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for to *return* statement + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astReturnStatement(ast, retArr) { + const type = this.returnType || this.getType(ast.argument); + + if (!this.returnType) { + this.returnType = type; + } + + if (this.isRootKernel) { + retArr.push(this.leadingReturnStatement); + this.astGeneric(ast.argument, retArr); + retArr.push(';\n'); + retArr.push(this.followingReturnStatement); + retArr.push('continue;\n'); + } else if (this.isSubKernel) { + retArr.push(`subKernelResult_${ this.name } = `); + this.astGeneric(ast.argument, retArr); + retArr.push(';'); + retArr.push(`return subKernelResult_${ this.name };`); + } else { + retArr.push('return '); + this.astGeneric(ast.argument, retArr); + retArr.push(';'); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *literal value* + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astLiteral(ast, retArr) { + + // Reject non numeric literals + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + + retArr.push(ast.value); + + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *binary* expression + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astBinaryExpression(ast, retArr) { + retArr.push('('); + this.astGeneric(ast.left, retArr); + retArr.push(ast.operator); + this.astGeneric(ast.right, retArr); + retArr.push(')'); + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *identifier* expression + * @param {Object} idtNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); + } + + switch (idtNode.name) { + case 'Infinity': + retArr.push('Infinity'); + break; + default: + if (this.constants && this.constants.hasOwnProperty(idtNode.name)) { + retArr.push('constants_' + idtNode.name); + } else { + retArr.push('user_' + idtNode.name); + } + } + + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *for-loop* expression + * @param {Object} forNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the parsed webgl string + */ + astForStatement(forNode, retArr) { + if (forNode.type !== 'ForStatement') { + throw this.astErrorOutput('Invalid for statement', forNode); + } + + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + + if (forNode.init) { + this.pushState('in-for-loop-init'); + this.astGeneric(forNode.init, initArr); + for (let i = 0; i < initArr.length; i++) { + if (initArr[i].includes && initArr[i].includes(',')) { + isSafe = false; + } + } + this.popState('in-for-loop-init'); + } else { + isSafe = false; + } + + if (forNode.test) { + this.astGeneric(forNode.test, testArr); + } else { + isSafe = false; + } + + if (forNode.update) { + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; + } + + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); + } + + // have all parts, now make them safe + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); + } + + if (isSafe) { + retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); + retArr.push(bodyArr.join('')); + retArr.push('}\n'); + } else { + const iVariableName = this.getInternalVariableName('safeI'); + if (initArr.length > 0) { + retArr.push(initArr.join(''), ';\n'); + } + retArr.push(`for (let ${iVariableName}=0;${iVariableName} 0) { + retArr.push(`if (!${testArr.join('')}) break;\n`); + } + retArr.push(bodyArr.join('')); + retArr.push(`\n${updateArr.join('')};`); + retArr.push('}\n'); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *while* loop + * @param {Object} whileNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the parsed javascript string + */ + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput( + 'Invalid while statement', + whileNode + ); + } + + retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); + retArr.push('if ('); + this.astGeneric(whileNode.test, retArr); + retArr.push(') {\n'); + this.astGeneric(whileNode.body, retArr); + retArr.push('} else {\n'); + retArr.push('break;\n'); + retArr.push('}\n'); + retArr.push('}\n'); + + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *do while* loop + * @param {Object} doWhileNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the parsed webgl string + */ + astDoWhileStatement(doWhileNode, retArr) { + if (doWhileNode.type !== 'DoWhileStatement') { + throw this.astErrorOutput( + 'Invalid while statement', + doWhileNode + ); + } + + retArr.push('for (let i = 0; i < LOOP_MAX; i++) {'); + this.astGeneric(doWhileNode.body, retArr); + retArr.push('if (!'); + this.astGeneric(doWhileNode.test, retArr); + retArr.push(') {\n'); + retArr.push('break;\n'); + retArr.push('}\n'); + retArr.push('}\n'); + + return retArr; + + } + + /** + * @desc Parses the abstract syntax tree for *Assignment* Expression + * @param {Object} assNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astAssignmentExpression(assNode, retArr) { + const declaration = this.getDeclaration(assNode.left); + if (declaration && !declaration.assignable) { + throw new this.astErrorOutput(`Variable ${assNode.left.name} is not assignable here`, assNode); + } + this.astGeneric(assNode.left, retArr); + retArr.push(assNode.operator); + this.astGeneric(assNode.right, retArr); + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *Block* statement + * @param {Object} bNode - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astBlockStatement(bNode, retArr) { + if (this.isState('loop-body')) { + this.pushState('block-body'); // this prevents recursive removal of braces + for (let i = 0; i < bNode.body.length; i++) { + this.astGeneric(bNode.body[i], retArr); + } + this.popState('block-body'); + } else { + retArr.push('{\n'); + for (let i = 0; i < bNode.body.length; i++) { + this.astGeneric(bNode.body[i], retArr); + } + retArr.push('}\n'); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *Variable Declaration* + * @param {Object} varDecNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astVariableDeclaration(varDecNode, retArr) { + if (varDecNode.kind === 'var' && this.warnVarUsage) { + this.varWarn(); + } + retArr.push(`${varDecNode.kind} `); + const { declarations } = varDecNode; + for (let i = 0; i < declarations.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(declarations[i], retArr); + } + if (!this.isState('in-for-loop-init')) { + retArr.push(';'); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *If* Statement + * @param {Object} ifNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astIfStatement(ifNode, retArr) { + retArr.push('if ('); + this.astGeneric(ifNode.test, retArr); + retArr.push(')'); + if (ifNode.consequent.type === 'BlockStatement') { + this.astGeneric(ifNode.consequent, retArr); + } else { + retArr.push(' {\n'); + this.astGeneric(ifNode.consequent, retArr); + retArr.push('\n}\n'); + } + + if (ifNode.alternate) { + retArr.push('else '); + if (ifNode.alternate.type === 'BlockStatement') { + this.astGeneric(ifNode.alternate, retArr); + } else { + retArr.push(' {\n'); + this.astGeneric(ifNode.alternate, retArr); + retArr.push('\n}\n'); + } + } + return retArr; + + } + + astSwitchStatement(ast, retArr) { + const { discriminant, cases } = ast; + retArr.push('switch ('); + this.astGeneric(discriminant, retArr); + retArr.push(') {\n'); + for (let i = 0; i < cases.length; i++) { + if (cases[i].test === null) { + retArr.push('default:\n'); + this.astGeneric(cases[i].consequent, retArr); + if (cases[i].consequent && cases[i].consequent.length > 0) { + retArr.push('break;\n'); + } + continue; + } + retArr.push('case '); + this.astGeneric(cases[i].test, retArr); + retArr.push(':\n'); + if (cases[i].consequent && cases[i].consequent.length > 0) { + this.astGeneric(cases[i].consequent, retArr); + retArr.push('break;\n'); + } + } + retArr.push('\n}'); + } + + /** + * @desc Parses the abstract syntax tree for *This* expression + * @param {Object} tNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astThisExpression(tNode, retArr) { + retArr.push('_this'); + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *Member* Expression + * @param {Object} mNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astMemberExpression(mNode, retArr) { + const { + signature, + type, + property, + xProperty, + yProperty, + zProperty, + name, + origin + } = this.getMemberExpressionDetails(mNode); + switch (signature) { + case 'this.thread.value': + retArr.push(`_this.thread.${ name }`); + return retArr; + case 'this.output.value': + switch (name) { + case 'x': + retArr.push('outputX'); + break; + case 'y': + retArr.push('outputY'); + break; + case 'z': + retArr.push('outputZ'); + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + return retArr; + case 'value': + throw this.astErrorOutput('Unexpected expression', mNode); + case 'value[]': + case 'value[][]': + case 'value[][][]': + case 'value.value': + if (origin === 'Math') { + retArr.push(Math[name]); + return retArr; + } + switch (property) { + case 'r': + retArr.push(`user_${ name }[0]`); + return retArr; + case 'g': + retArr.push(`user_${ name }[1]`); + return retArr; + case 'b': + retArr.push(`user_${ name }[2]`); + return retArr; + case 'a': + retArr.push(`user_${ name }[3]`); + return retArr; + } + break; + case 'this.constants.value': + case 'this.constants.value[]': + case 'this.constants.value[][]': + case 'this.constants.value[][][]': + break; + case 'fn()[]': + this.astGeneric(mNode.object, retArr); + retArr.push('['); + this.astGeneric(mNode.property, retArr); + retArr.push(']'); + return retArr; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + + if (!mNode.computed) { + // handle simple types + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + retArr.push(`${origin}_${name}`); + return retArr; + } + } + + // handle more complex types + // argument may have come from a parent + const markupName = `${origin}_${name}`; + + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + case 'HTMLImageArray': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'HTMLImage': + default: + let size; + let isInput; + if (origin === 'constants') { + const constant = this.constants[name]; + isInput = this.constantTypes[name] === 'Input'; + size = isInput ? constant.size : null; + } else { + isInput = this.isInput(name); + size = isInput ? this.argumentSizes[this.argumentNames.indexOf(name)] : null; + } + retArr.push(`${ markupName }`); + if (zProperty && yProperty) { + if (isInput) { + retArr.push('[('); + this.astGeneric(zProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? '(outputY * outputX)' : size[1] * size[0] })+(`); + this.astGeneric(yProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } else { + retArr.push('['); + this.astGeneric(zProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(yProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } + } else if (yProperty) { + if (isInput) { + retArr.push('[('); + this.astGeneric(yProperty, retArr); + retArr.push(`*${ this.dynamicArguments ? 'outputX' : size[0] })+`); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } else { + retArr.push('['); + this.astGeneric(yProperty, retArr); + retArr.push(']'); + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } + } else if (typeof xProperty !== 'undefined') { + retArr.push('['); + this.astGeneric(xProperty, retArr); + retArr.push(']'); + } + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *call* expression + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astCallExpression(ast, retArr) { + if (ast.type !== 'CallExpression') { + // Failure, unknown expression + throw this.astErrorOutput('Unknown CallExpression', ast); + } + // Get the full function call, unrolled + let functionName = this.astMemberExpressionUnroll(ast.callee); + + // Register the function into the called registry + if (this.calledFunctions.indexOf(functionName) < 0) { + this.calledFunctions.push(functionName); + } + + const isMathFunction = this.isAstMathFunction(ast); + + // track the function was called + if (this.onFunctionCall) { + this.onFunctionCall(this.name, functionName, ast.arguments); + } + + // Call the function + retArr.push(functionName); + + // Open arguments space + retArr.push('('); + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + // Add the arguments + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + + // in order to track return type, even though this is CPU + let argumentType = this.getType(argument); + if (!targetTypes[i]) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); + } + + if (i > 0) { + retArr.push(', '); + } + this.astGeneric(argument, retArr); + } + // Close arguments space + retArr.push(')'); + + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *Array* Expression + * @param {Object} arrNode - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astArrayExpression(arrNode, retArr) { + const arrLen = arrNode.elements.length; + + retArr.push('new Float32Array(['); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + this.astGeneric(subNode, retArr) + } + retArr.push('])'); + + return retArr; + } + + astDebuggerStatement(arrNode, retArr) { + retArr.push('debugger;'); + return retArr; + } +} diff --git a/src/backend/cpu/kernel-string.js b/src/backend/cpu/kernel-string.js index 166e124d..ddc3851c 100644 --- a/src/backend/cpu/kernel-string.js +++ b/src/backend/cpu/kernel-string.js @@ -1,179 +1,175 @@ -const { utils } = require('../../utils'); - -function constantsToString(constants, types) { - const results = []; - for (const name in types) { - if (!types.hasOwnProperty(name)) continue; - const type = types[name]; - const constant = constants[name]; - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - results.push(`${name}:${constant}`); - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); - break; - } - } - return `{ ${ results.join() } }`; -} - -function cpuKernelString(cpuKernel, name) { - const header = []; - const thisProperties = []; - const beforeReturn = []; - - const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString()); - - header.push( - ' const { context, canvas, constants: incomingConstants } = settings;', - ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`, - ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`, - ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`, - ); - - thisProperties.push( - ' constants: _constants,', - ' context,', - ' output,', - ' thread: {x: 0, y: 0, z: 0},', - ); - - if (cpuKernel.graphical) { - header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`); - header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`); - - const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), { - thisLookup: (propertyName) => { - switch (propertyName) { - case '_colorData': - return '_colorData'; - case '_imageData': - return '_imageData'; - case 'output': - return 'output'; - case 'thread': - return 'this.thread'; - } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: (object, name) => { - return null; - } - }); - - const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), { - thisLookup: (propertyName) => { - switch (propertyName) { - case '_colorData': - return '_colorData'; - case '_imageData': - return '_imageData'; - case 'output': - return 'output'; - case 'thread': - return 'this.thread'; - } - return JSON.stringify(cpuKernel[propertyName]); - }, - findDependency: () => { - return null; - } - }); - - thisProperties.push( - ' _imageData,', - ' _colorData,', - ` color: ${colorFn},`, - ); - - beforeReturn.push( - ` kernel.getPixels = ${getPixelsFn};` - ); - } - - const constantTypes = []; - const constantKeys = Object.keys(cpuKernel.constantTypes); - for (let i = 0; i < constantKeys.length; i++) { - constantTypes.push(cpuKernel.constantTypes[constantKeys]); - } - if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) { - const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), { - doNotDefine: ['canvas'], - findDependency: (object, name) => { - if (object === 'this') { - return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString(); - } - return null; - }, - thisLookup: (propertyName) => { - switch (propertyName) { - case 'canvas': - return; - case 'context': - return 'context'; - } - } - }); - beforeReturn.push(flattenedImageTo3DArray); - thisProperties.push(` _mediaTo2DArray,`); - thisProperties.push(` _imageTo3DArray,`); - } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) { - const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), { - findDependency: (object, name) => { - return null; - }, - thisLookup: (propertyName) => { - switch (propertyName) { - case 'canvas': - return 'settings.canvas'; - case 'context': - return 'settings.context'; - } - throw new Error('unhandled thisLookup'); - } - }); - beforeReturn.push(flattenedImageTo2DArray); - thisProperties.push(` _mediaTo2DArray,`); - } - - return `function(settings) { -${ header.join('\n') } - for (const p in _constantTypes) { - if (!_constantTypes.hasOwnProperty(p)) continue; - const type = _constantTypes[p]; - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - if (incomingConstants.hasOwnProperty(p)) { - console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); - } - continue; - } - if (!incomingConstants.hasOwnProperty(p)) { - throw new Error('constant ' + p + ' not found'); - } - _constants[p] = incomingConstants[p]; - } - const kernel = (function() { -${cpuKernel._kernelString} - }) - .apply({ ${thisProperties.join('\n')} }); - ${ beforeReturn.join('\n') } - return kernel; -}`; -} - -module.exports = { - cpuKernelString -}; \ No newline at end of file +import { utils } from '../../utils' + +function constantsToString(constants, types) { + const results = []; + for (const name in types) { + if (!types.hasOwnProperty(name)) continue; + const type = types[name]; + const constant = constants[name]; + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + results.push(`${name}:${constant}`); + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + results.push(`${name}:new ${constant.constructor.name}(${JSON.stringify(Array.from(constant))})`); + break; + } + } + return `{ ${ results.join() } }`; +} + +export function cpuKernelString(cpuKernel, name) { + const header = []; + const thisProperties = []; + const beforeReturn = []; + + const useFunctionKeyword = !/^function/.test(cpuKernel.color.toString()); + + header.push( + ' const { context, canvas, constants: incomingConstants } = settings;', + ` const output = new Int32Array(${JSON.stringify(Array.from(cpuKernel.output))});`, + ` const _constantTypes = ${JSON.stringify(cpuKernel.constantTypes)};`, + ` const _constants = ${constantsToString(cpuKernel.constants, cpuKernel.constantTypes)};`, + ); + + thisProperties.push( + ' constants: _constants,', + ' context,', + ' output,', + ' thread: {x: 0, y: 0, z: 0},', + ); + + if (cpuKernel.graphical) { + header.push(` const _imageData = context.createImageData(${cpuKernel.output[0]}, ${cpuKernel.output[1]});`); + header.push(` const _colorData = new Uint8ClampedArray(${cpuKernel.output[0]} * ${cpuKernel.output[1]} * 4);`); + + const colorFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.color.toString(), { + thisLookup: (propertyName) => { + switch (propertyName) { + case '_colorData': + return '_colorData'; + case '_imageData': + return '_imageData'; + case 'output': + return 'output'; + case 'thread': + return 'this.thread'; + } + return JSON.stringify(cpuKernel[propertyName]); + }, + findDependency: (object, name) => { + return null; + } + }); + + const getPixelsFn = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel.getPixels.toString(), { + thisLookup: (propertyName) => { + switch (propertyName) { + case '_colorData': + return '_colorData'; + case '_imageData': + return '_imageData'; + case 'output': + return 'output'; + case 'thread': + return 'this.thread'; + } + return JSON.stringify(cpuKernel[propertyName]); + }, + findDependency: () => { + return null; + } + }); + + thisProperties.push( + ' _imageData,', + ' _colorData,', + ` color: ${colorFn},`, + ); + + beforeReturn.push( + ` kernel.getPixels = ${getPixelsFn};` + ); + } + + const constantTypes = []; + const constantKeys = Object.keys(cpuKernel.constantTypes); + for (let i = 0; i < constantKeys.length; i++) { + constantTypes.push(cpuKernel.constantTypes[constantKeys]); + } + if (cpuKernel.argumentTypes.indexOf('HTMLImageArray') !== -1 || constantTypes.indexOf('HTMLImageArray') !== -1) { + const flattenedImageTo3DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._imageTo3DArray.toString(), { + doNotDefine: ['canvas'], + findDependency: (object, name) => { + if (object === 'this') { + return (useFunctionKeyword ? 'function ' : '') + cpuKernel[name].toString(); + } + return null; + }, + thisLookup: (propertyName) => { + switch (propertyName) { + case 'canvas': + return; + case 'context': + return 'context'; + } + } + }); + beforeReturn.push(flattenedImageTo3DArray); + thisProperties.push(` _mediaTo2DArray,`); + thisProperties.push(` _imageTo3DArray,`); + } else if (cpuKernel.argumentTypes.indexOf('HTMLImage') !== -1 || constantTypes.indexOf('HTMLImage') !== -1) { + const flattenedImageTo2DArray = utils.flattenFunctionToString((useFunctionKeyword ? 'function ' : '') + cpuKernel._mediaTo2DArray.toString(), { + findDependency: (object, name) => { + return null; + }, + thisLookup: (propertyName) => { + switch (propertyName) { + case 'canvas': + return 'settings.canvas'; + case 'context': + return 'settings.context'; + } + throw new Error('unhandled thisLookup'); + } + }); + beforeReturn.push(flattenedImageTo2DArray); + thisProperties.push(` _mediaTo2DArray,`); + } + + return `function(settings) { +${ header.join('\n') } + for (const p in _constantTypes) { + if (!_constantTypes.hasOwnProperty(p)) continue; + const type = _constantTypes[p]; + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + if (incomingConstants.hasOwnProperty(p)) { + console.warn('constant ' + p + ' of type ' + type + ' cannot be resigned'); + } + continue; + } + if (!incomingConstants.hasOwnProperty(p)) { + throw new Error('constant ' + p + ' not found'); + } + _constants[p] = incomingConstants[p]; + } + const kernel = (function() { +${cpuKernel._kernelString} + }) + .apply({ ${thisProperties.join('\n')} }); + ${ beforeReturn.join('\n') } + return kernel; +}`; +} diff --git a/src/backend/cpu/kernel.js b/src/backend/cpu/kernel.js index 07242dde..b0c853c5 100644 --- a/src/backend/cpu/kernel.js +++ b/src/backend/cpu/kernel.js @@ -1,536 +1,532 @@ -const { Kernel } = require('../kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { CPUFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const { cpuKernelString } = require('./kernel-string'); - -/** - * @desc Kernel Implementation for CPU. - *

Instantiates properties to the CPU Kernel.

- */ -class CPUKernel extends Kernel { - static getFeatures() { - return this.features; - } - static get features() { - return Object.freeze({ - kernelMap: true, - isIntegerDivisionAccurate: true - }); - } - static get isSupported() { - return true; - } - static isContextMatch(context) { - return false; - } - /** - * @desc The current mode in which gpu.js is executing. - */ - static get mode() { - return 'cpu'; - } - - static nativeFunctionArguments() { - return null; - } - - static nativeFunctionReturnType() { - return null; - } - - static combineKernels(combinedKernel) { - return combinedKernel; - } - - constructor(source, settings) { - super(source, settings); - this.mergeSettings(source.settings || settings); - - this._imageData = null; - this._colorData = null; - this._kernelString = null; - this.thread = { - x: 0, - y: 0, - z: 0 - }; - this.translatedSources = null; - } - - initCanvas() { - if (typeof document !== 'undefined') { - return document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - return new OffscreenCanvas(0, 0); - } - } - - initContext() { - if (!this.canvas) return null; - return this.canvas.getContext('2d'); - } - - initPlugins(settings) { - return []; - } - - /** - * @desc Validate settings related to Kernel, such as dimensions size, and auto output support. - * @param {IArguments} args - */ - validateSettings(args) { - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); - } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { - this.output = args[0].output; - } else { - throw new Error('Auto output not supported for input type: ' + argType); - } - } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); - } - } - - this.checkOutput(); - } - - translateSource() { - this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = '; - if (this.subKernels) { - const followingReturnStatement = [] - for (let i = 0; i < this.subKernels.length; i++) { - const { - name - } = this.subKernels[i]; - followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`); - } - this.followingReturnStatement = followingReturnStatement.join(''); - } - const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); - this.translatedSources = functionBuilder.getPrototypes('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - } - - /** - * @desc Builds the Kernel, by generating the kernel - * string using thread dimensions, and arguments - * supplied to the kernel. - * - *

If the graphical flag is enabled, canvas is used.

- */ - build() { - this.setupConstants(); - this.setupArguments(arguments); - this.validateSettings(arguments); - this.translateSource(); - - if (this.graphical) { - const { - canvas, - output - } = this; - if (!canvas) { - throw new Error('no canvas available for using graphical output'); - } - const width = output[0]; - const height = output[1] || 1; - canvas.width = width; - canvas.height = height; - this._imageData = this.context.createImageData(width, height); - this._colorData = new Uint8ClampedArray(width * height * 4); - } - - const kernelString = this.getKernelString(); - this.kernelString = kernelString; - - if (this.debug) { - console.log('Function output:'); - console.log(kernelString); - } - - try { - this.run = new Function([], kernelString).bind(this)(); - } catch (e) { - console.error('An error occurred compiling the javascript: ', e); - } - } - - color(r, g, b, a) { - if (typeof a === 'undefined') { - a = 1; - } - - r = Math.floor(r * 255); - g = Math.floor(g * 255); - b = Math.floor(b * 255); - a = Math.floor(a * 255); - - const width = this.output[0]; - const height = this.output[1]; - - const x = this.thread.x; - const y = height - this.thread.y - 1; - - const index = x + y * width; - - this._colorData[index * 4 + 0] = r; - this._colorData[index * 4 + 1] = g; - this._colorData[index * 4 + 2] = b; - this._colorData[index * 4 + 3] = a; - } - - /** - * @desc Generates kernel string for this kernel program. - * - *

If sub-kernels are supplied, they are also factored in. - * This string can be saved by calling the `toString` method - * and then can be reused later.

- * - * @returns {String} result - * - */ - getKernelString() { - if (this._kernelString !== null) return this._kernelString; - - let kernelThreadString = null; - let { - translatedSources - } = this; - if (translatedSources.length > 1) { - translatedSources = translatedSources.filter(fn => { - if (/^function/.test(fn)) return fn; - kernelThreadString = fn; - return false; - }) - } else { - kernelThreadString = translatedSources.shift(); - } - return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() }; - ${ this.injectedNative || '' } - const _this = this; - ${ this._processConstants() } - return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { - ${ this._processArguments() } - ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) } - ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' } - };`; - } - - /** - * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused. - */ - toString() { - return cpuKernelString(this); - } - - /** - * @desc Get the maximum loop size String. - * @returns {String} result - */ - _getLoopMaxString() { - return ( - this.loopMaxIterations ? - ` ${ parseInt(this.loopMaxIterations) };` : - ' 1000;' - ); - } - - _processConstants() { - if (!this.constants) return ''; - - const result = []; - for (let p in this.constants) { - const type = this.constantTypes[p]; - switch (type) { - case 'HTMLImage': - case 'HTMLVideo': - result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`); - break; - case 'HTMLImageArray': - result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`); - break; - case 'Input': - result.push(` const constants_${p} = this.constants.${p}.value;\n`); - break; - default: - result.push(` const constants_${p} = this.constants.${p};\n`); - } - } - return result.join(''); - } - - _processArguments() { - const result = []; - for (let i = 0; i < this.argumentTypes.length; i++) { - const variableName = `user_${this.argumentNames[i]}`; - switch (this.argumentTypes[i]) { - case 'HTMLImage': - case 'HTMLVideo': - result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`); - break; - case 'HTMLImageArray': - result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`); - break; - case 'Input': - result.push(` ${variableName} = ${variableName}.value;\n`); - break; - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'NumberTexture': - case 'MemoryOptimizedNumberTexture': - result.push(` - if (${variableName}.toArray) { - if (!_this.textureCache) { - _this.textureCache = []; - _this.arrayCache = []; - } - const textureIndex = _this.textureCache.indexOf(${variableName}); - if (textureIndex !== -1) { - ${variableName} = _this.arrayCache[textureIndex]; - } else { - _this.textureCache.push(${variableName}); - ${variableName} = ${variableName}.toArray(); - _this.arrayCache.push(${variableName}); - } - }`); - break; - } - } - return result.join(''); - } - - _mediaTo2DArray(media) { - const canvas = this.canvas; - const width = media.width > 0 ? media.width : media.videoWidth; - const height = media.height > 0 ? media.height : media.videoHeight; - if (canvas.width < width) { - canvas.width = width; - } - if (canvas.height < height) { - canvas.height = height; - } - const ctx = this.context; - ctx.drawImage(media, 0, 0, width, height); - const pixelsData = ctx.getImageData(0, 0, width, height).data; - const imageArray = new Array(height); - let index = 0; - for (let y = height - 1; y >= 0; y--) { - const row = imageArray[y] = new Array(width); - for (let x = 0; x < width; x++) { - const pixel = new Float32Array(4); - pixel[0] = pixelsData[index++] / 255; // r - pixel[1] = pixelsData[index++] / 255; // g - pixel[2] = pixelsData[index++] / 255; // b - pixel[3] = pixelsData[index++] / 255; // a - row[x] = pixel; - } - } - return imageArray; - } - - getPixels(flip) { - const [width, height] = this.output; - // cpu is not flipped by default - return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0); - } - - _imageTo3DArray(images) { - const imagesArray = new Array(images.length); - for (let i = 0; i < images.length; i++) { - imagesArray[i] = this._mediaTo2DArray(images[i]); - } - return imagesArray; - } - - _resultKernelBody(kernelString) { - switch (this.output.length) { - case 1: - return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); - case 2: - return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); - case 3: - return this._resultKernel3DLoop(kernelString) + this._kernelOutput(); - default: - throw new Error('unsupported size kernel'); - } - } - - _graphicalKernelBody(kernelThreadString) { - switch (this.output.length) { - case 2: - return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput(); - default: - throw new Error('unsupported size kernel'); - } - } - - _graphicalOutput() { - return ` - this._imageData.data.set(this._colorData); - this.context.putImageData(this._imageData, 0, 0); - return;` - } - - _getKernelResultTypeConstructorString() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return 'Float32Array'; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return 'Array'; - default: - if (this.graphical) { - return 'Float32Array'; - } - throw new Error(`unhandled returnType ${ this.returnType }`); - } - } - - _resultKernel1DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const result = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - this.thread.y = 0; - this.thread.z = 0; - ${ kernelString } - }`; - } - - _resultKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const result = new Array(outputY); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - const resultX = result[y] = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } - } - }`; - } - - _graphicalKernel2DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.z = 0; - this.thread.y = y; - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } - } - }`; - } - - _resultKernel3DLoop(kernelString) { - const { - output - } = this; - const constructorString = this._getKernelResultTypeConstructorString(); - return ` const outputX = _this.output[0]; - const outputY = _this.output[1]; - const outputZ = _this.output[2]; - const result = new Array(outputZ); - ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') } - ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } - for (let z = 0; z < outputZ; z++) { - this.thread.z = z; - const resultY = result[z] = new Array(outputY); - ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') } - for (let y = 0; y < outputY; y++) { - this.thread.y = y; - const resultX = resultY[y] = new ${constructorString}(outputX); - ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') } - for (let x = 0; x < outputX; x++) { - this.thread.x = x; - ${ kernelString } - } - } - }`; - } - - _kernelOutput() { - if (!this.subKernels) { - return '\n return result;'; - } - return `\n return { - result: result, - ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') } - };`; - } - - _mapSubKernels(fn) { - return this.subKernels === null ? [''] : - this.subKernels.map(fn); - } - - - - destroy(removeCanvasReference) { - if (removeCanvasReference) { - delete this.canvas; - } - } - - static destroyContext(context) {} - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON(); - return json; - } - - setOutput(output) { - super.setOutput(output); - const [width, height] = this.output; - if (this.graphical) { - this._imageData = this.context.createImageData(width, height); - this._colorData = new Uint8ClampedArray(width * height * 4); - } - } -} - -module.exports = { - CPUKernel -}; \ No newline at end of file +import { Kernel } from '../kernel'; +import { FunctionBuilder } from '../function-builder'; +import { CPUFunctionNode } from './function-node'; +import { utils } from '../../utils'; +import { cpuKernelString } from './kernel-string'; + +/** + * @desc Kernel Implementation for CPU. + *

Instantiates properties to the CPU Kernel.

+ */ +export class CPUKernel extends Kernel { + static getFeatures() { + return this.features; + } + static get features() { + return Object.freeze({ + kernelMap: true, + isIntegerDivisionAccurate: true + }); + } + static get isSupported() { + return true; + } + static isContextMatch(context) { + return false; + } + /** + * @desc The current mode in which gpu.js is executing. + */ + static get mode() { + return 'cpu'; + } + + static nativeFunctionArguments() { + return null; + } + + static nativeFunctionReturnType() { + return null; + } + + static combineKernels(combinedKernel) { + return combinedKernel; + } + + constructor(source, settings) { + super(source, settings); + this.mergeSettings(source.settings || settings); + + this._imageData = null; + this._colorData = null; + this._kernelString = null; + this.thread = { + x: 0, + y: 0, + z: 0 + }; + this.translatedSources = null; + } + + initCanvas() { + if (typeof document !== 'undefined') { + return document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + return new OffscreenCanvas(0, 0); + } + } + + initContext() { + if (!this.canvas) return null; + return this.canvas.getContext('2d'); + } + + initPlugins(settings) { + return []; + } + + /** + * @desc Validate settings related to Kernel, such as dimensions size, and auto output support. + * @param {IArguments} args + */ + validateSettings(args) { + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + + const argType = utils.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils.getDimensions(argType); + } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { + this.output = args[0].output; + } else { + throw new Error('Auto output not supported for input type: ' + argType); + } + } + + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); + } + } + + this.checkOutput(); + } + + translateSource() { + this.leadingReturnStatement = this.output.length > 1 ? 'resultX[x] = ' : 'result[x] = '; + if (this.subKernels) { + const followingReturnStatement = [] + for (let i = 0; i < this.subKernels.length; i++) { + const { + name + } = this.subKernels[i]; + followingReturnStatement.push(this.output.length > 1 ? `resultX_${ name }[x] = subKernelResult_${ name };\n` : `result_${ name }[x] = subKernelResult_${ name };\n`); + } + this.followingReturnStatement = followingReturnStatement.join(''); + } + const functionBuilder = FunctionBuilder.fromKernel(this, CPUFunctionNode); + this.translatedSources = functionBuilder.getPrototypes('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + } + + /** + * @desc Builds the Kernel, by generating the kernel + * string using thread dimensions, and arguments + * supplied to the kernel. + * + *

If the graphical flag is enabled, canvas is used.

+ */ + build() { + this.setupConstants(); + this.setupArguments(arguments); + this.validateSettings(arguments); + this.translateSource(); + + if (this.graphical) { + const { + canvas, + output + } = this; + if (!canvas) { + throw new Error('no canvas available for using graphical output'); + } + const width = output[0]; + const height = output[1] || 1; + canvas.width = width; + canvas.height = height; + this._imageData = this.context.createImageData(width, height); + this._colorData = new Uint8ClampedArray(width * height * 4); + } + + const kernelString = this.getKernelString(); + this.kernelString = kernelString; + + if (this.debug) { + console.log('Function output:'); + console.log(kernelString); + } + + try { + this.run = new Function([], kernelString).bind(this)(); + } catch (e) { + console.error('An error occurred compiling the javascript: ', e); + } + } + + color(r, g, b, a) { + if (typeof a === 'undefined') { + a = 1; + } + + r = Math.floor(r * 255); + g = Math.floor(g * 255); + b = Math.floor(b * 255); + a = Math.floor(a * 255); + + const width = this.output[0]; + const height = this.output[1]; + + const x = this.thread.x; + const y = height - this.thread.y - 1; + + const index = x + y * width; + + this._colorData[index * 4 + 0] = r; + this._colorData[index * 4 + 1] = g; + this._colorData[index * 4 + 2] = b; + this._colorData[index * 4 + 3] = a; + } + + /** + * @desc Generates kernel string for this kernel program. + * + *

If sub-kernels are supplied, they are also factored in. + * This string can be saved by calling the `toString` method + * and then can be reused later.

+ * + * @returns {String} result + * + */ + getKernelString() { + if (this._kernelString !== null) return this._kernelString; + + let kernelThreadString = null; + let { + translatedSources + } = this; + if (translatedSources.length > 1) { + translatedSources = translatedSources.filter(fn => { + if (/^function/.test(fn)) return fn; + kernelThreadString = fn; + return false; + }) + } else { + kernelThreadString = translatedSources.shift(); + } + return this._kernelString = ` const LOOP_MAX = ${ this._getLoopMaxString() }; + ${ this.injectedNative || '' } + const _this = this; + ${ this._processConstants() } + return (${ this.argumentNames.map(argumentName => 'user_' + argumentName).join(', ') }) => { + ${ this._processArguments() } + ${ this.graphical ? this._graphicalKernelBody(kernelThreadString) : this._resultKernelBody(kernelThreadString) } + ${ translatedSources.length > 0 ? translatedSources.join('\n') : '' } + };`; + } + + /** + * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused. + */ + toString() { + return cpuKernelString(this); + } + + /** + * @desc Get the maximum loop size String. + * @returns {String} result + */ + _getLoopMaxString() { + return ( + this.loopMaxIterations ? + ` ${ parseInt(this.loopMaxIterations) };` : + ' 1000;' + ); + } + + _processConstants() { + if (!this.constants) return ''; + + const result = []; + for (let p in this.constants) { + const type = this.constantTypes[p]; + switch (type) { + case 'HTMLImage': + case 'HTMLVideo': + result.push(` const constants_${p} = this._mediaTo2DArray(this.constants.${p});\n`); + break; + case 'HTMLImageArray': + result.push(` const constants_${p} = this._imageTo3DArray(this.constants.${p});\n`); + break; + case 'Input': + result.push(` const constants_${p} = this.constants.${p}.value;\n`); + break; + default: + result.push(` const constants_${p} = this.constants.${p};\n`); + } + } + return result.join(''); + } + + _processArguments() { + const result = []; + for (let i = 0; i < this.argumentTypes.length; i++) { + const variableName = `user_${this.argumentNames[i]}`; + switch (this.argumentTypes[i]) { + case 'HTMLImage': + case 'HTMLVideo': + result.push(` ${variableName} = this._mediaTo2DArray(${variableName});\n`); + break; + case 'HTMLImageArray': + result.push(` ${variableName} = this._imageTo3DArray(${variableName});\n`); + break; + case 'Input': + result.push(` ${variableName} = ${variableName}.value;\n`); + break; + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'NumberTexture': + case 'MemoryOptimizedNumberTexture': + result.push(` + if (${variableName}.toArray) { + if (!_this.textureCache) { + _this.textureCache = []; + _this.arrayCache = []; + } + const textureIndex = _this.textureCache.indexOf(${variableName}); + if (textureIndex !== -1) { + ${variableName} = _this.arrayCache[textureIndex]; + } else { + _this.textureCache.push(${variableName}); + ${variableName} = ${variableName}.toArray(); + _this.arrayCache.push(${variableName}); + } + }`); + break; + } + } + return result.join(''); + } + + _mediaTo2DArray(media) { + const canvas = this.canvas; + const width = media.width > 0 ? media.width : media.videoWidth; + const height = media.height > 0 ? media.height : media.videoHeight; + if (canvas.width < width) { + canvas.width = width; + } + if (canvas.height < height) { + canvas.height = height; + } + const ctx = this.context; + ctx.drawImage(media, 0, 0, width, height); + const pixelsData = ctx.getImageData(0, 0, width, height).data; + const imageArray = new Array(height); + let index = 0; + for (let y = height - 1; y >= 0; y--) { + const row = imageArray[y] = new Array(width); + for (let x = 0; x < width; x++) { + const pixel = new Float32Array(4); + pixel[0] = pixelsData[index++] / 255; // r + pixel[1] = pixelsData[index++] / 255; // g + pixel[2] = pixelsData[index++] / 255; // b + pixel[3] = pixelsData[index++] / 255; // a + row[x] = pixel; + } + } + return imageArray; + } + + getPixels(flip) { + const [width, height] = this.output; + // cpu is not flipped by default + return flip ? utils.flipPixels(this._imageData.data, width, height) : this._imageData.data.slice(0); + } + + _imageTo3DArray(images) { + const imagesArray = new Array(images.length); + for (let i = 0; i < images.length; i++) { + imagesArray[i] = this._mediaTo2DArray(images[i]); + } + return imagesArray; + } + + _resultKernelBody(kernelString) { + switch (this.output.length) { + case 1: + return this._resultKernel1DLoop(kernelString) + this._kernelOutput(); + case 2: + return this._resultKernel2DLoop(kernelString) + this._kernelOutput(); + case 3: + return this._resultKernel3DLoop(kernelString) + this._kernelOutput(); + default: + throw new Error('unsupported size kernel'); + } + } + + _graphicalKernelBody(kernelThreadString) { + switch (this.output.length) { + case 2: + return this._graphicalKernel2DLoop(kernelThreadString) + this._graphicalOutput(); + default: + throw new Error('unsupported size kernel'); + } + } + + _graphicalOutput() { + return ` + this._imageData.data.set(this._colorData); + this.context.putImageData(this._imageData, 0, 0); + return;` + } + + _getKernelResultTypeConstructorString() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return 'Float32Array'; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return 'Array'; + default: + if (this.graphical) { + return 'Float32Array'; + } + throw new Error(`unhandled returnType ${ this.returnType }`); + } + } + + _resultKernel1DLoop(kernelString) { + const { + output + } = this; + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const result = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new ${constructorString}(outputX);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + this.thread.y = 0; + this.thread.z = 0; + ${ kernelString } + }`; + } + + _resultKernel2DLoop(kernelString) { + const { + output + } = this; + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const result = new Array(outputY); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + const resultX = result[y] = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + }`; + } + + _graphicalKernel2DLoop(kernelString) { + const { + output + } = this; + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputY);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.z = 0; + this.thread.y = y; + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = result_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join('') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + }`; + } + + _resultKernel3DLoop(kernelString) { + const { + output + } = this; + const constructorString = this._getKernelResultTypeConstructorString(); + return ` const outputX = _this.output[0]; + const outputY = _this.output[1]; + const outputZ = _this.output[2]; + const result = new Array(outputZ); + ${ this._mapSubKernels(subKernel => `const result_${ subKernel.name } = new Array(outputZ);\n`).join(' ') } + ${ this._mapSubKernels(subKernel => `let subKernelResult_${ subKernel.name };\n`).join(' ') } + for (let z = 0; z < outputZ; z++) { + this.thread.z = z; + const resultY = result[z] = new Array(outputY); + ${ this._mapSubKernels(subKernel => `const resultY_${ subKernel.name } = result_${subKernel.name}[z] = new Array(outputY);\n`).join(' ') } + for (let y = 0; y < outputY; y++) { + this.thread.y = y; + const resultX = resultY[y] = new ${constructorString}(outputX); + ${ this._mapSubKernels(subKernel => `const resultX_${ subKernel.name } = resultY_${subKernel.name}[y] = new ${constructorString}(outputX);\n`).join(' ') } + for (let x = 0; x < outputX; x++) { + this.thread.x = x; + ${ kernelString } + } + } + }`; + } + + _kernelOutput() { + if (!this.subKernels) { + return '\n return result;'; + } + return `\n return { + result: result, + ${ this.subKernels.map(subKernel => `${ subKernel.property }: result_${ subKernel.name }`).join(',\n ') } + };`; + } + + _mapSubKernels(fn) { + return this.subKernels === null ? [''] : + this.subKernels.map(fn); + } + + + + destroy(removeCanvasReference) { + if (removeCanvasReference) { + delete this.canvas; + } + } + + static destroyContext(context) {} + + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, CPUFunctionNode).toJSON(); + return json; + } + + setOutput(output) { + super.setOutput(output); + const [width, height] = this.output; + if (this.graphical) { + this._imageData = this.context.createImageData(width, height); + this._colorData = new Uint8ClampedArray(width * height * 4); + } + } +} diff --git a/src/backend/function-builder.js b/src/backend/function-builder.js index 89bb3c07..610e7705 100644 --- a/src/backend/function-builder.js +++ b/src/backend/function-builder.js @@ -1,621 +1,664 @@ -/** - * @desc This handles all the raw state, converted state, etc. of a single function. - * [INTERNAL] A collection of functionNodes. - * @class - */ -class FunctionBuilder { - /** - * - * @param {Kernel} kernel - * @param {FunctionNode} FunctionNode - * @param {object} [extraNodeOptions] - * @returns {FunctionBuilder} - * @static - */ - static fromKernel(kernel, FunctionNode, extraNodeOptions) { - const { - kernelArguments, - kernelConstants, - argumentNames, - argumentSizes, - argumentBitRatios, - constants, - constantBitRatios, - debug, - loopMaxIterations, - nativeFunctions, - output, - optimizeFloatMemory, - precision, - plugins, - source, - subKernels, - functions, - leadingReturnStatement, - followingReturnStatement, - dynamicArguments, - dynamicOutput, - warnVarUsage, - } = kernel; - - const argumentTypes = new Array(kernelArguments.length); - const constantTypes = {}; - - for (let i = 0; i < kernelArguments.length; i++) { - argumentTypes[i] = kernelArguments[i].type; - } - - for (let i = 0; i < kernelConstants.length; i++) { - const kernelConstant = kernelConstants[i]; - constantTypes[kernelConstant.name] = kernelConstant.type; - } - - const needsArgumentType = (functionName, index) => { - return functionBuilder.needsArgumentType(functionName, index); - }; - - const assignArgumentType = (functionName, index, type) => { - functionBuilder.assignArgumentType(functionName, index, type); - }; - - const lookupReturnType = (functionName, ast, requestingNode) => { - return functionBuilder.lookupReturnType(functionName, ast, requestingNode); - }; - - const lookupFunctionArgumentTypes = (functionName) => { - return functionBuilder.lookupFunctionArgumentTypes(functionName); - }; - - const lookupFunctionArgumentName = (functionName, argumentIndex) => { - return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex); - }; - - const lookupFunctionArgumentBitRatio = (functionName, argumentName) => { - return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName); - }; - - const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => { - functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode); - }; - - const triggerImplyArgumentBitRatio = (functionName, argumentName, calleeFunctionName, argumentIndex) => { - functionBuilder.assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex); - }; - - const onFunctionCall = (functionName, calleeFunctionName, args) => { - functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); - }; - - const onNestedFunction = (ast, returnType) => { - const argumentNames = []; - for (let i = 0; i < ast.params.length; i++) { - argumentNames.push(ast.params[i].name); - } - const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { - returnType: null, - ast, - name: ast.id.name, - argumentNames, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - warnVarUsage, - })); - nestedFunction.traceFunctionAST(ast); - functionBuilder.addFunctionNode(nestedFunction); - }; - - const nodeOptions = Object.assign({ - isRootKernel: false, - onNestedFunction, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - optimizeFloatMemory, - precision, - constants, - constantTypes, - constantBitRatios, - debug, - loopMaxIterations, - output, - plugins, - dynamicArguments, - dynamicOutput, - }, extraNodeOptions || {}); - - const rootNodeOptions = Object.assign({}, nodeOptions, { - isRootKernel: true, - name: 'kernel', - argumentNames, - argumentTypes, - argumentSizes, - argumentBitRatios, - leadingReturnStatement, - followingReturnStatement, - }); - - if (typeof source === 'object' && source.functionNodes) { - return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode); - } - - const rootNode = new FunctionNode(source, rootNodeOptions); - - let functionNodes = null; - if (functions) { - functionNodes = functions.map((fn) => new FunctionNode(fn.source, { - returnType: fn.returnType, - argumentTypes: fn.argumentTypes, - output, - plugins, - constants, - constantTypes, - constantBitRatios, - optimizeFloatMemory, - precision, - lookupReturnType, - lookupFunctionArgumentTypes, - lookupFunctionArgumentName, - lookupFunctionArgumentBitRatio, - needsArgumentType, - assignArgumentType, - triggerImplyArgumentType, - triggerImplyArgumentBitRatio, - onFunctionCall, - onNestedFunction, - })); - } - - let subKernelNodes = null; - if (subKernels) { - subKernelNodes = subKernels.map((subKernel) => { - const { name, source } = subKernel; - return new FunctionNode(source, Object.assign({}, nodeOptions, { - name, - isSubKernel: true, - isRootKernel: false, - })); - }); - } - - const functionBuilder = new FunctionBuilder({ - kernel, - rootNode, - functionNodes, - nativeFunctions, - subKernelNodes - }); - - return functionBuilder; - } - - /** - * - * @param {IFunctionBuilderSettings} [settings] - */ - constructor(settings) { - settings = settings || {}; - this.kernel = settings.kernel; - this.rootNode = settings.rootNode; - this.functionNodes = settings.functionNodes || []; - this.subKernelNodes = settings.subKernelNodes || []; - this.nativeFunctions = settings.nativeFunctions || []; - this.functionMap = {}; - this.nativeFunctionNames = []; - this.lookupChain = []; - this.argumentChain = []; - this.functionNodeDependencies = {}; - this.functionCalls = {}; - - if (this.rootNode) { - this.functionMap['kernel'] = this.rootNode; - } - - if (this.functionNodes) { - for (let i = 0; i < this.functionNodes.length; i++) { - this.functionMap[this.functionNodes[i].name] = this.functionNodes[i]; - } - } - - if (this.subKernelNodes) { - for (let i = 0; i < this.subKernelNodes.length; i++) { - this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i]; - } - } - - if (this.nativeFunctions) { - for (let i = 0; i < this.nativeFunctions.length; i++) { - const nativeFunction = this.nativeFunctions[i]; - this.nativeFunctionNames.push(nativeFunction.name); - } - } - } - - /** - * @desc Add the function node directly - * - * @param {FunctionNode} functionNode - functionNode to add - * - */ - addFunctionNode(functionNode) { - if (!functionNode.name) throw new Error('functionNode.name needs set'); - this.functionMap[functionNode.name] = functionNode; - if (functionNode.isRootKernel) { - this.rootNode = functionNode; - } - } - - /** - * @desc Trace all the depending functions being called, from a single function - * - * This allow for 'unneeded' functions to be automatically optimized out. - * Note that the 0-index, is the starting function trace. - * - * @param {String} functionName - Function name to trace from, default to 'kernel' - * @param {String[]} [retList] - Returning list of function names that is traced. Including itself. - * - * @returns {String[]} Returning list of function names that is traced. Including itself. - */ - traceFunctionCalls(functionName, retList) { - functionName = functionName || 'kernel'; - retList = retList || []; - - if (this.nativeFunctionNames.indexOf(functionName) > -1) { - if (retList.indexOf(functionName) === -1) { - retList.push(functionName); - } - return retList; - } - - const functionNode = this.functionMap[functionName]; - if (functionNode) { - // Check if function already exists - const functionIndex = retList.indexOf(functionName); - if (functionIndex === -1) { - retList.push(functionName); - functionNode.toString(); //ensure JS trace is done - for (let i = 0; i < functionNode.calledFunctions.length; ++i) { - this.traceFunctionCalls(functionNode.calledFunctions[i], retList); - } - } else { - /** - * https://github.com/gpujs/gpu.js/issues/207 - * if dependent function is already in the list, because a function depends on it, and because it has - * already been traced, we know that we must move the dependent function to the end of the the retList. - * */ - const dependantFunctionName = retList.splice(functionIndex, 1)[0]; - retList.push(dependantFunctionName); - } - } - - return retList; - } - - /** - * @desc Return the string for a function - * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack - * @returns {String} The full string, of all the various functions. Trace optimized if functionName given - */ - getPrototypeString(functionName) { - return this.getPrototypes(functionName).join('\n'); - } - - /** - * @desc Return the string for a function - * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack - * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given - */ - getPrototypes(functionName) { - if (this.rootNode) { - this.rootNode.toString(); - } - if (functionName) { - return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); - } - return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); - } - - /** - * @desc Get string from function names - * @param {String[]} functionList - List of function to build string - * @returns {String} The string, of all the various functions. Trace optimized if functionName given - */ - getStringFromFunctionNames(functionList) { - const ret = []; - for (let i = 0; i < functionList.length; ++i) { - const node = this.functionMap[functionList[i]]; - if (node) { - ret.push(this.functionMap[functionList[i]].toString()); - } - } - return ret.join('\n'); - } - - /** - * @desc Return string of all functions converted - * @param {String[]} functionList - List of function names to build the string. - * @returns {Array} Prototypes of all functions converted - */ - getPrototypesFromFunctionNames(functionList) { - const ret = []; - for (let i = 0; i < functionList.length; ++i) { - const functionName = functionList[i]; - const functionIndex = this.nativeFunctionNames.indexOf(functionName); - if (functionIndex > -1) { - ret.push(this.nativeFunctions[functionIndex].source); - continue; - } - const node = this.functionMap[functionName]; - if (node) { - ret.push(node.toString()); - } - } - return ret; - } - - toJSON() { - return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => { - const nativeIndex = this.nativeFunctions.indexOf(name); - if (nativeIndex > -1) { - return { - name, - source: this.nativeFunctions[nativeIndex].source - }; - } else if (this.functionMap[name]) { - return this.functionMap[name].toJSON(); - } else { - throw new Error(`function ${ name } not found`); - } - }); - } - - fromJSON(jsonFunctionNodes, FunctionNode) { - this.functionMap = {}; - for (let i = 0; i < jsonFunctionNodes.length; i++) { - const jsonFunctionNode = jsonFunctionNodes[i]; - this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings); - } - return this; - } - - /** - * @desc Get string for a particular function name - * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack - * @returns {String} settings - The string, of all the various functions. Trace optimized if functionName given - */ - getString(functionName) { - if (functionName) { - return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse()); - } - return this.getStringFromFunctionNames(Object.keys(this.functionMap)); - } - - lookupReturnType(functionName, ast, requestingNode) { - if (ast.type !== 'CallExpression') { - throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`); - } - if (this._isNativeFunction(functionName)) { - return this._lookupNativeFunctionReturnType(functionName); - } else if (this._isFunction(functionName)) { - const node = this._getFunction(functionName); - if (node.returnType) { - return node.returnType; - } else { - for (let i = 0; i < this.lookupChain.length; i++) { - // detect circlical logic - if (this.lookupChain[i].ast === ast) { - // detect if arguments have not resolved, preventing a return type - // if so, go ahead and resolve them, so we can resolve the return type - if (node.argumentTypes.length === 0 && ast.arguments.length > 0) { - const args = ast.arguments; - for (let j = 0; j < args.length; j++) { - this.lookupChain.push({ - name: requestingNode.name, - ast: args[i], - requestingNode - }); - node.argumentTypes[j] = requestingNode.getType(args[j]); - this.lookupChain.pop(); - } - return node.returnType = node.getType(node.getJsAST()); - } - - throw new Error('circlical logic detected!'); - } - } - // get ready for a ride! - this.lookupChain.push({ - name: requestingNode.name, - ast, - requestingNode - }); - const type = node.getType(node.getJsAST()); - this.lookupChain.pop(); - return node.returnType = type; - } - } - - return null; - } - - /** - * - * @param {String} functionName - * @return {FunctionNode} - * @private - */ - _getFunction(functionName) { - if (!this._isFunction(functionName)) { - new Error(`Function ${functionName} not found`); - } - return this.functionMap[functionName]; - } - - _isFunction(functionName) { - return Boolean(this.functionMap[functionName]); - } - - _getNativeFunction(functionName) { - for (let i = 0; i < this.nativeFunctions.length; i++) { - if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i]; - } - return null; - } - - _isNativeFunction(functionName) { - return Boolean(this._getNativeFunction(functionName)); - } - - _lookupNativeFunctionReturnType(functionName) { - let nativeFunction = this._getNativeFunction(functionName); - if (nativeFunction) { - return nativeFunction.returnType; - } - throw new Error(`Native function ${ functionName } not found`); - } - - lookupFunctionArgumentTypes(functionName) { - if (this._isNativeFunction(functionName)) { - return this._getNativeFunction(functionName).argumentTypes; - } else if (this._isFunction(functionName)) { - return this._getFunction(functionName).argumentTypes; - } - return null; - } - - lookupFunctionArgumentName(functionName, argumentIndex) { - return this._getFunction(functionName).argumentNames[argumentIndex]; - } - - /** - * - * @param {string} functionName - * @param {string} argumentName - * @return {number} - */ - lookupFunctionArgumentBitRatio(functionName, argumentName) { - if (!this._isFunction(functionName)) { - throw new Error('function not found'); - } - if (this.rootNode.name === functionName) { - const i = this.rootNode.argumentNames.indexOf(argumentName); - if (i !== -1) { - return this.rootNode.argumentBitRatios[i]; - } - } - const node = this._getFunction(functionName); - const i = node.argumentNames.indexOf(argumentName); - if (i === -1) { - throw new Error('argument not found'); - } - const bitRatio = node.argumentBitRatios[i]; - if (typeof bitRatio !== 'number') { - throw new Error('argument bit ratio not found'); - } - return bitRatio; - } - - needsArgumentType(functionName, i) { - if (!this._isFunction(functionName)) return false; - const fnNode = this._getFunction(functionName); - return !fnNode.argumentTypes[i]; - } - - assignArgumentType(functionName, i, argumentType, requestingNode) { - if (!this._isFunction(functionName)) return; - const fnNode = this._getFunction(functionName); - if (!fnNode.argumentTypes[i]) { - fnNode.argumentTypes[i] = argumentType; - } - } - - /** - * @param {string} functionName - * @param {string} argumentName - * @param {string} calleeFunctionName - * @param {number} argumentIndex - * @return {number|null} - */ - assignArgumentBitRatio(functionName, argumentName, calleeFunctionName, argumentIndex) { - const node = this._getFunction(functionName); - if (this._isNativeFunction(calleeFunctionName)) return null; - const calleeNode = this._getFunction(calleeFunctionName); - const i = node.argumentNames.indexOf(argumentName); - if (i === -1) { - throw new Error(`Argument ${argumentName} not found in arguments from function ${functionName}`); - } - const bitRatio = node.argumentBitRatios[i]; - if (typeof bitRatio !== 'number') { - throw new Error(`Bit ratio for argument ${argumentName} not found in function ${functionName}`); - } - if (!calleeNode.argumentBitRatios) { - calleeNode.argumentBitRatios = new Array(calleeNode.argumentNames.length); - } - const calleeBitRatio = calleeNode.argumentBitRatios[i]; - if (typeof calleeBitRatio === 'number') { - if (calleeBitRatio !== bitRatio) { - throw new Error(`Incompatible bit ratio found at function ${functionName} at argument ${argumentName}`); - } - return calleeBitRatio; - } - calleeNode.argumentBitRatios[i] = bitRatio; - return bitRatio; - } - - trackFunctionCall(functionName, calleeFunctionName, args) { - if (!this.functionNodeDependencies[functionName]) { - this.functionNodeDependencies[functionName] = new Set(); - this.functionCalls[functionName] = []; - } - this.functionNodeDependencies[functionName].add(calleeFunctionName); - this.functionCalls[functionName].push(args); - } - - getKernelResultType() { - return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast); - } - - getSubKernelResultType(index) { - const subKernelNode = this.subKernelNodes[index]; - let called = false; - for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) { - const functionCall = this.rootNode.functionCalls[functionCallIndex]; - if (functionCall.ast.callee.name === subKernelNode.name) { - called = true; - } - } - if (!called) { - throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); - } - return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST()); - } - - getReturnTypes() { - const result = { - [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast), - }; - const list = this.traceFunctionCalls(this.rootNode.name); - for (let i = 0; i < list.length; i++) { - const functionName = list[i]; - const functionNode = this.functionMap[functionName]; - result[functionName] = functionNode.getType(functionNode.ast); - } - return result; - } -} - -module.exports = { - FunctionBuilder -}; \ No newline at end of file +/** + * @desc This handles all the raw state, converted state, etc. of a single function. + * [INTERNAL] A collection of functionNodes. + * @class + */ +export class FunctionBuilder { + /** + * + * @param {Kernel} kernel + * @param {FunctionNode} FunctionNode + * @param {object} [extraNodeOptions] + * @returns {FunctionBuilder} + * @static + */ + static fromKernel(kernel, FunctionNode, extraNodeOptions) { + const { + kernelArguments, + kernelConstants, + argumentNames, + argumentSizes, + argumentBitRatios, + constants, + constantBitRatios, + debug, + loopMaxIterations, + nativeFunctions, + output, + optimizeFloatMemory, + precision, + plugins, + source, + subKernels, + functions, + leadingReturnStatement, + followingReturnStatement, + dynamicArguments, + dynamicOutput, + warnVarUsage, + } = kernel; + + const argumentTypes = new Array(kernelArguments.length); + const constantTypes = {}; + + for (let i = 0; i < kernelArguments.length; i++) { + argumentTypes[i] = kernelArguments[i].type; + } + + for (let i = 0; i < kernelConstants.length; i++) { + const kernelConstant = kernelConstants[i] + constantTypes[kernelConstant.name] = kernelConstant.type; + } + + const needsArgumentType = (functionName, index) => { + return functionBuilder.needsArgumentType(functionName, index); + }; + + const assignArgumentType = (functionName, index, type) => { + functionBuilder.assignArgumentType(functionName, index, type); + }; + + const lookupReturnType = (functionName, ast, requestingNode) => { + return functionBuilder.lookupReturnType(functionName, ast, requestingNode); + }; + + const lookupFunctionArgumentTypes = (functionName) => { + return functionBuilder.lookupFunctionArgumentTypes(functionName); + }; + + const lookupFunctionArgumentName = (functionName, argumentIndex) => { + return functionBuilder.lookupFunctionArgumentName(functionName, argumentIndex); + }; + + const lookupFunctionArgumentBitRatio = (functionName, argumentName) => { + return functionBuilder.lookupFunctionArgumentBitRatio(functionName, argumentName); + }; + + const triggerImplyArgumentType = (functionName, i, argumentType, requestingNode) => { + functionBuilder.assignArgumentType(functionName, i, argumentType, requestingNode); + }; + + const triggerTrackArgumentSynonym = (functionName, argumentName, calleeFunctionName, argumentIndex) => { + functionBuilder.trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex); + }; + + const lookupArgumentSynonym = (originFunctionName, functionName, argumentName) => { + return functionBuilder.lookupArgumentSynonym(originFunctionName, functionName, argumentName); + }; + + const onFunctionCall = (functionName, calleeFunctionName, args) => { + functionBuilder.trackFunctionCall(functionName, calleeFunctionName, args); + }; + + const onNestedFunction = (ast, returnType) => { + const argumentNames = []; + for (let i = 0; i < ast.params.length; i++) { + argumentNames.push(ast.params[i].name); + } + const nestedFunction = new FunctionNode(null, Object.assign({}, nodeOptions, { + returnType: null, + ast, + name: ast.id.name, + argumentNames, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + warnVarUsage, + })); + nestedFunction.traceFunctionAST(ast); + functionBuilder.addFunctionNode(nestedFunction); + }; + + const nodeOptions = Object.assign({ + isRootKernel: false, + onNestedFunction, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + optimizeFloatMemory, + precision, + constants, + constantTypes, + constantBitRatios, + debug, + loopMaxIterations, + output, + plugins, + dynamicArguments, + dynamicOutput, + }, extraNodeOptions || {}); + + const rootNodeOptions = Object.assign({}, nodeOptions, { + isRootKernel: true, + name: 'kernel', + argumentNames, + argumentTypes, + argumentSizes, + argumentBitRatios, + leadingReturnStatement, + followingReturnStatement, + }); + + if (typeof source === 'object' && source.functionNodes) { + return new FunctionBuilder().fromJSON(source.functionNodes, FunctionNode); + } + + const rootNode = new FunctionNode(source, rootNodeOptions); + + let functionNodes = null; + if (functions) { + functionNodes = functions.map((fn) => new FunctionNode(fn.source, { + returnType: fn.returnType, + argumentTypes: fn.argumentTypes, + output, + plugins, + constants, + constantTypes, + constantBitRatios, + optimizeFloatMemory, + precision, + lookupReturnType, + lookupFunctionArgumentTypes, + lookupFunctionArgumentName, + lookupFunctionArgumentBitRatio, + needsArgumentType, + assignArgumentType, + triggerImplyArgumentType, + triggerTrackArgumentSynonym, + lookupArgumentSynonym, + onFunctionCall, + })); + } + + let subKernelNodes = null; + if (subKernels) { + subKernelNodes = subKernels.map((subKernel) => { + const { name, source } = subKernel; + return new FunctionNode(source, Object.assign({}, nodeOptions, { + name, + isSubKernel: true, + isRootKernel: false, + })); + }); + } + + const functionBuilder = new FunctionBuilder({ + kernel, + rootNode, + functionNodes, + nativeFunctions, + subKernelNodes + }); + + return functionBuilder; + } + + /** + * + * @param {IFunctionBuilderSettings} [settings] + */ + constructor(settings) { + settings = settings || {}; + this.kernel = settings.kernel; + this.rootNode = settings.rootNode; + this.functionNodes = settings.functionNodes || []; + this.subKernelNodes = settings.subKernelNodes || []; + this.nativeFunctions = settings.nativeFunctions || []; + this.functionMap = {}; + this.nativeFunctionNames = []; + this.lookupChain = []; + this.argumentChain = []; + this.functionNodeDependencies = {}; + this.functionCalls = {}; + + if (this.rootNode) { + this.functionMap['kernel'] = this.rootNode; + } + + if (this.functionNodes) { + for (let i = 0; i < this.functionNodes.length; i++) { + this.functionMap[this.functionNodes[i].name] = this.functionNodes[i]; + } + } + + if (this.subKernelNodes) { + for (let i = 0; i < this.subKernelNodes.length; i++) { + this.functionMap[this.subKernelNodes[i].name] = this.subKernelNodes[i]; + } + } + + if (this.nativeFunctions) { + for (let i = 0; i < this.nativeFunctions.length; i++) { + const nativeFunction = this.nativeFunctions[i]; + this.nativeFunctionNames.push(nativeFunction.name); + } + } + } + + /** + * @desc Add the function node directly + * + * @param {FunctionNode} functionNode - functionNode to add + * + */ + addFunctionNode(functionNode) { + if (!functionNode.name) throw new Error('functionNode.name needs set'); + this.functionMap[functionNode.name] = functionNode; + if (functionNode.isRootKernel) { + this.rootNode = functionNode; + } + } + + /** + * @desc Trace all the depending functions being called, from a single function + * + * This allow for 'unneeded' functions to be automatically optimized out. + * Note that the 0-index, is the starting function trace. + * + * @param {String} functionName - Function name to trace from, default to 'kernel' + * @param {String[]} [retList] - Returning list of function names that is traced. Including itself. + * + * @returns {String[]} Returning list of function names that is traced. Including itself. + */ + traceFunctionCalls(functionName, retList) { + functionName = functionName || 'kernel'; + retList = retList || []; + + if (this.nativeFunctionNames.indexOf(functionName) > -1) { + if (retList.indexOf(functionName) === -1) { + retList.push(functionName); + } + return retList; + } + + const functionNode = this.functionMap[functionName]; + if (functionNode) { + // Check if function already exists + const functionIndex = retList.indexOf(functionName); + if (functionIndex === -1) { + retList.push(functionName); + functionNode.toString(); //ensure JS trace is done + for (let i = 0; i < functionNode.calledFunctions.length; ++i) { + this.traceFunctionCalls(functionNode.calledFunctions[i], retList); + } + } else { + /** + * https://github.com/gpujs/gpu.js/issues/207 + * if dependent function is already in the list, because a function depends on it, and because it has + * already been traced, we know that we must move the dependent function to the end of the the retList. + * */ + const dependantFunctionName = retList.splice(functionIndex, 1)[0]; + retList.push(dependantFunctionName); + } + } + + return retList; + } + + /** + * @desc Return the string for a function + * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack + * @returns {String} The full string, of all the various functions. Trace optimized if functionName given + */ + getPrototypeString(functionName) { + return this.getPrototypes(functionName).join('\n'); + } + + /** + * @desc Return the string for a function + * @param {String} [functionName] - Function name to trace from. If null, it returns the WHOLE builder stack + * @returns {Array} The full string, of all the various functions. Trace optimized if functionName given + */ + getPrototypes(functionName) { + if (this.rootNode) { + this.rootNode.toString(); + } + if (functionName) { + return this.getPrototypesFromFunctionNames(this.traceFunctionCalls(functionName, []).reverse()); + } + return this.getPrototypesFromFunctionNames(Object.keys(this.functionMap)); + } + + /** + * @desc Get string from function names + * @param {String[]} functionList - List of function to build string + * @returns {String} The string, of all the various functions. Trace optimized if functionName given + */ + getStringFromFunctionNames(functionList) { + const ret = []; + for (let i = 0; i < functionList.length; ++i) { + const node = this.functionMap[functionList[i]]; + if (node) { + ret.push(this.functionMap[functionList[i]].toString()); + } + } + return ret.join('\n'); + } + + /** + * @desc Return string of all functions converted + * @param {String[]} functionList - List of function names to build the string. + * @returns {Array} Prototypes of all functions converted + */ + getPrototypesFromFunctionNames(functionList) { + const ret = []; + for (let i = 0; i < functionList.length; ++i) { + const functionName = functionList[i]; + const functionIndex = this.nativeFunctionNames.indexOf(functionName); + if (functionIndex > -1) { + ret.push(this.nativeFunctions[functionIndex].source); + continue; + } + const node = this.functionMap[functionName]; + if (node) { + ret.push(node.toString()); + } + } + return ret; + } + + toJSON() { + return this.traceFunctionCalls(this.rootNode.name).reverse().map(name => { + const nativeIndex = this.nativeFunctions.indexOf(name); + if (nativeIndex > -1) { + return { + name, + source: this.nativeFunctions[nativeIndex].source + }; + } else if (this.functionMap[name]) { + return this.functionMap[name].toJSON(); + } else { + throw new Error(`function ${ name } not found`); + } + }); + } + + fromJSON(jsonFunctionNodes, FunctionNode) { + this.functionMap = {}; + for (let i = 0; i < jsonFunctionNodes.length; i++) { + const jsonFunctionNode = jsonFunctionNodes[i]; + this.functionMap[jsonFunctionNode.settings.name] = new FunctionNode(jsonFunctionNode.ast, jsonFunctionNode.settings); + } + return this; + } + + /** + * @desc Get string for a particular function name + * @param {String} functionName - Function name to trace from. If null, it returns the WHOLE builder stack + * @returns {String} settings - The string, of all the various functions. Trace optimized if functionName given + */ + getString(functionName) { + if (functionName) { + return this.getStringFromFunctionNames(this.traceFunctionCalls(functionName).reverse()); + } + return this.getStringFromFunctionNames(Object.keys(this.functionMap)); + } + + lookupReturnType(functionName, ast, requestingNode) { + if (ast.type !== 'CallExpression') { + throw new Error(`expected ast type of "CallExpression", but is ${ ast.type }`); + } + if (this._isNativeFunction(functionName)) { + return this._lookupNativeFunctionReturnType(functionName); + } else if (this._isFunction(functionName)) { + const node = this._getFunction(functionName); + if (node.returnType) { + return node.returnType; + } else { + for (let i = 0; i < this.lookupChain.length; i++) { + // detect circlical logic + if (this.lookupChain[i].ast === ast) { + // detect if arguments have not resolved, preventing a return type + // if so, go ahead and resolve them, so we can resolve the return type + if (node.argumentTypes.length === 0 && ast.arguments.length > 0) { + const args = ast.arguments; + for (let j = 0; j < args.length; j++) { + this.lookupChain.push({ + name: requestingNode.name, + ast: args[i], + requestingNode + }); + node.argumentTypes[j] = requestingNode.getType(args[j]); + this.lookupChain.pop(); + } + return node.returnType = node.getType(node.getJsAST()); + } + + throw new Error('circlical logic detected!'); + } + } + // get ready for a ride! + this.lookupChain.push({ + name: requestingNode.name, + ast, + requestingNode + }); + const type = node.getType(node.getJsAST()); + this.lookupChain.pop(); + return node.returnType = type; + } + } + + // function not found, maybe native? + return null; + + /** + * first iteration + * kernel.outputs = Array + * kernel.targets = Array + * kernel.returns = null + * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets] + * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output] + * calcErrorOutput.output = null + * calcErrorOutput.targets = null + * calcErrorOutput.returns = null + * calcDeltasSigmoid.error = null + * calcDeltasSigmoid.output = Number + * calcDeltasSigmoid.returns = null + * + * resolvable are: + * calcErrorOutput.output + * calcErrorOutput.targets + * calcErrorOutput.returns + * + * second iteration + * kernel.outputs = Array + * kernel.targets = Array + * kernel.returns = null + * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets] + * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output] + * calcErrorOutput.output = Number + * calcErrorOutput.targets = Array + * calcErrorOutput.returns = Number + * calcDeltasSigmoid.error = null + * calcDeltasSigmoid.output = Number + * calcDeltasSigmoid.returns = null + * + * resolvable are: + * calcDeltasSigmoid.error + * calcDeltasSigmoid.returns + * kernel.returns + * + * third iteration + * kernel.outputs = Array + * kernel.targets = Array + * kernel.returns = Number + * kernel.calls.calcErrorOutput = [kernel.output, kernel.targets] + * kernel.calls.calcDeltas = [calcErrorOutput.returns, kernel.output] + * calcErrorOutput.output = Number + * calcErrorOutput.targets = Array + * calcErrorOutput.returns = Number + * calcDeltasSigmoid.error = Number + * calcDeltasSigmoid.output = Number + * calcDeltasSigmoid.returns = Number + * + * + */ + } + + _getFunction(functionName) { + if (!this._isFunction(functionName)) { + new Error(`Function ${functionName} not found`); + } + return this.functionMap[functionName]; + } + + _isFunction(functionName) { + return Boolean(this.functionMap[functionName]); + } + + _getNativeFunction(functionName) { + for (let i = 0; i < this.nativeFunctions.length; i++) { + if (this.nativeFunctions[i].name === functionName) return this.nativeFunctions[i]; + } + return null; + } + + _isNativeFunction(functionName) { + return Boolean(this._getNativeFunction(functionName)); + } + + _lookupNativeFunctionReturnType(functionName) { + let nativeFunction = this._getNativeFunction(functionName); + if (nativeFunction) { + return nativeFunction.returnType; + } + throw new Error(`Native function ${ functionName } not found`); + } + + lookupFunctionArgumentTypes(functionName) { + if (this._isNativeFunction(functionName)) { + return this._getNativeFunction(functionName).argumentTypes; + } else if (this._isFunction(functionName)) { + return this._getFunction(functionName).argumentTypes; + } + return null; + } + + lookupFunctionArgumentName(functionName, argumentIndex) { + return this._getFunction(functionName).argumentNames[argumentIndex]; + } + + lookupFunctionArgumentBitRatio(functionName, argumentName) { + if (!this._isFunction(functionName)) { + throw new Error('function not found'); + } + if (this.rootNode.name === functionName) { + const i = this.rootNode.argumentNames.indexOf(argumentName); + if (i !== -1) { + return this.rootNode.argumentBitRatios[i]; + } else { + throw new Error('argument bit ratio not found'); + } + } else { + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymIndex]; + if (!argumentSynonym) { + throw new Error('argument synonym not found'); + } + return this.lookupFunctionArgumentBitRatio(argumentSynonym.functionName, argumentSynonym.argumentName); + } + } + + needsArgumentType(functionName, i) { + if (!this._isFunction(functionName)) return false; + const fnNode = this._getFunction(functionName); + return !fnNode.argumentTypes[i]; + } + + assignArgumentType(functionName, i, argumentType, requestingNode) { + if (!this._isFunction(functionName)) return; + const fnNode = this._getFunction(functionName); + if (!fnNode.argumentTypes[i]) { + fnNode.argumentTypes[i] = argumentType; + } + } + + trackArgumentSynonym(functionName, argumentName, calleeFunctionName, argumentIndex) { + if (!this._isFunction(calleeFunctionName)) return; + const node = this._getFunction(calleeFunctionName); + if (!node.argumentSynonym) { + node.argumentSynonym = {}; + } + const calleeArgumentName = node.argumentNames[argumentIndex]; + if (!node.argumentSynonym[calleeArgumentName]) { + node.argumentSynonym[calleeArgumentName] = {}; + } + node.synonymIndex++; + node.argumentSynonym[node.synonymIndex] = { + functionName, + argumentName, + calleeArgumentName, + calleeFunctionName, + }; + } + + lookupArgumentSynonym(originFunctionName, functionName, argumentName) { + if (originFunctionName === functionName) return argumentName; + if (!this._isFunction(functionName)) return null; + const node = this._getFunction(functionName); + const argumentSynonym = node.argumentSynonym[node.synonymUseIndex]; + if (!argumentSynonym) return null; + if (argumentSynonym.calleeArgumentName !== argumentName) return null; + node.synonymUseIndex++; + if (originFunctionName !== functionName) { + return this.lookupArgumentSynonym(originFunctionName, argumentSynonym.functionName, argumentSynonym.argumentName); + } + return argumentSynonym.argumentName; + } + + trackFunctionCall(functionName, calleeFunctionName, args) { + if (!this.functionNodeDependencies[functionName]) { + this.functionNodeDependencies[functionName] = new Set(); + this.functionCalls[functionName] = []; + } + this.functionNodeDependencies[functionName].add(calleeFunctionName); + this.functionCalls[functionName].push(args); + } + + getKernelResultType() { + return this.rootNode.returnType || this.rootNode.getType(this.rootNode.ast); + } + + getSubKernelResultType(index) { + const subKernelNode = this.subKernelNodes[index]; + let called = false; + for (let functionCallIndex = 0; functionCallIndex < this.rootNode.functionCalls.length; functionCallIndex++) { + const functionCall = this.rootNode.functionCalls[functionCallIndex]; + if (functionCall.ast.callee.name === subKernelNode.name) { + called = true; + } + } + if (!called) { + throw new Error(`SubKernel ${ subKernelNode.name } never called by kernel`); + } + return subKernelNode.returnType || subKernelNode.getType(subKernelNode.getJsAST()); + } + + getReturnTypes() { + const result = { + [this.rootNode.name]: this.rootNode.getType(this.rootNode.ast), + }; + const list = this.traceFunctionCalls(this.rootNode.name); + for (let i = 0; i < list.length; i++) { + const functionName = list[i]; + const functionNode = this.functionMap[functionName]; + result[functionName] = functionNode.getType(functionNode.ast); + } + return result; + } +} diff --git a/src/backend/function-node.js b/src/backend/function-node.js index 8ffd1da9..14b39132 100644 --- a/src/backend/function-node.js +++ b/src/backend/function-node.js @@ -1,1509 +1,1510 @@ -const acorn = require('acorn'); -const { utils } = require('../utils'); -const { FunctionTracer } = require('./function-tracer'); - -/** - * - * @desc Represents a single function, inside JS, webGL, or openGL. - *

This handles all the raw state, converted state, etc. Of a single function.

- */ -class FunctionNode { - /** - * - * @param {string|object} source - * @param {IFunctionSettings} [settings] - */ - constructor(source, settings) { - if (!source && !settings.ast) { - throw new Error('source parameter is missing'); - } - settings = settings || {}; - this.source = source; - this.ast = null; - this.name = typeof source === 'string' ? settings.isRootKernel ? - 'kernel' : - (settings.name || utils.getFunctionNameFromString(source)) : null; - this.calledFunctions = []; - this.constants = {}; - this.constantTypes = {}; - this.constantBitRatios = {}; - this.isRootKernel = false; - this.isSubKernel = false; - this.debug = null; - this.declarations = null; - this.functions = null; - this.identifiers = null; - this.contexts = null; - this.functionCalls = null; - this.states = []; - this.needsArgumentType = null; - this.assignArgumentType = null; - this.lookupReturnType = null; - this.lookupFunctionArgumentTypes = null; - this.lookupFunctionArgumentBitRatio = null; - this.triggerImplyArgumentType = null; - this.triggerImplyArgumentBitRatio = null; - this.onNestedFunction = null; - this.onFunctionCall = null; - this.optimizeFloatMemory = null; - this.precision = null; - this.loopMaxIterations = null; - this.argumentNames = (typeof this.source === 'string' ? utils.getArgumentNamesFromString(this.source) : null); - this.argumentTypes = []; - this.argumentSizes = []; - this.argumentBitRatios = null; - this.returnType = null; - this.output = []; - this.plugins = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.dynamicOutput = null; - this.dynamicArguments = null; - this.strictTypingChecking = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - - if (settings) { - for (const p in settings) { - if (!settings.hasOwnProperty(p)) continue; - if (!this.hasOwnProperty(p)) continue; - this[p] = settings[p]; - } - } - - this.literalTypes = {}; - - this.validate(); - this._string = null; - this._internalVariableNames = {}; - } - - validate() { - if (typeof this.source !== 'string' && !this.ast) { - throw new Error('this.source not a string'); - } - - if (!this.ast && !utils.isFunctionString(this.source)) { - throw new Error('this.source not a function string'); - } - - if (!this.name) { - throw new Error('this.name could not be set'); - } - - if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) { - throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`); - } - - if (this.output.length < 1) { - throw new Error('this.output is not big enough'); - } - } - - /** - * @param {String} name - * @returns {boolean} - */ - isIdentifierConstant(name) { - if (!this.constants) return false; - return this.constants.hasOwnProperty(name); - } - - isInput(argumentName) { - return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input'; - } - - pushState(state) { - this.states.push(state); - } - - popState(state) { - if (this.state !== state) { - throw new Error(`Cannot popState ${ state } when in ${ this.state }`); - } - this.states.pop(); - } - - isState(state) { - return this.state === state; - } - - get state() { - return this.states[this.states.length - 1]; - } - - /** - * @function - * @name astMemberExpressionUnroll - * @desc Parses the abstract syntax tree for binary expression. - * - *

Utility function for astCallExpression.

- * - * @param {Object} ast - the AST object to parse - * - * @returns {String} the function namespace call, unrolled - */ - astMemberExpressionUnroll(ast) { - if (ast.type === 'Identifier') { - return ast.name; - } else if (ast.type === 'ThisExpression') { - return 'this'; - } - - if (ast.type === 'MemberExpression') { - if (ast.object && ast.property) { - //babel sniffing - if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { - return this.astMemberExpressionUnroll(ast.property); - } - - return ( - this.astMemberExpressionUnroll(ast.object) + - '.' + - this.astMemberExpressionUnroll(ast.property) - ); - } - } - - //babel sniffing - if (ast.hasOwnProperty('expressions')) { - const firstExpression = ast.expressions[0]; - if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) { - return this.astMemberExpressionUnroll(ast.expressions[1]); - } - } - - // Failure, unknown expression - throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast); - } - - /** - * @desc Parses the class function JS, and returns its Abstract Syntax Tree object. - * This is used internally to convert to shader code - * - * @param {Object} [inParser] - Parser to use, assumes in scope 'parser' if null or undefined - * - * @returns {Object} The function AST Object, note that result is cached under this.ast; - */ - getJsAST(inParser) { - if (this.ast) { - return this.ast; - } - if (typeof this.source === 'object') { - this.traceFunctionAST(this.source); - return this.ast = this.source; - } - - inParser = inParser || acorn; - if (inParser === null) { - throw new Error('Missing JS to AST parser'); - } - - const ast = Object.freeze(inParser.parse(`const parser_${ this.name } = ${ this.source };`, { - locations: true - })); - // take out the function object, outside the var declarations - const functionAST = ast.body[0].declarations[0].init; - this.traceFunctionAST(functionAST); - - if (!ast) { - throw new Error('Failed to parse JS code'); - } - - return this.ast = functionAST; - } - - traceFunctionAST(ast) { - const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast); - this.contexts = contexts; - this.identifiers = identifiers; - this.functionCalls = functionCalls; - this.declarations = []; - this.functions = functions; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - const { ast, context, name, origin, forceInteger, assignable } = declaration; - const { init } = ast; - const dependencies = this.getDependencies(init); - let valueType = null; - - if (forceInteger) { - valueType = 'Integer'; - } else { - if (init) { - const realType = this.getType(init); - switch (realType) { - case 'Integer': - case 'Float': - case 'Number': - if (init.type === 'MemberExpression') { - valueType = realType; - } else { - valueType = 'Number'; - } - break; - case 'LiteralInteger': - valueType = 'Number'; - break; - default: - valueType = realType; - } - } - } - this.declarations.push({ - valueType, - dependencies, - isSafe: this.isSafeDependencies(dependencies), - ast, - name, - context, - origin, - assignable, - }); - } - - for (let i = 0; i < functions.length; i++) { - this.onNestedFunction(functions[i]); - } - } - - getDeclaration(ast) { - for (let i = 0; i < this.identifiers.length; i++) { - const identifier = this.identifiers[i]; - if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { - for (let j = 0; j < this.declarations.length; j++) { - const declaration = this.declarations[j]; - if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { - return declaration; - } - } - } - } - return null; - } - - /** - * @desc Return the type of parameter sent to subKernel/Kernel. - * @param {Object} ast - Identifier - * @returns {String} Type of the parameter - */ - getVariableType(ast) { - if (ast.type !== 'Identifier') { - throw new Error(`ast of ${ast.type} not "Identifier"`); - } - let type = null; - const argumentIndex = this.argumentNames.indexOf(ast.name); - if (argumentIndex === -1) { - const declaration = this.getDeclaration(ast); - if (declaration) { - return declaration.valueType; - } - } else { - const argumentType = this.argumentTypes[argumentIndex]; - if (argumentType) { - type = argumentType; - } - } - if (!type && this.strictTypingChecking) { - throw new Error(`Declaration of ${name} not found`); - } - return type; - } - - /** - * Generally used to lookup the value type returned from a member expressions - * @param {String} type - * @return {String} - */ - getLookupType(type) { - if (!typeLookupMap.hasOwnProperty(type)) { - throw new Error(`unknown typeLookupMap ${ type }`); - } - return typeLookupMap[type]; - } - - getConstantType(constantName) { - if (this.constantTypes[constantName]) { - const type = this.constantTypes[constantName]; - if (type === 'Float') { - return 'Number'; - } else { - return type; - } - } - throw new Error(`Type for constant "${ constantName }" not declared`); - } - - toString() { - if (this._string) return this._string; - return this._string = this.astGeneric(this.getJsAST(), []).join('').trim(); - } - - toJSON() { - const settings = { - source: this.source, - name: this.name, - constants: this.constants, - constantTypes: this.constantTypes, - isRootKernel: this.isRootKernel, - isSubKernel: this.isSubKernel, - debug: this.debug, - output: this.output, - loopMaxIterations: this.loopMaxIterations, - argumentNames: this.argumentNames, - argumentTypes: this.argumentTypes, - argumentSizes: this.argumentSizes, - returnType: this.returnType, - leadingReturnStatement: this.leadingReturnStatement, - followingReturnStatement: this.followingReturnStatement, - }; - - return { - ast: this.ast, - settings - }; - } - - /** - * Recursively looks up type for ast expression until it's found - * @param ast - * @returns {String|null} - */ - getType(ast) { - if (Array.isArray(ast)) { - return this.getType(ast[ast.length - 1]); - } - switch (ast.type) { - case 'BlockStatement': - return this.getType(ast.body); - case 'ArrayExpression': - return `Array(${ ast.elements.length })`; - case 'Literal': - const literalKey = `${ast.start},${ast.end}`; - if (this.literalTypes[literalKey]) { - return this.literalTypes[literalKey]; - } - if (Number.isInteger(ast.value)) { - return 'LiteralInteger'; - } else if (ast.value === true || ast.value === false) { - return 'Boolean'; - } else { - return 'Number'; - } - case 'AssignmentExpression': - return this.getType(ast.left); - case 'CallExpression': - if (this.isAstMathFunction(ast)) { - return 'Number'; - } - if (!ast.callee || !ast.callee.name) { - if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) { - const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name; - this.inferArgumentTypesIfNeeded(functionName, ast.arguments); - return this.lookupReturnType(functionName, ast, this); - } - throw this.astErrorOutput('Unknown call expression', ast); - } - if (ast.callee && ast.callee.name) { - const functionName = ast.callee.name; - this.inferArgumentTypesIfNeeded(functionName, ast.arguments); - return this.lookupReturnType(functionName, ast, this); - } - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); - case 'BinaryExpression': - // modulos is Number - switch (ast.operator) { - case '%': - case '/': - if (this.fixIntegerDivisionAccuracy) { - return 'Number'; - } else { - break; - } - case '>': - case '<': - return 'Boolean'; - case '&': - case '|': - case '^': - case '<<': - case '>>': - case '>>>': - return 'Integer'; - } - const type = this.getType(ast.left); - if (this.isState('skip-literal-correction')) return type; - if (type === 'LiteralInteger') { - const rightType = this.getType(ast.right); - if (rightType === 'LiteralInteger') { - if (ast.left.value % 1 === 0) { - return 'Integer'; - } else { - return 'Float'; - } - } - return rightType; - } - return typeLookupMap[type] || type; - case 'UpdateExpression': - return this.getType(ast.argument); - case 'UnaryExpression': - if (ast.operator === '~') { - return 'Integer'; - } - return this.getType(ast.argument); - case 'VariableDeclaration': { - const declarations = ast.declarations; - let lastType; - for (let i = 0; i < declarations.length; i++) { - const declaration = declarations[i]; - lastType = this.getType(declaration); - } - if (!lastType) { - throw this.astErrorOutput(`Unable to find type for declaration`, ast); - } - return lastType; - } - case 'VariableDeclarator': - const declaration = this.getDeclaration(ast.id); - if (!declaration) { - throw this.astErrorOutput(`Unable to find declarator`, ast); - } - - if (!declaration.valueType) { - throw this.astErrorOutput(`Unable to find declarator valueType`, ast); - } - - return declaration.valueType; - case 'Identifier': - if (ast.name === 'Infinity') { - return 'Number'; - } - if (this.isAstVariable(ast)) { - const signature = this.getVariableSignature(ast); - if (signature === 'value') { - const type = this.getVariableType(ast); - if (!type) { - throw this.astErrorOutput(`Unable to find identifier valueType`, ast); - } - return type; - } - } - const origin = this.findIdentifierOrigin(ast); - if (origin && origin.init) { - return this.getType(origin.init); - } - return null; - case 'ReturnStatement': - return this.getType(ast.argument); - case 'MemberExpression': - if (this.isAstMathFunction(ast)) { - switch (ast.property.name) { - case 'ceil': - return 'Integer'; - case 'floor': - return 'Integer'; - case 'round': - return 'Integer'; - } - return 'Number'; - } - if (this.isAstVariable(ast)) { - const variableSignature = this.getVariableSignature(ast); - switch (variableSignature) { - case 'value[]': - return this.getLookupType(this.getVariableType(ast.object)); - case 'value[][]': - return this.getLookupType(this.getVariableType(ast.object.object)); - case 'value[][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object)); - case 'value[][][][]': - return this.getLookupType(this.getVariableType(ast.object.object.object.object)); - case 'value.thread.value': - case 'this.thread.value': - return 'Integer'; - case 'this.output.value': - return this.dynamicOutput ? 'Integer' : 'LiteralInteger'; - case 'this.constants.value': - return this.getConstantType(ast.property.name); - case 'this.constants.value[]': - return this.getLookupType(this.getConstantType(ast.object.property.name)); - case 'this.constants.value[][]': - return this.getLookupType(this.getConstantType(ast.object.object.property.name)); - case 'this.constants.value[][][]': - return this.getLookupType(this.getConstantType(ast.object.object.object.property.name)); - case 'this.constants.value[][][][]': - return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name)); - case 'fn()[]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][]': - return this.getLookupType(this.getType(ast.object)); - case 'fn()[][][]': - return this.getLookupType(this.getType(ast.object)); - case 'value.value': - if (this.isAstMathVariable(ast)) { - return 'Number'; - } - switch (ast.property.name) { - case 'r': - return this.getLookupType(this.getVariableType(ast.object)); - case 'g': - return this.getLookupType(this.getVariableType(ast.object)); - case 'b': - return this.getLookupType(this.getVariableType(ast.object)); - case 'a': - return this.getLookupType(this.getVariableType(ast.object)); - } - case '[][]': - return 'Number'; - } - throw this.astErrorOutput('Unhandled getType MemberExpression', ast); - } - throw this.astErrorOutput('Unhandled getType MemberExpression', ast); - case 'ConditionalExpression': - return this.getType(ast.consequent); - case 'FunctionDeclaration': - case 'FunctionExpression': - const lastReturn = this.findLastReturn(ast.body); - if (lastReturn) { - return this.getType(lastReturn); - } - return null; - case 'IfStatement': - return this.getType(ast.consequent); - default: - throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); - } - } - - inferArgumentTypesIfNeeded(functionName, args) { - // ensure arguments are filled in, so when we lookup return type, we already can infer it - for (let i = 0; i < args.length; i++) { - if (!this.needsArgumentType(functionName, i)) continue; - const type = this.getType(args[i]); - if (!type) { - throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]); - } - this.assignArgumentType(functionName, i, type); - } - } - - isAstMathVariable(ast) { - const mathProperties = [ - 'E', - 'PI', - 'SQRT2', - 'SQRT1_2', - 'LN2', - 'LN10', - 'LOG2E', - 'LOG10E', - ]; - return ast.type === 'MemberExpression' && - ast.object && ast.object.type === 'Identifier' && - ast.object.name === 'Math' && - ast.property && - ast.property.type === 'Identifier' && - mathProperties.indexOf(ast.property.name) > -1; - } - - isAstMathFunction(ast) { - const mathFunctions = [ - 'abs', - 'acos', - 'asin', - 'atan', - 'atan2', - 'ceil', - 'cos', - 'exp', - 'floor', - 'log', - 'log2', - 'max', - 'min', - 'pow', - 'random', - 'round', - 'sign', - 'sin', - 'sqrt', - 'tan', - ]; - return ast.type === 'CallExpression' && - ast.callee && - ast.callee.type === 'MemberExpression' && - ast.callee.object && - ast.callee.object.type === 'Identifier' && - ast.callee.object.name === 'Math' && - ast.callee.property && - ast.callee.property.type === 'Identifier' && - mathFunctions.indexOf(ast.callee.property.name) > -1; - } - - isAstVariable(ast) { - return ast.type === 'Identifier' || ast.type === 'MemberExpression'; - } - - isSafe(ast) { - return this.isSafeDependencies(this.getDependencies(ast)); - } - - isSafeDependencies(dependencies) { - return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true; - } - - /** - * - * @param ast - * @param dependencies - * @param isNotSafe - * @return {Array} - */ - getDependencies(ast, dependencies, isNotSafe) { - if (!dependencies) { - dependencies = []; - } - if (!ast) return null; - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.getDependencies(ast[i], dependencies, isNotSafe); - } - return dependencies; - } - switch (ast.type) { - case 'AssignmentExpression': - this.getDependencies(ast.left, dependencies, isNotSafe); - this.getDependencies(ast.right, dependencies, isNotSafe); - return dependencies; - case 'ConditionalExpression': - this.getDependencies(ast.test, dependencies, isNotSafe); - this.getDependencies(ast.alternate, dependencies, isNotSafe); - this.getDependencies(ast.consequent, dependencies, isNotSafe); - return dependencies; - case 'Literal': - dependencies.push({ - origin: 'literal', - value: ast.value, - isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value) - }); - break; - case 'VariableDeclarator': - return this.getDependencies(ast.init, dependencies, isNotSafe); - case 'Identifier': - const declaration = this.getDeclaration(ast); - if (declaration) { - dependencies.push({ - name: ast.name, - origin: 'declaration', - isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies), - }); - } else if (this.argumentNames.indexOf(ast.name) > -1) { - dependencies.push({ - name: ast.name, - origin: 'argument', - isSafe: false, - }); - } else if (this.strictTypingChecking) { - throw new Error(`Cannot find identifier origin "${ast.name}"`); - } - break; - case 'FunctionDeclaration': - return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe); - case 'ReturnStatement': - return this.getDependencies(ast.argument, dependencies); - case 'BinaryExpression': - isNotSafe = (ast.operator === '/' || ast.operator === '*'); - this.getDependencies(ast.left, dependencies, isNotSafe); - this.getDependencies(ast.right, dependencies, isNotSafe); - return dependencies; - case 'UnaryExpression': - case 'UpdateExpression': - return this.getDependencies(ast.argument, dependencies, isNotSafe); - case 'VariableDeclaration': - return this.getDependencies(ast.declarations, dependencies, isNotSafe); - case 'ArrayExpression': - dependencies.push({ - origin: 'declaration', - isSafe: true, - }); - return dependencies; - case 'CallExpression': - dependencies.push({ - origin: 'function', - isSafe: true, - }); - return dependencies; - case 'MemberExpression': - const details = this.getMemberExpressionDetails(ast); - switch (details.signature) { - case 'value[]': - this.getDependencies(ast.object, dependencies, isNotSafe); - break; - case 'value[][]': - this.getDependencies(ast.object.object, dependencies, isNotSafe); - break; - case 'value[][][]': - this.getDependencies(ast.object.object.object, dependencies, isNotSafe); - break; - case 'this.output.value': - if (this.dynamicOutput) { - dependencies.push({ - name: details.name, - origin: 'output', - isSafe: false, - }); - } - break; - } - if (details) { - if (details.property) { - this.getDependencies(details.property, dependencies, isNotSafe); - } - if (details.xProperty) { - this.getDependencies(details.xProperty, dependencies, isNotSafe); - } - if (details.yProperty) { - this.getDependencies(details.yProperty, dependencies, isNotSafe); - } - if (details.zProperty) { - this.getDependencies(details.zProperty, dependencies, isNotSafe); - } - return dependencies; - } - default: - throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); - } - return dependencies; - } - - getVariableSignature(ast) { - if (!this.isAstVariable(ast)) { - throw new Error(`ast of type "${ ast.type }" is not a variable signature`); - } - if (ast.type === 'Identifier') { - return 'value'; - } - const signature = []; - while (true) { - if (!ast) break; - if (ast.computed) { - signature.push('[]'); - } else if (ast.type === 'ThisExpression') { - signature.unshift('this'); - } else if (ast.property && ast.property.name) { - if ( - ast.property.name === 'x' || - ast.property.name === 'y' || - ast.property.name === 'z' - ) { - signature.unshift('.value'); - } else if ( - ast.property.name === 'constants' || - ast.property.name === 'thread' || - ast.property.name === 'output' - ) { - signature.unshift('.' + ast.property.name); - } else { - signature.unshift('.value'); - } - } else if (ast.name) { - signature.unshift('value'); - } else if (ast.callee && ast.callee.name) { - signature.unshift('fn()'); - } else if (ast.elements) { - signature.unshift('[]'); - } else { - signature.unshift('unknown'); - } - ast = ast.object; - } - - const signatureString = signature.join(''); - const allowedExpressions = [ - 'value', - 'value[]', - 'value[][]', - 'value[][][]', - 'value[][][][]', - 'value.value', - 'value.thread.value', - 'this.thread.value', - 'this.output.value', - 'this.constants.value', - 'this.constants.value[]', - 'this.constants.value[][]', - 'this.constants.value[][][]', - 'this.constants.value[][][][]', - 'fn()[]', - 'fn()[][]', - 'fn()[][][]', - '[][]', - ]; - if (allowedExpressions.indexOf(signatureString) > -1) { - return signatureString; - } - return null; - } - - build() { - return this.toString().length > 0; - } - - /** - * @desc Parses the abstract syntax tree for generically to its respective function - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the parsed string array - */ - astGeneric(ast, retArr) { - if (ast === null) { - throw this.astErrorOutput('NULL ast', ast); - } else { - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.astGeneric(ast[i], retArr); - } - return retArr; - } - - switch (ast.type) { - case 'FunctionDeclaration': - return this.astFunctionDeclaration(ast, retArr); - case 'FunctionExpression': - return this.astFunctionExpression(ast, retArr); - case 'ReturnStatement': - return this.astReturnStatement(ast, retArr); - case 'Literal': - return this.astLiteral(ast, retArr); - case 'BinaryExpression': - return this.astBinaryExpression(ast, retArr); - case 'Identifier': - return this.astIdentifierExpression(ast, retArr); - case 'AssignmentExpression': - return this.astAssignmentExpression(ast, retArr); - case 'ExpressionStatement': - return this.astExpressionStatement(ast, retArr); - case 'EmptyStatement': - return this.astEmptyStatement(ast, retArr); - case 'BlockStatement': - return this.astBlockStatement(ast, retArr); - case 'IfStatement': - return this.astIfStatement(ast, retArr); - case 'SwitchStatement': - return this.astSwitchStatement(ast, retArr); - case 'BreakStatement': - return this.astBreakStatement(ast, retArr); - case 'ContinueStatement': - return this.astContinueStatement(ast, retArr); - case 'ForStatement': - return this.astForStatement(ast, retArr); - case 'WhileStatement': - return this.astWhileStatement(ast, retArr); - case 'DoWhileStatement': - return this.astDoWhileStatement(ast, retArr); - case 'VariableDeclaration': - return this.astVariableDeclaration(ast, retArr); - case 'VariableDeclarator': - return this.astVariableDeclarator(ast, retArr); - case 'ThisExpression': - return this.astThisExpression(ast, retArr); - case 'SequenceExpression': - return this.astSequenceExpression(ast, retArr); - case 'UnaryExpression': - return this.astUnaryExpression(ast, retArr); - case 'UpdateExpression': - return this.astUpdateExpression(ast, retArr); - case 'LogicalExpression': - return this.astLogicalExpression(ast, retArr); - case 'MemberExpression': - return this.astMemberExpression(ast, retArr); - case 'CallExpression': - return this.astCallExpression(ast, retArr); - case 'ArrayExpression': - return this.astArrayExpression(ast, retArr); - case 'DebuggerStatement': - return this.astDebuggerStatement(ast, retArr); - case 'ConditionalExpression': - return this.astConditionalExpression(ast, retArr); - } - - throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); - } - } - /** - * @desc To throw the AST error, with its location. - * @param {string} error - the error message output - * @param {Object} ast - the AST object where the error is - */ - astErrorOutput(error, ast) { - if (typeof this.source !== 'string') { - return new Error(error); - } - - const debugString = utils.getAstString(this.source, ast); - const leadingSource = this.source.substr(ast.start); - const splitLines = leadingSource.split(/\n/); - const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0; - return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`); - } - - astDebuggerStatement(arrNode, retArr) { - return retArr; - } - - astConditionalExpression(ast, retArr) { - if (ast.type !== 'ConditionalExpression') { - throw this.astErrorOutput('Not a conditional expression', ast); - } - retArr.push('('); - this.astGeneric(ast.test, retArr); - retArr.push('?'); - this.astGeneric(ast.consequent, retArr); - retArr.push(':'); - this.astGeneric(ast.alternate, retArr); - retArr.push(')'); - return retArr; - } - - /** - * @abstract - * @param {Object} ast - * @param {String[]} retArr - * @returns {String[]} - */ - astFunction(ast, retArr) { - throw new Error(`"astFunction" not defined on ${ this.constructor.name }`); - } - - /** - * @desc Parses the abstract syntax tree for to its *named function declaration* - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astFunctionDeclaration(ast, retArr) { - if (this.isChildFunction(ast)) { - return retArr; - } - return this.astFunction(ast, retArr); - } - astFunctionExpression(ast, retArr) { - if (this.isChildFunction(ast)) { - return retArr; - } - return this.astFunction(ast, retArr); - } - isChildFunction(ast) { - for (let i = 0; i < this.functions.length; i++) { - if (this.functions[i] === ast) { - return true; - } - } - return false; - } - astReturnStatement(ast, retArr) { - return retArr; - } - astLiteral(ast, retArr) { - this.literalTypes[`${ast.start},${ast.end}`] = 'Number'; - return retArr; - } - astBinaryExpression(ast, retArr) { - return retArr; - } - astIdentifierExpression(ast, retArr) { - return retArr; - } - astAssignmentExpression(ast, retArr) { - return retArr; - } - /** - * @desc Parses the abstract syntax tree for *generic expression* statement - * @param {Object} esNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astExpressionStatement(esNode, retArr) { - this.astGeneric(esNode.expression, retArr); - retArr.push(';'); - return retArr; - } - /** - * @desc Parses the abstract syntax tree for an *Empty* Statement - * @param {Object} eNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astEmptyStatement(eNode, retArr) { - return retArr; - } - astBlockStatement(ast, retArr) { - return retArr; - } - astIfStatement(ast, retArr) { - return retArr; - } - astSwitchStatement(ast, retArr) { - return retArr; - } - /** - * @desc Parses the abstract syntax tree for *Break* Statement - * @param {Object} brNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astBreakStatement(brNode, retArr) { - retArr.push('break;'); - return retArr; - } - /** - * @desc Parses the abstract syntax tree for *Continue* Statement - * @param {Object} crNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astContinueStatement(crNode, retArr) { - retArr.push('continue;\n'); - return retArr; - } - astForStatement(ast, retArr) { - return retArr; - } - astWhileStatement(ast, retArr) { - return retArr; - } - astDoWhileStatement(ast, retArr) { - return retArr; - } - /** - * @desc Parses the abstract syntax tree for *Variable Declaration* - * @param {Object} varDecNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astVariableDeclaration(varDecNode, retArr) { - const declarations = varDecNode.declarations; - if (!declarations || !declarations[0] || !declarations[0].init) { - throw this.astErrorOutput('Unexpected expression', varDecNode); - } - const result = []; - const firstDeclaration = declarations[0]; - const init = firstDeclaration.init; - let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); - if (type === 'LiteralInteger') { - // We had the choice to go either float or int, choosing float - type = 'Number'; - } - const markupType = typeMap[type]; - if (!markupType) { - throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); - } - let dependencies = this.getDependencies(firstDeclaration.init); - throw new Error('remove me'); - this.declarations[firstDeclaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: dependencies.every(dependency => dependency.isSafe) - }); - const initResult = [`${type} user_${firstDeclaration.id.name}=`]; - this.astGeneric(init, initResult); - result.push(initResult.join('')); - - // first declaration is done, now any added ones setup - for (let i = 1; i < declarations.length; i++) { - const declaration = declarations[i]; - dependencies = this.getDependencies(declaration); - throw new Error('Remove me'); - this.declarations[declaration.id.name] = Object.freeze({ - type, - dependencies, - isSafe: false - }); - this.astGeneric(declaration, result); - } - - retArr.push(retArr, result.join(',')); - retArr.push(';'); - return retArr; - } - /** - * @desc Parses the abstract syntax tree for *Variable Declarator* - * @param {Object} iVarDecNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astVariableDeclarator(iVarDecNode, retArr) { - this.astGeneric(iVarDecNode.id, retArr); - if (iVarDecNode.init !== null) { - retArr.push('='); - this.astGeneric(iVarDecNode.init, retArr); - } - return retArr; - } - astThisExpression(ast, retArr) { - return retArr; - } - astSequenceExpression(sNode, retArr) { - for (let i = 0; i < sNode.expressions.length; i++) { - if (i > 0) { - retArr.push(','); - } - this.astGeneric(sNode.expressions, retArr); - } - return retArr; - } - /** - * @desc Parses the abstract syntax tree for *Unary* Expression - * @param {Object} uNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astUnaryExpression(uNode, retArr) { - const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); - if (unaryResult) { - return retArr; - } - - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); - } - - return retArr; - } - - checkAndUpconvertBitwiseUnary(uNode, retArr) {} - - /** - * @desc Parses the abstract syntax tree for *Update* Expression - * @param {Object} uNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astUpdateExpression(uNode, retArr) { - if (uNode.prefix) { - retArr.push(uNode.operator); - this.astGeneric(uNode.argument, retArr); - } else { - this.astGeneric(uNode.argument, retArr); - retArr.push(uNode.operator); - } - - return retArr; - } - /** - * @desc Parses the abstract syntax tree for *Logical* Expression - * @param {Object} logNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astLogicalExpression(logNode, retArr) { - retArr.push('('); - this.astGeneric(logNode.left, retArr); - retArr.push(logNode.operator); - this.astGeneric(logNode.right, retArr); - retArr.push(')'); - return retArr; - } - astMemberExpression(ast, retArr) { - return retArr; - } - astCallExpression(ast, retArr) { - return retArr; - } - astArrayExpression(ast, retArr) { - return retArr; - } - - /** - * - * @param ast - * @return {IFunctionNodeMemberExpressionDetails} - */ - getMemberExpressionDetails(ast) { - if (ast.type !== 'MemberExpression') { - throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast); - } - let name = null; - let type = null; - const variableSignature = this.getVariableSignature(ast); - switch (variableSignature) { - case 'value': - return null; - case 'value.thread.value': - case 'this.thread.value': - case 'this.output.value': - return { - signature: variableSignature, - type: 'Integer', - name: ast.property.name - }; - case 'value[]': - if (typeof ast.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object), - xProperty: ast.property - }; - case 'value[][]': - if (typeof ast.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object), - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value[][][]': - if (typeof ast.object.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object.object), - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value[][][][]': - if (typeof ast.object.object.object.object.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.object.object.name; - return { - name, - origin: 'user', - signature: variableSignature, - type: this.getVariableType(ast.object.object.object.object), - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - case 'value.value': - if (typeof ast.property.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - if (this.isAstMathVariable(ast)) { - name = ast.property.name; - return { - name, - origin: 'Math', - type: 'Number', - signature: variableSignature, - }; - } - switch (ast.property.name) { - case 'r': - case 'g': - case 'b': - case 'a': - name = ast.object.name; - return { - name, - property: ast.property.name, - origin: 'user', - signature: variableSignature, - type: 'Number' - }; - default: - throw this.astErrorOutput('Unexpected expression', ast); - } - case 'this.constants.value': - if (typeof ast.property.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } - return { - name, - type, - origin: 'constants', - signature: variableSignature, - }; - case 'this.constants.value[]': - if (typeof ast.object.property.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } - return { - name, - type, - origin: 'constants', - signature: variableSignature, - xProperty: ast.property, - }; - case 'this.constants.value[][]': { - if (typeof ast.object.object.property.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } - return { - name, - type, - origin: 'constants', - signature: variableSignature, - yProperty: ast.object.property, - xProperty: ast.property, - }; - } - case 'this.constants.value[][][]': { - if (typeof ast.object.object.object.property.name !== 'string') { - throw this.astErrorOutput('Unexpected expression', ast); - } - name = ast.object.object.object.property.name; - type = this.getConstantType(name); - if (!type) { - throw this.astErrorOutput('Constant has no type', ast); - } - return { - name, - type, - origin: 'constants', - signature: variableSignature, - zProperty: ast.object.object.property, - yProperty: ast.object.property, - xProperty: ast.property, - }; - } - case 'fn()[]': - case '[][]': - return { - signature: variableSignature, - property: ast.property, - }; - default: - throw this.astErrorOutput('Unexpected expression', ast); - } - } - - findIdentifierOrigin(astToFind) { - const stack = [this.ast]; - - while (stack.length > 0) { - const atNode = stack[0]; - if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) { - return atNode; - } - stack.shift(); - if (atNode.argument) { - stack.push(atNode.argument); - } else if (atNode.body) { - stack.push(atNode.body); - } else if (atNode.declarations) { - stack.push(atNode.declarations); - } else if (Array.isArray(atNode)) { - for (let i = 0; i < atNode.length; i++) { - stack.push(atNode[i]); - } - } - } - return null; - } - - findLastReturn(ast) { - const stack = [ast || this.ast]; - - while (stack.length > 0) { - const atNode = stack.pop(); - if (atNode.type === 'ReturnStatement') { - return atNode; - } - if (atNode.type === 'FunctionDeclaration') { - continue; - } - if (atNode.argument) { - stack.push(atNode.argument); - } else if (atNode.body) { - stack.push(atNode.body); - } else if (atNode.declarations) { - stack.push(atNode.declarations); - } else if (Array.isArray(atNode)) { - for (let i = 0; i < atNode.length; i++) { - stack.push(atNode[i]); - } - } else if (atNode.consequent) { - stack.push(atNode.consequent); - } else if (atNode.cases) { - stack.push(atNode.cases); - } - } - return null; - } - - getInternalVariableName(name) { - if (!this._internalVariableNames.hasOwnProperty(name)) { - this._internalVariableNames[name] = 0; - } - this._internalVariableNames[name]++; - if (this._internalVariableNames[name] === 1) { - return name; - } - return name + this._internalVariableNames[name]; - } - - varWarn() { - console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); - } -} - -const typeLookupMap = { - 'Number': 'Number', - 'Float': 'Float', - 'Integer': 'Integer', - 'Array': 'Number', - 'Array(2)': 'Number', - 'Array(3)': 'Number', - 'Array(4)': 'Number', - 'Array2D': 'Number', - 'Array3D': 'Number', - 'Input': 'Number', - 'HTMLImage': 'Array(4)', - 'HTMLVideo': 'Array(4)', - 'HTMLImageArray': 'Array(4)', - 'NumberTexture': 'Number', - 'MemoryOptimizedNumberTexture': 'Number', - 'Array1D(2)': 'Array(2)', - 'Array1D(3)': 'Array(3)', - 'Array1D(4)': 'Array(4)', - 'Array2D(2)': 'Array(2)', - 'Array2D(3)': 'Array(3)', - 'Array2D(4)': 'Array(4)', - 'Array3D(2)': 'Array(2)', - 'Array3D(3)': 'Array(3)', - 'Array3D(4)': 'Array(4)', - 'ArrayTexture(1)': 'Number', - 'ArrayTexture(2)': 'Array(2)', - 'ArrayTexture(3)': 'Array(3)', - 'ArrayTexture(4)': 'Array(4)', -}; - -module.exports = { - FunctionNode -}; \ No newline at end of file +import { parse } from 'acorn'; +import { FunctionTracer } from './function-tracer'; +import { + getArgumentNamesFromString, + getAstString, + getFunctionNameFromString, + isFunctionString, +} from '../common'; + +/** + * + * @desc Represents a single function, inside JS, webGL, or openGL. + *

This handles all the raw state, converted state, etc. Of a single function.

+ */ +export class FunctionNode { + /** + * + * @param {string|object} source + * @param {IFunctionSettings} [settings] + */ + constructor(source, settings) { + if (!source && !settings.ast) { + throw new Error('source parameter is missing'); + } + settings = settings || {}; + this.source = source; + this.ast = null; + this.name = typeof source === 'string' ? settings.isRootKernel ? + 'kernel' : + (settings.name || getFunctionNameFromString(source)) : null; + this.calledFunctions = []; + this.constants = {}; + this.constantTypes = {}; + this.constantBitRatios = {}; + this.isRootKernel = false; + this.isSubKernel = false; + this.debug = null; + this.declarations = null; + this.functions = null; + this.identifiers = null; + this.contexts = null; + this.functionCalls = null; + this.states = []; + this.needsArgumentType = null; + this.assignArgumentType = null; + this.lookupReturnType = null; + this.lookupFunctionArgumentTypes = null; + this.lookupFunctionArgumentBitRatio = null; + this.triggerImplyArgumentType = null; + this.triggerImplyArgumentBitRatio = null; + this.onNestedFunction = null; + this.onFunctionCall = null; + this.optimizeFloatMemory = null; + this.precision = null; + this.loopMaxIterations = null; + this.argumentNames = (typeof this.source === 'string' ? getArgumentNamesFromString(this.source) : null); + this.argumentTypes = []; + this.argumentSizes = []; + this.argumentBitRatios = null; + this.returnType = null; + this.output = []; + this.plugins = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.dynamicOutput = null; + this.dynamicArguments = null; + this.strictTypingChecking = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + + if (settings) { + for (const p in settings) { + if (!settings.hasOwnProperty(p)) continue; + if (!this.hasOwnProperty(p)) continue; + this[p] = settings[p]; + } + } + + this.literalTypes = {}; + + this.validate(); + this._string = null; + this._internalVariableNames = {}; + } + + validate() { + if (typeof this.source !== 'string' && !this.ast) { + throw new Error('this.source not a string'); + } + + if (!this.ast && !isFunctionString(this.source)) { + throw new Error('this.source not a function string'); + } + + if (!this.name) { + throw new Error('this.name could not be set'); + } + + if (this.argumentTypes.length > 0 && this.argumentTypes.length !== this.argumentNames.length) { + throw new Error(`argumentTypes count of ${ this.argumentTypes.length } exceeds ${ this.argumentNames.length }`); + } + + if (this.output.length < 1) { + throw new Error('this.output is not big enough'); + } + } + + /** + * @param {String} name + * @returns {boolean} + */ + isIdentifierConstant(name) { + if (!this.constants) return false; + return this.constants.hasOwnProperty(name); + } + + isInput(argumentName) { + return this.argumentTypes[this.argumentNames.indexOf(argumentName)] === 'Input'; + } + + pushState(state) { + this.states.push(state); + } + + popState(state) { + if (this.state !== state) { + throw new Error(`Cannot popState ${ state } when in ${ this.state }`); + } + this.states.pop(); + } + + isState(state) { + return this.state === state; + } + + get state() { + return this.states[this.states.length - 1]; + } + + /** + * @function + * @name astMemberExpressionUnroll + * @desc Parses the abstract syntax tree for binary expression. + * + *

Utility function for astCallExpression.

+ * + * @param {Object} ast - the AST object to parse + * + * @returns {String} the function namespace call, unrolled + */ + astMemberExpressionUnroll(ast) { + if (ast.type === 'Identifier') { + return ast.name; + } else if (ast.type === 'ThisExpression') { + return 'this'; + } + + if (ast.type === 'MemberExpression') { + if (ast.object && ast.property) { + //babel sniffing + if (ast.object.hasOwnProperty('name') && ast.object.name[0] === '_') { + return this.astMemberExpressionUnroll(ast.property); + } + + return ( + this.astMemberExpressionUnroll(ast.object) + + '.' + + this.astMemberExpressionUnroll(ast.property) + ); + } + } + + //babel sniffing + if (ast.hasOwnProperty('expressions')) { + const firstExpression = ast.expressions[0]; + if (firstExpression.type === 'Literal' && firstExpression.value === 0 && ast.expressions.length === 2) { + return this.astMemberExpressionUnroll(ast.expressions[1]); + } + } + + // Failure, unknown expression + throw this.astErrorOutput('Unknown astMemberExpressionUnroll', ast); + } + + /** + * @desc Parses the class function JS, and returns its Abstract Syntax Tree object. + * This is used internally to convert to shader code + * + * @param {Object} [inParser] - Parser to use, assumes in scope 'parser' if null or undefined + * + * @returns {Object} The function AST Object, note that result is cached under this.ast; + */ + getJsAST(inParser) { + if (this.ast) { + return this.ast; + } + if (typeof this.source === 'object') { + this.traceFunctionAST(this.source); + return this.ast = this.source; + } + + const parser = inParser && inParser.hasOwnProperty('parse') ? inParser.parse : parse + if (inParser === null) { + throw new Error('Missing JS to AST parser'); + } + + const ast = Object.freeze(parser(`const parser_${ this.name } = ${ this.source };`, { + locations: true + })); + // take out the function object, outside the var declarations + const functionAST = ast.body[0].declarations[0].init; + this.traceFunctionAST(functionAST); + + if (!ast) { + throw new Error('Failed to parse JS code'); + } + + return this.ast = functionAST; + } + + traceFunctionAST(ast) { + const { contexts, declarations, functions, identifiers, functionCalls } = new FunctionTracer(ast); + this.contexts = contexts; + this.identifiers = identifiers; + this.functionCalls = functionCalls; + this.declarations = []; + this.functions = functions; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + const { ast, context, name, origin, forceInteger, assignable } = declaration; + const { init } = ast; + const dependencies = this.getDependencies(init); + let valueType = null; + + if (forceInteger) { + valueType = 'Integer'; + } else { + if (init) { + const realType = this.getType(init); + switch (realType) { + case 'Integer': + case 'Float': + case 'Number': + if (init.type === 'MemberExpression') { + valueType = realType; + } else { + valueType = 'Number'; + } + break; + case 'LiteralInteger': + valueType = 'Number'; + break; + default: + valueType = realType; + } + } + } + this.declarations.push({ + valueType, + dependencies, + isSafe: this.isSafeDependencies(dependencies), + ast, + name, + context, + origin, + assignable, + }); + } + + for (let i = 0; i < functions.length; i++) { + this.onNestedFunction(functions[i]); + } + } + + getDeclaration(ast) { + for (let i = 0; i < this.identifiers.length; i++) { + const identifier = this.identifiers[i]; + if (ast === identifier.ast && identifier.context.hasOwnProperty(ast.name)) { + for (let j = 0; j < this.declarations.length; j++) { + const declaration = this.declarations[j]; + if (declaration.name === ast.name && declaration.context[ast.name] === identifier.context[ast.name]) { + return declaration; + } + } + } + } + return null; + } + + /** + * @desc Return the type of parameter sent to subKernel/Kernel. + * @param {Object} ast - Identifier + * @returns {String} Type of the parameter + */ + getVariableType(ast) { + if (ast.type !== 'Identifier') { + throw new Error(`ast of ${ast.type} not "Identifier"`); + } + let type = null; + const argumentIndex = this.argumentNames.indexOf(ast.name); + if (argumentIndex === -1) { + const declaration = this.getDeclaration(ast); + if (declaration) { + return declaration.valueType; + } + } else { + const argumentType = this.argumentTypes[argumentIndex]; + if (argumentType) { + type = argumentType; + } + } + if (!type && this.strictTypingChecking) { + throw new Error(`Declaration of ${name} not found`); + } + return type; + } + + /** + * Generally used to lookup the value type returned from a member expressions + * @param {String} type + * @return {String} + */ + getLookupType(type) { + if (!typeLookupMap.hasOwnProperty(type)) { + throw new Error(`unknown typeLookupMap ${ type }`); + } + return typeLookupMap[type]; + } + + getConstantType(constantName) { + if (this.constantTypes[constantName]) { + const type = this.constantTypes[constantName]; + if (type === 'Float') { + return 'Number'; + } else { + return type; + } + } + throw new Error(`Type for constant "${ constantName }" not declared`); + } + + toString() { + if (this._string) return this._string; + return this._string = this.astGeneric(this.getJsAST(), []).join('').trim(); + } + + toJSON() { + const settings = { + source: this.source, + name: this.name, + constants: this.constants, + constantTypes: this.constantTypes, + isRootKernel: this.isRootKernel, + isSubKernel: this.isSubKernel, + debug: this.debug, + output: this.output, + loopMaxIterations: this.loopMaxIterations, + argumentNames: this.argumentNames, + argumentTypes: this.argumentTypes, + argumentSizes: this.argumentSizes, + returnType: this.returnType, + leadingReturnStatement: this.leadingReturnStatement, + followingReturnStatement: this.followingReturnStatement, + }; + + return { + ast: this.ast, + settings + }; + } + + /** + * Recursively looks up type for ast expression until it's found + * @param ast + * @returns {String|null} + */ + getType(ast) { + if (Array.isArray(ast)) { + return this.getType(ast[ast.length - 1]); + } + switch (ast.type) { + case 'BlockStatement': + return this.getType(ast.body); + case 'ArrayExpression': + return `Array(${ ast.elements.length })`; + case 'Literal': + const literalKey = `${ast.start},${ast.end}`; + if (this.literalTypes[literalKey]) { + return this.literalTypes[literalKey]; + } + if (Number.isInteger(ast.value)) { + return 'LiteralInteger'; + } else if (ast.value === true || ast.value === false) { + return 'Boolean'; + } else { + return 'Number'; + } + case 'AssignmentExpression': + return this.getType(ast.left); + case 'CallExpression': + if (this.isAstMathFunction(ast)) { + return 'Number'; + } + if (!ast.callee || !ast.callee.name) { + if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[ast.callee.expressions.length - 1].property.name) { + const functionName = ast.callee.expressions[ast.callee.expressions.length - 1].property.name; + this.inferArgumentTypesIfNeeded(functionName, ast.arguments); + return this.lookupReturnType(functionName, ast, this); + } + throw this.astErrorOutput('Unknown call expression', ast); + } + if (ast.callee && ast.callee.name) { + const functionName = ast.callee.name; + this.inferArgumentTypesIfNeeded(functionName, ast.arguments); + return this.lookupReturnType(functionName, ast, this); + } + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + case 'BinaryExpression': + // modulos is Number + switch (ast.operator) { + case '%': + case '/': + if (this.fixIntegerDivisionAccuracy) { + return 'Number'; + } else { + break; + } + case '>': + case '<': + return 'Boolean'; + case '&': + case '|': + case '^': + case '<<': + case '>>': + case '>>>': + return 'Integer'; + } + const type = this.getType(ast.left); + if (this.isState('skip-literal-correction')) return type; + if (type === 'LiteralInteger') { + const rightType = this.getType(ast.right); + if (rightType === 'LiteralInteger') { + if (ast.left.value % 1 === 0) { + return 'Integer'; + } else { + return 'Float'; + } + } + return rightType; + } + return typeLookupMap[type] || type; + case 'UpdateExpression': + return this.getType(ast.argument); + case 'UnaryExpression': + if (ast.operator === '~') { + return 'Integer'; + } + return this.getType(ast.argument); + case 'VariableDeclaration': { + const declarations = ast.declarations; + let lastType; + for (let i = 0; i < declarations.length; i++) { + const declaration = declarations[i]; + lastType = this.getType(declaration); + } + if (!lastType) { + throw this.astErrorOutput(`Unable to find type for declaration`, ast); + } + return lastType; + } + case 'VariableDeclarator': + const declaration = this.getDeclaration(ast.id); + if (!declaration) { + throw this.astErrorOutput(`Unable to find declarator`, ast); + } + + if (!declaration.valueType) { + throw this.astErrorOutput(`Unable to find declarator valueType`, ast); + } + + return declaration.valueType; + case 'Identifier': + if (ast.name === 'Infinity') { + return 'Number'; + } + if (this.isAstVariable(ast)) { + const signature = this.getVariableSignature(ast); + if (signature === 'value') { + const type = this.getVariableType(ast); + if (!type) { + throw this.astErrorOutput(`Unable to find identifier valueType`, ast); + } + return type; + } + } + const origin = this.findIdentifierOrigin(ast); + if (origin && origin.init) { + return this.getType(origin.init); + } + return null; + case 'ReturnStatement': + return this.getType(ast.argument); + case 'MemberExpression': + if (this.isAstMathFunction(ast)) { + switch (ast.property.name) { + case 'ceil': + return 'Integer'; + case 'floor': + return 'Integer'; + case 'round': + return 'Integer'; + } + return 'Number'; + } + if (this.isAstVariable(ast)) { + const variableSignature = this.getVariableSignature(ast); + switch (variableSignature) { + case 'value[]': + return this.getLookupType(this.getVariableType(ast.object)); + case 'value[][]': + return this.getLookupType(this.getVariableType(ast.object.object)); + case 'value[][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object)); + case 'value[][][][]': + return this.getLookupType(this.getVariableType(ast.object.object.object.object)); + case 'value.thread.value': + case 'this.thread.value': + return 'Integer'; + case 'this.output.value': + return this.dynamicOutput ? 'Integer' : 'LiteralInteger'; + case 'this.constants.value': + return this.getConstantType(ast.property.name); + case 'this.constants.value[]': + return this.getLookupType(this.getConstantType(ast.object.property.name)); + case 'this.constants.value[][]': + return this.getLookupType(this.getConstantType(ast.object.object.property.name)); + case 'this.constants.value[][][]': + return this.getLookupType(this.getConstantType(ast.object.object.object.property.name)); + case 'this.constants.value[][][][]': + return this.getLookupType(this.getConstantType(ast.object.object.object.object.property.name)); + case 'fn()[]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][]': + return this.getLookupType(this.getType(ast.object)); + case 'fn()[][][]': + return this.getLookupType(this.getType(ast.object)); + case 'value.value': + if (this.isAstMathVariable(ast)) { + return 'Number'; + } + switch (ast.property.name) { + case 'r': + return this.getLookupType(this.getVariableType(ast.object)); + case 'g': + return this.getLookupType(this.getVariableType(ast.object)); + case 'b': + return this.getLookupType(this.getVariableType(ast.object)); + case 'a': + return this.getLookupType(this.getVariableType(ast.object)); + } + case '[][]': + return 'Number'; + } + throw this.astErrorOutput('Unhandled getType MemberExpression', ast); + } + throw this.astErrorOutput('Unhandled getType MemberExpression', ast); + case 'ConditionalExpression': + return this.getType(ast.consequent); + case 'FunctionDeclaration': + case 'FunctionExpression': + const lastReturn = this.findLastReturn(ast.body); + if (lastReturn) { + return this.getType(lastReturn); + } + return null; + case 'IfStatement': + return this.getType(ast.consequent); + default: + throw this.astErrorOutput(`Unhandled getType Type "${ ast.type }"`, ast); + } + } + + inferArgumentTypesIfNeeded(functionName, args) { + // ensure arguments are filled in, so when we lookup return type, we already can infer it + for (let i = 0; i < args.length; i++) { + if (!this.needsArgumentType(functionName, i)) continue; + const type = this.getType(args[i]); + if (!type) { + throw this.astErrorOutput(`Unable to infer argument ${i}`, args[i]); + } + this.assignArgumentType(functionName, i, type); + } + } + + isAstMathVariable(ast) { + const mathProperties = [ + 'E', + 'PI', + 'SQRT2', + 'SQRT1_2', + 'LN2', + 'LN10', + 'LOG2E', + 'LOG10E', + ]; + return ast.type === 'MemberExpression' && + ast.object && ast.object.type === 'Identifier' && + ast.object.name === 'Math' && + ast.property && + ast.property.type === 'Identifier' && + mathProperties.indexOf(ast.property.name) > -1; + } + + isAstMathFunction(ast) { + const mathFunctions = [ + 'abs', + 'acos', + 'asin', + 'atan', + 'atan2', + 'ceil', + 'cos', + 'exp', + 'floor', + 'log', + 'log2', + 'max', + 'min', + 'pow', + 'random', + 'round', + 'sign', + 'sin', + 'sqrt', + 'tan', + ]; + return ast.type === 'CallExpression' && + ast.callee && + ast.callee.type === 'MemberExpression' && + ast.callee.object && + ast.callee.object.type === 'Identifier' && + ast.callee.object.name === 'Math' && + ast.callee.property && + ast.callee.property.type === 'Identifier' && + mathFunctions.indexOf(ast.callee.property.name) > -1; + } + + isAstVariable(ast) { + return ast.type === 'Identifier' || ast.type === 'MemberExpression'; + } + + isSafe(ast) { + return this.isSafeDependencies(this.getDependencies(ast)); + } + + isSafeDependencies(dependencies) { + return dependencies && dependencies.every ? dependencies.every(dependency => dependency.isSafe) : true; + } + + /** + * + * @param ast + * @param dependencies + * @param isNotSafe + * @return {Array} + */ + getDependencies(ast, dependencies, isNotSafe) { + if (!dependencies) { + dependencies = []; + } + if (!ast) return null; + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.getDependencies(ast[i], dependencies, isNotSafe); + } + return dependencies; + } + switch (ast.type) { + case 'AssignmentExpression': + this.getDependencies(ast.left, dependencies, isNotSafe); + this.getDependencies(ast.right, dependencies, isNotSafe); + return dependencies; + case 'ConditionalExpression': + this.getDependencies(ast.test, dependencies, isNotSafe); + this.getDependencies(ast.alternate, dependencies, isNotSafe); + this.getDependencies(ast.consequent, dependencies, isNotSafe); + return dependencies; + case 'Literal': + dependencies.push({ + origin: 'literal', + value: ast.value, + isSafe: isNotSafe === true ? false : ast.value > -Infinity && ast.value < Infinity && !isNaN(ast.value) + }); + break; + case 'VariableDeclarator': + return this.getDependencies(ast.init, dependencies, isNotSafe); + case 'Identifier': + const declaration = this.getDeclaration(ast); + if (declaration) { + dependencies.push({ + name: ast.name, + origin: 'declaration', + isSafe: isNotSafe ? false : this.isSafeDependencies(declaration.dependencies), + }); + } else if (this.argumentNames.indexOf(ast.name) > -1) { + dependencies.push({ + name: ast.name, + origin: 'argument', + isSafe: false, + }); + } else if (this.strictTypingChecking) { + throw new Error(`Cannot find identifier origin "${ast.name}"`); + } + break; + case 'FunctionDeclaration': + return this.getDependencies(ast.body.body[ast.body.body.length - 1], dependencies, isNotSafe); + case 'ReturnStatement': + return this.getDependencies(ast.argument, dependencies); + case 'BinaryExpression': + isNotSafe = (ast.operator === '/' || ast.operator === '*'); + this.getDependencies(ast.left, dependencies, isNotSafe); + this.getDependencies(ast.right, dependencies, isNotSafe); + return dependencies; + case 'UnaryExpression': + case 'UpdateExpression': + return this.getDependencies(ast.argument, dependencies, isNotSafe); + case 'VariableDeclaration': + return this.getDependencies(ast.declarations, dependencies, isNotSafe); + case 'ArrayExpression': + dependencies.push({ + origin: 'declaration', + isSafe: true, + }); + return dependencies; + case 'CallExpression': + dependencies.push({ + origin: 'function', + isSafe: true, + }); + return dependencies; + case 'MemberExpression': + const details = this.getMemberExpressionDetails(ast); + switch (details.signature) { + case 'value[]': + this.getDependencies(ast.object, dependencies, isNotSafe); + break; + case 'value[][]': + this.getDependencies(ast.object.object, dependencies, isNotSafe); + break; + case 'value[][][]': + this.getDependencies(ast.object.object.object, dependencies, isNotSafe); + break; + case 'this.output.value': + if (this.dynamicOutput) { + dependencies.push({ + name: details.name, + origin: 'output', + isSafe: false, + }); + } + break; + } + if (details) { + if (details.property) { + this.getDependencies(details.property, dependencies, isNotSafe); + } + if (details.xProperty) { + this.getDependencies(details.xProperty, dependencies, isNotSafe); + } + if (details.yProperty) { + this.getDependencies(details.yProperty, dependencies, isNotSafe); + } + if (details.zProperty) { + this.getDependencies(details.zProperty, dependencies, isNotSafe); + } + return dependencies; + } + default: + throw this.astErrorOutput(`Unhandled type ${ ast.type } in getDependencies`, ast); + } + return dependencies; + } + + getVariableSignature(ast) { + if (!this.isAstVariable(ast)) { + throw new Error(`ast of type "${ ast.type }" is not a variable signature`); + } + if (ast.type === 'Identifier') { + return 'value'; + } + const signature = []; + while (true) { + if (!ast) break; + if (ast.computed) { + signature.push('[]'); + } else if (ast.type === 'ThisExpression') { + signature.unshift('this'); + } else if (ast.property && ast.property.name) { + if ( + ast.property.name === 'x' || + ast.property.name === 'y' || + ast.property.name === 'z' + ) { + signature.unshift('.value'); + } else if ( + ast.property.name === 'constants' || + ast.property.name === 'thread' || + ast.property.name === 'output' + ) { + signature.unshift('.' + ast.property.name); + } else { + signature.unshift('.value'); + } + } else if (ast.name) { + signature.unshift('value'); + } else if (ast.callee && ast.callee.name) { + signature.unshift('fn()'); + } else if (ast.elements) { + signature.unshift('[]'); + } else { + signature.unshift('unknown'); + } + ast = ast.object; + } + + const signatureString = signature.join(''); + const allowedExpressions = [ + 'value', + 'value[]', + 'value[][]', + 'value[][][]', + 'value[][][][]', + 'value.value', + 'value.thread.value', + 'this.thread.value', + 'this.output.value', + 'this.constants.value', + 'this.constants.value[]', + 'this.constants.value[][]', + 'this.constants.value[][][]', + 'this.constants.value[][][][]', + 'fn()[]', + 'fn()[][]', + 'fn()[][][]', + '[][]', + ]; + if (allowedExpressions.indexOf(signatureString) > -1) { + return signatureString; + } + return null; + } + + build() { + return this.toString().length > 0; + } + + /** + * @desc Parses the abstract syntax tree for generically to its respective function + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the parsed string array + */ + astGeneric(ast, retArr) { + if (ast === null) { + throw this.astErrorOutput('NULL ast', ast); + } else { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.astGeneric(ast[i], retArr); + } + return retArr; + } + + switch (ast.type) { + case 'FunctionDeclaration': + return this.astFunctionDeclaration(ast, retArr); + case 'FunctionExpression': + return this.astFunctionExpression(ast, retArr); + case 'ReturnStatement': + return this.astReturnStatement(ast, retArr); + case 'Literal': + return this.astLiteral(ast, retArr); + case 'BinaryExpression': + return this.astBinaryExpression(ast, retArr); + case 'Identifier': + return this.astIdentifierExpression(ast, retArr); + case 'AssignmentExpression': + return this.astAssignmentExpression(ast, retArr); + case 'ExpressionStatement': + return this.astExpressionStatement(ast, retArr); + case 'EmptyStatement': + return this.astEmptyStatement(ast, retArr); + case 'BlockStatement': + return this.astBlockStatement(ast, retArr); + case 'IfStatement': + return this.astIfStatement(ast, retArr); + case 'SwitchStatement': + return this.astSwitchStatement(ast, retArr); + case 'BreakStatement': + return this.astBreakStatement(ast, retArr); + case 'ContinueStatement': + return this.astContinueStatement(ast, retArr); + case 'ForStatement': + return this.astForStatement(ast, retArr); + case 'WhileStatement': + return this.astWhileStatement(ast, retArr); + case 'DoWhileStatement': + return this.astDoWhileStatement(ast, retArr); + case 'VariableDeclaration': + return this.astVariableDeclaration(ast, retArr); + case 'VariableDeclarator': + return this.astVariableDeclarator(ast, retArr); + case 'ThisExpression': + return this.astThisExpression(ast, retArr); + case 'SequenceExpression': + return this.astSequenceExpression(ast, retArr); + case 'UnaryExpression': + return this.astUnaryExpression(ast, retArr); + case 'UpdateExpression': + return this.astUpdateExpression(ast, retArr); + case 'LogicalExpression': + return this.astLogicalExpression(ast, retArr); + case 'MemberExpression': + return this.astMemberExpression(ast, retArr); + case 'CallExpression': + return this.astCallExpression(ast, retArr); + case 'ArrayExpression': + return this.astArrayExpression(ast, retArr); + case 'DebuggerStatement': + return this.astDebuggerStatement(ast, retArr); + case 'ConditionalExpression': + return this.astConditionalExpression(ast, retArr); + } + + throw this.astErrorOutput('Unknown ast type : ' + ast.type, ast); + } + } + /** + * @desc To throw the AST error, with its location. + * @param {string} error - the error message output + * @param {Object} ast - the AST object where the error is + */ + astErrorOutput(error, ast) { + if (typeof this.source !== 'string') { + return new Error(error); + } + + const debugString = getAstString(this.source, ast); + const leadingSource = this.source.substr(ast.start); + const splitLines = leadingSource.split(/\n/); + const lineBefore = splitLines.length > 0 ? splitLines[splitLines.length - 1] : 0; + return new Error(`${error} on line ${ splitLines.length }, position ${ lineBefore.length }:\n ${ debugString }`); + } + + astDebuggerStatement(arrNode, retArr) { + return retArr; + } + + astConditionalExpression(ast, retArr) { + if (ast.type !== 'ConditionalExpression') { + throw this.astErrorOutput('Not a conditional expression', ast); + } + retArr.push('('); + this.astGeneric(ast.test, retArr); + retArr.push('?'); + this.astGeneric(ast.consequent, retArr); + retArr.push(':'); + this.astGeneric(ast.alternate, retArr); + retArr.push(')'); + return retArr; + } + + /** + * @abstract + * @param {Object} ast + * @param {String[]} retArr + * @returns {String[]} + */ + astFunction(ast, retArr) { + throw new Error(`"astFunction" not defined on ${ this.constructor.name }`); + } + + /** + * @desc Parses the abstract syntax tree for to its *named function declaration* + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astFunctionDeclaration(ast, retArr) { + if (this.isChildFunction(ast)) { + return retArr; + } + return this.astFunction(ast, retArr); + } + astFunctionExpression(ast, retArr) { + if (this.isChildFunction(ast)) { + return retArr; + } + return this.astFunction(ast, retArr); + } + isChildFunction(ast) { + for (let i = 0; i < this.functions.length; i++) { + if (this.functions[i] === ast) { + return true; + } + } + return false; + } + astReturnStatement(ast, retArr) { + return retArr; + } + astLiteral(ast, retArr) { + this.literalTypes[`${ast.start},${ast.end}`] = 'Number'; + return retArr; + } + astBinaryExpression(ast, retArr) { + return retArr; + } + astIdentifierExpression(ast, retArr) { + return retArr; + } + astAssignmentExpression(ast, retArr) { + return retArr; + } + /** + * @desc Parses the abstract syntax tree for *generic expression* statement + * @param {Object} esNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astExpressionStatement(esNode, retArr) { + this.astGeneric(esNode.expression, retArr); + retArr.push(';'); + return retArr; + } + /** + * @desc Parses the abstract syntax tree for an *Empty* Statement + * @param {Object} eNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astEmptyStatement(eNode, retArr) { + return retArr; + } + astBlockStatement(ast, retArr) { + return retArr; + } + astIfStatement(ast, retArr) { + return retArr; + } + astSwitchStatement(ast, retArr) { + return retArr; + } + /** + * @desc Parses the abstract syntax tree for *Break* Statement + * @param {Object} brNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astBreakStatement(brNode, retArr) { + retArr.push('break;'); + return retArr; + } + /** + * @desc Parses the abstract syntax tree for *Continue* Statement + * @param {Object} crNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astContinueStatement(crNode, retArr) { + retArr.push('continue;\n'); + return retArr; + } + astForStatement(ast, retArr) { + return retArr; + } + astWhileStatement(ast, retArr) { + return retArr; + } + astDoWhileStatement(ast, retArr) { + return retArr; + } + /** + * @desc Parses the abstract syntax tree for *Variable Declaration* + * @param {Object} varDecNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astVariableDeclaration(varDecNode, retArr) { + const declarations = varDecNode.declarations; + if (!declarations || !declarations[0] || !declarations[0].init) { + throw this.astErrorOutput('Unexpected expression', varDecNode); + } + const result = []; + const firstDeclaration = declarations[0]; + const init = firstDeclaration.init; + let type = this.isState('in-for-loop-init') ? 'Integer' : this.getType(init); + if (type === 'LiteralInteger') { + // We had the choice to go either float or int, choosing float + type = 'Number'; + } + const markupType = typeMap[type]; + if (!markupType) { + throw this.astErrorOutput(`Markup type ${ markupType } not handled`, varDecNode); + } + let dependencies = this.getDependencies(firstDeclaration.init); + throw new Error('remove me'); + this.declarations[firstDeclaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: dependencies.every(dependency => dependency.isSafe) + }); + const initResult = [`${type} user_${firstDeclaration.id.name}=`]; + this.astGeneric(init, initResult); + result.push(initResult.join('')); + + // first declaration is done, now any added ones setup + for (let i = 1; i < declarations.length; i++) { + const declaration = declarations[i]; + dependencies = this.getDependencies(declaration); + throw new Error('Remove me'); + this.declarations[declaration.id.name] = Object.freeze({ + type, + dependencies, + isSafe: false + }); + this.astGeneric(declaration, result); + } + + retArr.push(retArr, result.join(',')); + retArr.push(';'); + return retArr; + } + /** + * @desc Parses the abstract syntax tree for *Variable Declarator* + * @param {Object} iVarDecNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astVariableDeclarator(iVarDecNode, retArr) { + this.astGeneric(iVarDecNode.id, retArr); + if (iVarDecNode.init !== null) { + retArr.push('='); + this.astGeneric(iVarDecNode.init, retArr); + } + return retArr; + } + astThisExpression(ast, retArr) { + return retArr; + } + astSequenceExpression(sNode, retArr) { + for (let i = 0; i < sNode.expressions.length; i++) { + if (i > 0) { + retArr.push(','); + } + this.astGeneric(sNode.expressions, retArr); + } + return retArr; + } + /** + * @desc Parses the abstract syntax tree for *Unary* Expression + * @param {Object} uNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astUnaryExpression(uNode, retArr) { + const unaryResult = this.checkAndUpconvertBitwiseUnary(uNode, retArr); + if (unaryResult) { + return retArr; + } + + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } + + return retArr; + } + + checkAndUpconvertBitwiseUnary(uNode, retArr) {} + + /** + * @desc Parses the abstract syntax tree for *Update* Expression + * @param {Object} uNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astUpdateExpression(uNode, retArr) { + if (uNode.prefix) { + retArr.push(uNode.operator); + this.astGeneric(uNode.argument, retArr); + } else { + this.astGeneric(uNode.argument, retArr); + retArr.push(uNode.operator); + } + + return retArr; + } + /** + * @desc Parses the abstract syntax tree for *Logical* Expression + * @param {Object} logNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astLogicalExpression(logNode, retArr) { + retArr.push('('); + this.astGeneric(logNode.left, retArr); + retArr.push(logNode.operator); + this.astGeneric(logNode.right, retArr); + retArr.push(')'); + return retArr; + } + astMemberExpression(ast, retArr) { + return retArr; + } + astCallExpression(ast, retArr) { + return retArr; + } + astArrayExpression(ast, retArr) { + return retArr; + } + + /** + * + * @param ast + * @return {IFunctionNodeMemberExpressionDetails} + */ + getMemberExpressionDetails(ast) { + if (ast.type !== 'MemberExpression') { + throw this.astErrorOutput(`Expression ${ ast.type } not a MemberExpression`, ast); + } + let name = null; + let type = null; + const variableSignature = this.getVariableSignature(ast); + switch (variableSignature) { + case 'value': + return null; + case 'value.thread.value': + case 'this.thread.value': + case 'this.output.value': + return { + signature: variableSignature, + type: 'Integer', + name: ast.property.name + }; + case 'value[]': + if (typeof ast.object.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.name; + return { + name, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object), + xProperty: ast.property + }; + case 'value[][]': + if (typeof ast.object.object.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.name; + return { + name, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object), + yProperty: ast.object.property, + xProperty: ast.property, + }; + case 'value[][][]': + if (typeof ast.object.object.object.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.object.name; + return { + name, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, + }; + case 'value[][][][]': + if (typeof ast.object.object.object.object.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.object.object.name; + return { + name, + origin: 'user', + signature: variableSignature, + type: this.getVariableType(ast.object.object.object.object), + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, + }; + case 'value.value': + if (typeof ast.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + if (this.isAstMathVariable(ast)) { + name = ast.property.name; + return { + name, + origin: 'Math', + type: 'Number', + signature: variableSignature, + }; + } + switch (ast.property.name) { + case 'r': + case 'g': + case 'b': + case 'a': + name = ast.object.name; + return { + name, + property: ast.property.name, + origin: 'user', + signature: variableSignature, + type: 'Number' + }; + default: + throw this.astErrorOutput('Unexpected expression', ast); + } + case 'this.constants.value': + if (typeof ast.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + }; + case 'this.constants.value[]': + if (typeof ast.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + xProperty: ast.property, + }; + case 'this.constants.value[][]': { + if (typeof ast.object.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + yProperty: ast.object.property, + xProperty: ast.property, + }; + } + case 'this.constants.value[][][]': { + if (typeof ast.object.object.object.property.name !== 'string') { + throw this.astErrorOutput('Unexpected expression', ast); + } + name = ast.object.object.object.property.name; + type = this.getConstantType(name); + if (!type) { + throw this.astErrorOutput('Constant has no type', ast); + } + return { + name, + type, + origin: 'constants', + signature: variableSignature, + zProperty: ast.object.object.property, + yProperty: ast.object.property, + xProperty: ast.property, + }; + } + case 'fn()[]': + case '[][]': + return { + signature: variableSignature, + property: ast.property, + }; + default: + throw this.astErrorOutput('Unexpected expression', ast); + } + } + + findIdentifierOrigin(astToFind) { + const stack = [this.ast]; + + while (stack.length > 0) { + const atNode = stack[0]; + if (atNode.type === 'VariableDeclarator' && atNode.id && atNode.id.name && atNode.id.name === astToFind.name) { + return atNode; + } + stack.shift(); + if (atNode.argument) { + stack.push(atNode.argument); + } else if (atNode.body) { + stack.push(atNode.body); + } else if (atNode.declarations) { + stack.push(atNode.declarations); + } else if (Array.isArray(atNode)) { + for (let i = 0; i < atNode.length; i++) { + stack.push(atNode[i]); + } + } + } + return null; + } + + findLastReturn(ast) { + const stack = [ast || this.ast]; + + while (stack.length > 0) { + const atNode = stack.pop(); + if (atNode.type === 'ReturnStatement') { + return atNode; + } + if (atNode.type === 'FunctionDeclaration') { + continue; + } + if (atNode.argument) { + stack.push(atNode.argument); + } else if (atNode.body) { + stack.push(atNode.body); + } else if (atNode.declarations) { + stack.push(atNode.declarations); + } else if (Array.isArray(atNode)) { + for (let i = 0; i < atNode.length; i++) { + stack.push(atNode[i]); + } + } else if (atNode.consequent) { + stack.push(atNode.consequent); + } else if (atNode.cases) { + stack.push(atNode.cases); + } + } + return null; + } + + getInternalVariableName(name) { + if (!this._internalVariableNames.hasOwnProperty(name)) { + this._internalVariableNames[name] = 0; + } + this._internalVariableNames[name]++; + if (this._internalVariableNames[name] === 1) { + return name; + } + return name + this._internalVariableNames[name]; + } + + varWarn() { + console.warn('var declarations are deprecated, weird things happen when falling back to CPU because var scope differs in javascript than in most languages. Use const or let'); + } +} + +const typeLookupMap = { + 'Number': 'Number', + 'Float': 'Float', + 'Integer': 'Integer', + 'Array': 'Number', + 'Array(2)': 'Number', + 'Array(3)': 'Number', + 'Array(4)': 'Number', + 'Array2D': 'Number', + 'Array3D': 'Number', + 'Input': 'Number', + 'HTMLImage': 'Array(4)', + 'HTMLVideo': 'Array(4)', + 'HTMLImageArray': 'Array(4)', + 'NumberTexture': 'Number', + 'MemoryOptimizedNumberTexture': 'Number', + 'Array1D(2)': 'Array(2)', + 'Array1D(3)': 'Array(3)', + 'Array1D(4)': 'Array(4)', + 'Array2D(2)': 'Array(2)', + 'Array2D(3)': 'Array(3)', + 'Array2D(4)': 'Array(4)', + 'Array3D(2)': 'Array(2)', + 'Array3D(3)': 'Array(3)', + 'Array3D(4)': 'Array(4)', + 'ArrayTexture(1)': 'Number', + 'ArrayTexture(2)': 'Array(2)', + 'ArrayTexture(3)': 'Array(3)', + 'ArrayTexture(4)': 'Array(4)', +}; diff --git a/src/backend/function-tracer.js b/src/backend/function-tracer.js index a464a796..38a59358 100644 --- a/src/backend/function-tracer.js +++ b/src/backend/function-tracer.js @@ -1,167 +1,163 @@ -class FunctionTracer { - constructor(ast) { - this.runningContexts = []; - this.contexts = []; - this.functionCalls = []; - this.declarations = []; - this.identifiers = []; - this.functions = []; - this.returnStatements = []; - this.inLoopInit = false; - this.scan(ast); - } - - get currentContext() { - return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; - } - - newContext(run) { - const newContext = Object.assign({}, this.currentContext); - this.contexts.push(newContext); - this.runningContexts.push(newContext); - run(); - this.runningContexts.pop(); - } - - /** - * Recursively scans AST for declarations and functions, and add them to their respective context - * @param ast - */ - scan(ast) { - if (!ast) return; - if (Array.isArray(ast)) { - for (let i = 0; i < ast.length; i++) { - this.scan(ast[i]); - } - return; - } - switch (ast.type) { - case 'Program': - this.scan(ast.body); - break; - case 'BlockStatement': - this.newContext(() => { - this.scan(ast.body); - }); - break; - case 'AssignmentExpression': - case 'LogicalExpression': - this.scan(ast.left); - this.scan(ast.right); - break; - case 'BinaryExpression': - this.scan(ast.left); - this.scan(ast.right); - break; - case 'UpdateExpression': - case 'UnaryExpression': - this.scan(ast.argument); - break; - case 'VariableDeclaration': - this.scan(ast.declarations); - break; - case 'VariableDeclarator': - const { currentContext } = this; - const declaration = { - ast: ast, - context: currentContext, - name: ast.id.name, - origin: 'declaration', - forceInteger: this.inLoopInit, - assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name), - }; - currentContext[ast.id.name] = declaration; - this.declarations.push(declaration); - this.scan(ast.id); - this.scan(ast.init); - break; - case 'FunctionExpression': - case 'FunctionDeclaration': - if (this.runningContexts.length === 0) { - this.scan(ast.body); - } else { - this.functions.push(ast); - } - break; - case 'IfStatement': - this.scan(ast.test); - this.scan(ast.consequent); - if (ast.alternate) this.scan(ast.alternate); - break; - case 'ForStatement': - this.newContext(() => { - this.inLoopInit = true; - this.scan(ast.init); - this.inLoopInit = false; - this.scan(ast.test); - this.scan(ast.update); - this.newContext(() => { - this.scan(ast.body); - }); - }); - break; - case 'DoWhileStatement': - case 'WhileStatement': - this.newContext(() => { - this.scan(ast.body); - this.scan(ast.test); - }); - break; - case 'Identifier': - this.identifiers.push({ - context: this.currentContext, - ast, - }); - break; - case 'ReturnStatement': - this.returnStatements.push(ast); - this.scan(ast.argument); - break; - case 'MemberExpression': - this.scan(ast.object); - this.scan(ast.property); - break; - case 'ExpressionStatement': - this.scan(ast.expression); - break; - case 'CallExpression': - this.functionCalls.push({ - context: this.currentContext, - ast, - }); - this.scan(ast.arguments); - break; - case 'ArrayExpression': - this.scan(ast.elements); - break; - case 'ConditionalExpression': - this.scan(ast.test); - this.scan(ast.alternate); - this.scan(ast.consequent); - break; - case 'SwitchStatement': - this.scan(ast.discriminant); - this.scan(ast.cases); - break; - case 'SwitchCase': - this.scan(ast.test); - this.scan(ast.consequent); - break; - - case 'ThisExpression': - case 'Literal': - case 'DebuggerStatement': - case 'EmptyStatement': - case 'BreakStatement': - case 'ContinueStatement': - break; - - default: - throw new Error(`unhandled type "${ast.type}"`); - } - } -} - -module.exports = { - FunctionTracer, -}; \ No newline at end of file +export class FunctionTracer { + constructor(ast) { + this.runningContexts = []; + this.contexts = []; + this.functionCalls = []; + this.declarations = []; + this.identifiers = []; + this.functions = []; + this.returnStatements = []; + this.inLoopInit = false; + this.scan(ast); + } + + get currentContext() { + return this.runningContexts.length > 0 ? this.runningContexts[this.runningContexts.length - 1] : null; + } + + newContext(run) { + const newContext = Object.assign({}, this.currentContext); + this.contexts.push(newContext); + this.runningContexts.push(newContext); + run(); + this.runningContexts.pop(); + } + + /** + * Recursively scans AST for declarations and functions, and add them to their respective context + * @param ast + */ + scan(ast) { + if (Array.isArray(ast)) { + for (let i = 0; i < ast.length; i++) { + this.scan(ast[i]); + } + return; + } + switch (ast.type) { + case 'Program': + this.scan(ast.body); + break; + case 'BlockStatement': + this.newContext(() => { + this.scan(ast.body); + }); + break; + case 'AssignmentExpression': + case 'LogicalExpression': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'BinaryExpression': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'UpdateExpression': + case 'UnaryExpression': + this.scan(ast.argument); + break; + case 'VariableDeclaration': + this.scan(ast.declarations); + break; + case 'VariableDeclarator': + const { currentContext } = this; + const declaration = { + ast: ast, + context: currentContext, + name: ast.id.name, + origin: 'declaration', + forceInteger: this.inLoopInit, + assignable: !this.inLoopInit && !currentContext.hasOwnProperty(ast.id.name), + }; + currentContext[ast.id.name] = declaration; + this.declarations.push(declaration); + this.scan(ast.id); + this.scan(ast.init); + break; + case 'FunctionExpression': + case 'FunctionDeclaration': + if (this.runningContexts.length === 0) { + this.scan(ast.body); + } else { + this.functions.push(ast); + } + break; + case 'IfStatement': + this.scan(ast.test); + this.scan(ast.consequent); + if (ast.alternate) this.scan(ast.alternate); + break; + case 'ForStatement': + this.newContext(() => { + this.inLoopInit = true; + this.scan(ast.init); + this.inLoopInit = false; + this.scan(ast.test); + this.scan(ast.update); + this.newContext(() => { + this.scan(ast.body); + }); + }); + break; + case 'DoWhileStatement': + case 'WhileStatement': + this.newContext(() => { + this.scan(ast.body); + this.scan(ast.test); + }); + break; + case 'Identifier': + this.identifiers.push({ + context: this.currentContext, + ast, + }); + break; + case 'ReturnStatement': + this.returnStatements.push(ast); + this.scan(ast.argument); + break; + case 'MemberExpression': + this.scan(ast.object); + this.scan(ast.property); + break; + case 'ExpressionStatement': + this.scan(ast.expression); + break; + case 'CallExpression': + this.functionCalls.push({ + context: this.currentContext, + ast, + }); + this.scan(ast.arguments); + break; + case 'ArrayExpression': + this.scan(ast.elements); + break; + case 'ConditionalExpression': + this.scan(ast.test); + this.scan(ast.alternate); + this.scan(ast.consequent); + break; + case 'SwitchStatement': + this.scan(ast.discriminant); + this.scan(ast.cases); + break; + case 'SwitchCase': + this.scan(ast.test); + this.scan(ast.consequent); + break; + case 'ThisExpression': + this.scan(ast.left); + this.scan(ast.right); + break; + case 'Literal': + case 'DebuggerStatement': + case 'EmptyStatement': + case 'BreakStatement': + case 'ContinueStatement': + break; + default: + throw new Error(`unhandled type "${ast.type}"`); + } + } +} diff --git a/src/backend/gl/kernel-string.js b/src/backend/gl/kernel-string.js index db5b7a12..7f21dad6 100644 --- a/src/backend/gl/kernel-string.js +++ b/src/backend/gl/kernel-string.js @@ -1,341 +1,337 @@ -const { glWiretap } = require('gl-wiretap'); -const { utils } = require('../../utils'); - -function toStringWithoutUtils(fn) { - return fn.toString() - .replace('=>', '') - .replace(/^function /, '') - .replace(/utils[.]/g, '/*utils.*/'); -} - -/** - * - * @param {Kernel} Kernel - * @param {KernelVariable[]} args - * @param {Kernel} originKernel - * @param {string} [setupContextString] - * @param {string} [destroyContextString] - * @returns {string} - */ -function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { - args = args ? Array.from(args).map(arg => { - switch (typeof arg) { - case 'boolean': - return new Boolean(arg); - case 'number': - return new Number(arg); - default: - return arg; - } - }) : null; - const uploadedValues = []; - const postResult = []; - const context = glWiretap(originKernel.context, { - useTrackablePrimitives: true, - onReadPixels: (targetName) => { - if (kernel.subKernels) { - if (!subKernelsResultVariableSetup) { - postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`); - subKernelsResultVariableSetup = true; - } else { - const property = kernel.subKernels[subKernelsResultIndex++].property; - postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`); - } - if (subKernelsResultIndex === kernel.subKernels.length) { - postResult.push(' return result;'); - } - return; - } - if (targetName) { - postResult.push(` return ${getRenderString(targetName, kernel)};`); - } else { - postResult.push(` return null;`); - } - }, - onUnrecognizedArgumentLookup: (argument) => { - const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues); - if (argumentName) { - return argumentName; - } - const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues); - if (constantName) { - return constantName; - } - return null; - } - }); - let subKernelsResultVariableSetup = false; - let subKernelsResultIndex = 0; - const { - source, - canvas, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - kernelArguments, - kernelConstants, - } = originKernel; - const kernel = new Kernel(source, { - canvas, - context, - checkContext: false, - output, - pipeline, - graphical, - loopMaxIterations, - constants, - optimizeFloatMemory, - precision, - fixIntegerDivisionAccuracy, - functions, - nativeFunctions, - subKernels, - immutable, - argumentTypes, - constantTypes, - }); - let result = []; - context.setIndent(2); - kernel.build.apply(kernel, args); - result.push(context.toString()); - context.reset(); - - kernel.kernelArguments.forEach((kernelArgument, i) => { - switch (kernelArgument.type) { - // primitives - case 'Integer': - case 'Boolean': - case 'Number': - case 'Float': - // non-primitives - case 'Array': - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - case 'HTMLImage': - case 'HTMLVideo': - context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); - break; - case 'HTMLImageArray': - for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) { - const arg = args[i]; - context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]); - } - break; - case 'Input': - context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); - break; - case 'MemoryOptimizedNumberTexture': - case 'NumberTexture': - case 'Array1D(2)': - case 'Array1D(3)': - case 'Array1D(4)': - case 'Array2D(2)': - case 'Array2D(3)': - case 'Array2D(4)': - case 'Array3D(2)': - case 'Array3D(3)': - case 'Array3D(4)': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture); - break; - default: - throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`); - } - }); - result.push('/** start of injected functions **/'); - result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`); - result.push(`function ${toStringWithoutUtils(utils.isArray)}`); - if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) { - result.push( - ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};` - ); - } - result.push('/** end of injected functions **/'); - result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`); - context.setIndent(4); - kernel.run.apply(kernel, args); - if (kernel.renderKernels) { - kernel.renderKernels(); - } else if (kernel.renderOutput) { - kernel.renderOutput(); - } - result.push(' /** start setup uploads for kernel values **/'); - kernel.kernelArguments.forEach(kernelArgument => { - result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n ')); - }); - result.push(' /** end setup uploads for kernel values **/'); - result.push(context.toString()); - if (kernel.renderOutput === kernel.renderTexture) { - context.reset(); - const results = kernel.renderKernels(); - const textureName = context.getContextVariableName(kernel.outputTexture); - result.push(` return { - result: { - texture: ${ textureName }, - type: '${ results.result.type }', - toArray: ${ getToArrayString(results.result, textureName) } - },`); - const { subKernels, subKernelOutputTextures } = kernel; - for (let i = 0; i < subKernels.length; i++) { - const texture = subKernelOutputTextures[i]; - const subKernel = subKernels[i]; - const subKernelResult = results[subKernel.property]; - const subKernelTextureName = context.getContextVariableName(texture); - result.push(` - ${subKernel.property}: { - texture: ${ subKernelTextureName }, - type: '${ subKernelResult.type }', - toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } - },`); - } - result.push(` };`); - } - result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`); - result.push(postResult.join('\n')); - result.push(' };'); - if (kernel.graphical) { - result.push(getGetPixelsString(kernel)); - result.push(` innerKernel.getPixels = getPixels;`); - } - result.push(' return innerKernel;'); - - let constantsUpload = []; - kernelConstants.forEach((kernelConstant) => { - constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`); - }); - return `function kernel(settings) { - const { context, constants } = settings; - ${constantsUpload.join('')} - ${setupContextString ? setupContextString : ''} -${result.join('\n')} -}`; -} - -function getRenderString(targetName, kernel) { - const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`; - if (kernel.output[2]) { - return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`; - } - if (kernel.output[1]) { - return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`; - } - - return `renderOutput(${readBackValue}, ${kernel.output[0]})`; -} - -function getGetPixelsString(kernel) { - const getPixels = kernel.getPixels.toString(); - const useFunctionKeyword = !/^function/.test(getPixels); - return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, { - findDependency: (object, name) => { - if (object === 'utils') { - return `const ${name} = ${utils[name].toString()};`; - } - return null; - }, - thisLookup: (property) => { - if (property === 'context') { - return null; - } - if (kernel.hasOwnProperty(property)) { - return JSON.stringify(kernel[property]); - } - throw new Error(`unhandled thisLookup ${ property }`); - } - }); -} - -function getToArrayString(kernelResult, textureName) { - const toArray = kernelResult.toArray.toString(); - const useFunctionKeyword = !/^function/.test(toArray); - const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, { - findDependency: (object, name) => { - if (object === 'utils') { - return `const ${name} = ${utils[name].toString()};`; - } else if (object === 'this') { - return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; - } else { - throw new Error('unhandled fromObject'); - } - }, - thisLookup: (property) => { - if (property === 'texture') { - return textureName; - } - if (kernelResult.hasOwnProperty(property)) { - return JSON.stringify(kernelResult[property]); - } - throw new Error(`unhandled thisLookup ${ property }`); - } - }); - return `() => { - ${flattenedFunctions} - return toArray(); - }`; -} - -/** - * - * @param {KernelVariable} argument - * @param {KernelValue[]} kernelValues - * @param {KernelVariable[]} values - * @param context - * @param {KernelVariable[]} uploadedValues - * @return {string|null} - */ -function findKernelValue(argument, kernelValues, values, context, uploadedValues) { - if (argument === null) return null; - switch (typeof argument) { - case 'boolean': - case 'number': - return null; - } - if ( - typeof HTMLImageElement !== 'undefined' && - argument instanceof HTMLImageElement - ) { - for (let i = 0; i < kernelValues.length; i++) { - const kernelValue = kernelValues[i]; - if (kernelValue.type !== 'HTMLImageArray') continue; - if (kernelValue.uploadValue !== argument) continue; - // TODO: if we send two of the same image, the parser could get confused, and short circuit to the first, handle that here - const variableIndex = values[i].indexOf(argument); - if (variableIndex === -1) continue; - const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`; - context.insertVariable(variableName, argument); - return variableName; - } - return null; - } - - for (let i = 0; i < kernelValues.length; i++) { - const kernelValue = kernelValues[i]; - if (argument !== kernelValue.uploadValue) continue; - const variable = `uploadValue_${kernelValue.name}`; - context.insertVariable(variable, kernelValue); - return variable; - } - return null; -} - -module.exports = { - glKernelString -}; \ No newline at end of file +import { glWiretap } from 'gl-wiretap'; +import { utils } from '../../utils'; + +function toStringWithoutUtils(fn) { + return fn.toString() + .replace('=>', '') + .replace(/^function /, '') + .replace(/utils[.]/g, '/*utils.*/'); +} + +/** + * + * @param {Kernel} Kernel + * @param {KernelVariable[]} args + * @param {Kernel} originKernel + * @param {string} [setupContextString] + * @param {string} [destroyContextString] + * @returns {string} + */ +export function glKernelString(Kernel, args, originKernel, setupContextString, destroyContextString) { + args = args ? Array.from(args).map(arg => { + switch (typeof arg) { + case 'boolean': + return new Boolean(arg); + case 'number': + return new Number(arg); + default: + return arg; + } + }) : null; + const uploadedValues = []; + const postResult = []; + const context = glWiretap(originKernel.context, { + useTrackablePrimitives: true, + onReadPixels: (targetName) => { + if (kernel.subKernels) { + if (!subKernelsResultVariableSetup) { + postResult.push(` const result = { result: ${getRenderString(targetName, kernel)} };`); + subKernelsResultVariableSetup = true; + } else { + const property = kernel.subKernels[subKernelsResultIndex++].property; + postResult.push(` result${isNaN(property) ? '.' + property : `[${property}]`} = ${getRenderString(targetName, kernel)};`); + } + if (subKernelsResultIndex === kernel.subKernels.length) { + postResult.push(' return result;'); + } + return; + } + if (targetName) { + postResult.push(` return ${getRenderString(targetName, kernel)};`); + } else { + postResult.push(` return null;`); + } + }, + onUnrecognizedArgumentLookup: (argument) => { + const argumentName = findKernelValue(argument, kernel.kernelArguments, [], context, uploadedValues); + if (argumentName) { + return argumentName; + } + const constantName = findKernelValue(argument, kernel.kernelConstants, constants ? Object.keys(constants).map(key => constants[key]) : [], context, uploadedValues); + if (constantName) { + return constantName; + } + return null; + } + }); + let subKernelsResultVariableSetup = false; + let subKernelsResultIndex = 0; + const { + source, + canvas, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + kernelArguments, + kernelConstants, + } = originKernel; + const kernel = new Kernel(source, { + canvas, + context, + checkContext: false, + output, + pipeline, + graphical, + loopMaxIterations, + constants, + optimizeFloatMemory, + precision, + fixIntegerDivisionAccuracy, + functions, + nativeFunctions, + subKernels, + immutable, + argumentTypes, + constantTypes, + }); + let result = []; + context.setIndent(2); + kernel.build.apply(kernel, args); + result.push(context.toString()); + context.reset(); + + kernel.kernelArguments.forEach((kernelArgument, i) => { + switch (kernelArgument.type) { + // primitives + case 'Integer': + case 'Boolean': + case 'Number': + case 'Float': + // non-primitives + case 'Array': + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + case 'HTMLImage': + case 'HTMLVideo': + context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); + break; + case 'HTMLImageArray': + for (let imageIndex = 0; imageIndex < args[i].length; imageIndex++) { + const arg = args[i]; + context.insertVariable(`uploadValue_${kernelArgument.name}[${imageIndex}]`, arg[imageIndex]); + } + break; + case 'Input': + context.insertVariable(`uploadValue_${kernelArgument.name}`, kernelArgument.uploadValue); + break; + case 'MemoryOptimizedNumberTexture': + case 'NumberTexture': + case 'Array1D(2)': + case 'Array1D(3)': + case 'Array1D(4)': + case 'Array2D(2)': + case 'Array2D(3)': + case 'Array2D(4)': + case 'Array3D(2)': + case 'Array3D(3)': + case 'Array3D(4)': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + context.insertVariable(`uploadValue_${kernelArgument.name}`, args[i].texture); + break; + default: + throw new Error(`unhandled kernelArgumentType insertion for glWiretap of type ${kernelArgument.type}`); + } + }); + result.push('/** start of injected functions **/'); + result.push(`function ${toStringWithoutUtils(utils.flattenTo)}`); + result.push(`function ${toStringWithoutUtils(utils.flatten2dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils.flatten3dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils.flatten4dArrayTo)}`); + result.push(`function ${toStringWithoutUtils(utils.isArray)}`); + if (kernel.renderOutput !== kernel.renderTexture && kernel.formatValues) { + result.push( + ` const renderOutput = function ${toStringWithoutUtils(kernel.formatValues)};` + ); + } + result.push('/** end of injected functions **/'); + result.push(` const innerKernel = function (${kernel.kernelArguments.map(kernelArgument => kernelArgument.varName).join(', ')}) {`); + context.setIndent(4); + kernel.run.apply(kernel, args); + if (kernel.renderKernels) { + kernel.renderKernels(); + } else if (kernel.renderOutput) { + kernel.renderOutput(); + } + result.push(' /** start setup uploads for kernel values **/'); + kernel.kernelArguments.forEach(kernelArgument => { + result.push(' ' + kernelArgument.getStringValueHandler().split('\n').join('\n ')); + }); + result.push(' /** end setup uploads for kernel values **/'); + result.push(context.toString()); + if (kernel.renderOutput === kernel.renderTexture) { + context.reset(); + const results = kernel.renderKernels(); + const textureName = context.getContextVariableName(kernel.outputTexture); + result.push(` return { + result: { + texture: ${ textureName }, + type: '${ results.result.type }', + toArray: ${ getToArrayString(results.result, textureName) } + },`); + const { subKernels, subKernelOutputTextures } = kernel; + for (let i = 0; i < subKernels.length; i++) { + const texture = subKernelOutputTextures[i]; + const subKernel = subKernels[i]; + const subKernelResult = results[subKernel.property]; + const subKernelTextureName = context.getContextVariableName(texture); + result.push(` + ${subKernel.property}: { + texture: ${ subKernelTextureName }, + type: '${ subKernelResult.type }', + toArray: ${ getToArrayString(subKernelResult, subKernelTextureName) } + },`); + } + result.push(` };`); + } + result.push(` ${destroyContextString ? '\n' + destroyContextString + ' ': ''}`); + result.push(postResult.join('\n')); + result.push(' };'); + if (kernel.graphical) { + result.push(getGetPixelsString(kernel)); + result.push(` innerKernel.getPixels = getPixels;`); + } + result.push(' return innerKernel;'); + + let constantsUpload = []; + kernelConstants.forEach((kernelConstant) => { + constantsUpload.push(`${ kernelConstant.getStringValueHandler()}`); + }); + return `function kernel(settings) { + const { context, constants } = settings; + ${constantsUpload.join('')} + ${setupContextString ? setupContextString : ''} +${result.join('\n')} +}`; +} + +function getRenderString(targetName, kernel) { + const readBackValue = kernel.precision === 'single' ? targetName : `new Float32Array(${targetName}.buffer)`; + if (kernel.output[2]) { + return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]}, ${kernel.output[2]})`; + } + if (kernel.output[1]) { + return `renderOutput(${readBackValue}, ${kernel.output[0]}, ${kernel.output[1]})`; + } + + return `renderOutput(${readBackValue}, ${kernel.output[0]})`; +} + +function getGetPixelsString(kernel) { + const getPixels = kernel.getPixels.toString(); + const useFunctionKeyword = !/^function/.test(getPixels); + return utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ getPixels }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils[name].toString()};`; + } + return null; + }, + thisLookup: (property) => { + if (property === 'context') { + return null; + } + if (kernel.hasOwnProperty(property)) { + return JSON.stringify(kernel[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } + }); +} + +function getToArrayString(kernelResult, textureName) { + const toArray = kernelResult.toArray.toString(); + const useFunctionKeyword = !/^function/.test(toArray); + const flattenedFunctions = utils.flattenFunctionToString(`${useFunctionKeyword ? 'function ' : ''}${ toArray }`, { + findDependency: (object, name) => { + if (object === 'utils') { + return `const ${name} = ${utils[name].toString()};`; + } else if (object === 'this') { + return `${useFunctionKeyword ? 'function ' : ''}${kernelResult[name].toString()}`; + } else { + throw new Error('unhandled fromObject'); + } + }, + thisLookup: (property) => { + if (property === 'texture') { + return textureName; + } + if (kernelResult.hasOwnProperty(property)) { + return JSON.stringify(kernelResult[property]); + } + throw new Error(`unhandled thisLookup ${ property }`); + } + }); + return `() => { + ${flattenedFunctions} + return toArray(); + }`; +} + +/** + * + * @param {KernelVariable} argument + * @param {KernelValue[]} kernelValues + * @param {KernelVariable[]} values + * @param context + * @param {KernelVariable[]} uploadedValues + * @return {string|null} + */ +function findKernelValue(argument, kernelValues, values, context, uploadedValues) { + if (argument === null) return null; + switch (typeof argument) { + case 'boolean': + case 'number': + return null; + } + if ( + typeof HTMLImageElement !== 'undefined' && + argument instanceof HTMLImageElement + ) { + for (let i = 0; i < kernelValues.length; i++) { + const kernelValue = kernelValues[i]; + if (kernelValue.type !== 'HTMLImageArray') continue; + if (kernelValue.uploadValue !== argument) continue; + // TODO: if we send two of the same image, the parser could get confused, and short circuit to the first, handle that here + const variableIndex = values[i].indexOf(argument); + if (variableIndex === -1) continue; + const variableName = `uploadValue_${kernelValue.name}[${variableIndex}]`; + context.insertVariable(variableName, argument); + return variableName; + } + return null; + } + + for (let i = 0; i < kernelValues.length; i++) { + const kernelValue = kernelValues[i]; + if (argument !== kernelValue.uploadValue) continue; + const variable = `uploadValue_${kernelValue.name}`; + context.insertVariable(variable, kernelValue); + return variable; + } + return null; +} diff --git a/src/backend/gl/kernel.js b/src/backend/gl/kernel.js index 9f40045a..02081258 100644 --- a/src/backend/gl/kernel.js +++ b/src/backend/gl/kernel.js @@ -1,1001 +1,995 @@ -const { Kernel } = require('../kernel'); -const { Texture } = require('../../texture'); -const { utils } = require('../../utils'); -const { GLTextureArray2Float } = require('./texture/array-2-float'); -const { GLTextureArray2Float2D } = require('./texture/array-2-float-2d'); -const { GLTextureArray2Float3D } = require('./texture/array-2-float-3d'); -const { GLTextureArray3Float } = require('./texture/array-3-float'); -const { GLTextureArray3Float2D } = require('./texture/array-3-float-2d'); -const { GLTextureArray3Float3D } = require('./texture/array-3-float-3d'); -const { GLTextureArray4Float } = require('./texture/array-4-float'); -const { GLTextureArray4Float2D } = require('./texture/array-4-float-2d'); -const { GLTextureArray4Float3D } = require('./texture/array-4-float-3d'); -const { GLTextureFloat } = require('./texture/float'); -const { GLTextureFloat2D } = require('./texture/float-2d'); -const { GLTextureFloat3D } = require('./texture/float-3d'); -const { GLTextureMemoryOptimized } = require('./texture/memory-optimized'); -const { GLTextureMemoryOptimized2D } = require('./texture/memory-optimized-2d'); -const { GLTextureMemoryOptimized3D } = require('./texture/memory-optimized-3d'); -const { GLTextureUnsigned } = require('./texture/unsigned'); -const { GLTextureUnsigned2D } = require('./texture/unsigned-2d'); -const { GLTextureUnsigned3D } = require('./texture/unsigned-3d'); -const { GLTextureGraphical } = require('./texture/graphical'); - -/** - * @abstract - * @extends Kernel - */ -class GLKernel extends Kernel { - static get mode() { - return 'gpu'; - } - - static getIsFloatRead() { - const kernelString = `function kernelFunction() { - return 1; - }`; - const kernel = new this(kernelString, { - context: this.testContext, - canvas: this.testCanvas, - validate: false, - output: [1], - precision: 'single', - returnType: 'Number', - tactic: 'speed', - }); - kernel.build(); - kernel.run(); - const result = kernel.renderOutput(); - kernel.destroy(true); - return result[0] === 1; - } - - static getIsIntegerDivisionAccurate() { - function kernelFunction(v1, v2) { - return v1[this.thread.x] / v2[this.thread.x]; - } - const kernel = new this(kernelFunction.toString(), { - context: this.testContext, - canvas: this.testCanvas, - validate: false, - output: [2], - returnType: 'Number', - precision: 'unsigned', - tactic: 'speed', - }); - const args = [ - [6, 6030401], - [3, 3991] - ]; - kernel.build.apply(kernel, args); - kernel.run.apply(kernel, args); - const result = kernel.renderOutput(); - kernel.destroy(true); - // have we not got whole numbers for 6/3 or 6030401/3991 - // add more here if others see this problem - return result[0] === 2 && result[1] === 1511; - } - - /** - * @abstract - */ - static get testCanvas() { - throw new Error(`"testCanvas" not defined on ${ this.name }`); - } - - /** - * @abstract - */ - static get testContext() { - throw new Error(`"testContext" not defined on ${ this.name }`); - } - - /** - * @type {IKernelFeatures} - */ - static get features() { - throw new Error(`"features" not defined on ${ this.name }`); - } - - /** - * @abstract - */ - static setupFeatureChecks() { - throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); - } - - /** - * @desc Fix division by factor of 3 FP accuracy bug - * @param {Boolean} fix - should fix - */ - setFixIntegerDivisionAccuracy(fix) { - this.fixIntegerDivisionAccuracy = fix; - return this; - } - - /** - * @desc Toggle output mode - * @param {String} flag - 'single' or 'unsigned' - */ - setPrecision(flag) { - this.precision = flag; - return this; - } - - /** - * @desc Toggle texture output mode - * @param {Boolean} flag - true to enable floatTextures - * @deprecated - */ - setFloatTextures(flag) { - utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory'); - this.floatTextures = flag; - return this; - } - - /** - * A highly readable very forgiving micro-parser for a glsl function that gets argument types - * @param {String} source - * @returns {{argumentTypes: String[], argumentNames: String[]}} - */ - static nativeFunctionArguments(source) { - const argumentTypes = []; - const argumentNames = []; - const states = []; - const isStartingVariableName = /^[a-zA-Z_]/; - const isVariableChar = /[a-zA-Z_0-9]/; - let i = 0; - let argumentName = null; - let argumentType = null; - while (i < source.length) { - const char = source[i]; - const nextChar = source[i + 1]; - const state = states.length > 0 ? states[states.length - 1] : null; - - // begin MULTI_LINE_COMMENT handling - if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') { - states.push('MULTI_LINE_COMMENT'); - i += 2; - continue; - } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') { - states.pop(); - i += 2; - continue; - } - // end MULTI_LINE_COMMENT handling - - // begin COMMENT handling - else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') { - states.push('COMMENT'); - i += 2; - continue; - } else if (state === 'COMMENT' && char === '\n') { - states.pop(); - i++; - continue; - } - // end COMMENT handling - - // being FUNCTION_ARGUMENTS handling - else if (state === null && char === '(') { - states.push('FUNCTION_ARGUMENTS'); - i++; - continue; - } else if (state === 'FUNCTION_ARGUMENTS') { - if (char === ')') { - states.pop(); - break; - } - if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'float'; - argumentName = ''; - i += 6; - continue; - } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'int'; - argumentName = ''; - i += 4; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec2'; - argumentName = ''; - i += 5; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec3'; - argumentName = ''; - i += 5; - continue; - } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') { - states.push('DECLARE_VARIABLE'); - argumentType = 'vec4'; - argumentName = ''; - i += 5; - continue; - } - } - // end FUNCTION_ARGUMENTS handling - - // begin DECLARE_VARIABLE handling - else if (state === 'DECLARE_VARIABLE') { - if (argumentName === '') { - if (char === ' ') { - i++; - continue; - } - if (!isStartingVariableName.test(char)) { - throw new Error('variable name is not expected string'); - } - } - argumentName += char; - if (!isVariableChar.test(nextChar)) { - states.pop(); - argumentNames.push(argumentName); - argumentTypes.push(typeMap[argumentType]); - } - } - // end DECLARE_VARIABLE handling - - // Progress to next character - i++; - } - if (states.length > 0) { - throw new Error('GLSL function was not parsable'); - } - return { - argumentNames, - argumentTypes, - }; - } - - static nativeFunctionReturnType(source) { - return typeMap[source.match(/int|float|vec[2-4]/)[0]]; - } - - static combineKernels(combinedKernel, lastKernel) { - combinedKernel.apply(null, arguments); - const { - texSize, - context, - threadDim - } = lastKernel.texSize; - let result; - if (lastKernel.precision === 'single') { - const w = texSize[0]; - const h = Math.ceil(texSize[1] / 4); - result = new Float32Array(w * h * 4 * 4); - context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result); - } else { - const bytes = new Uint8Array(texSize[0] * texSize[1] * 4); - context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes); - result = new Float32Array(bytes.buffer); - } - - result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]); - - if (lastKernel.output.length === 1) { - return result; - } else if (lastKernel.output.length === 2) { - return utils.splitArray(result, lastKernel.output[0]); - } else if (lastKernel.output.length === 3) { - const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); - return cube.map(function(x) { - return utils.splitArray(x, lastKernel.output[0]); - }); - } - } - - constructor(source, settings) { - super(source, settings); - this.transferValues = null; - this.formatValues = null; - this.TextureConstructor = null; - this.renderOutput = null; - this.renderRawOutput = null; - this.texSize = null; - this.translatedSource = null; - this.renderStrategy = null; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - } - - checkTextureSize() { - const { features } = this.constructor; - if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) { - throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`); - } - } - - translateSource() { - throw new Error(`"translateSource" not defined on ${this.constructor.name}`); - } - - /** - * Picks a render strategy for the now finally parsed kernel - * @param args - * @return {null|KernelOutput} - */ - pickRenderStrategy(args) { - if (this.graphical) { - this.renderRawOutput = this.readPackedPixelsToUint8Array; - this.transferValues = (pixels) => pixels; - this.TextureConstructor = GLTextureGraphical; - return null; - } - if (this.precision === 'unsigned') { - this.renderRawOutput = this.readPackedPixelsToUint8Array; - this.transferValues = this.readPackedPixelsToFloat32Array; - if (this.pipeline) { - this.renderOutput = this.renderTexture; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToTextures; - } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureUnsigned3D; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - return null; - } - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return this.requestFallback(args); - } - } else { - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToArrays; - } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - this.renderOutput = this.renderValues; - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureUnsigned3D; - this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; - this.formatValues = utils.erect3DPackedFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureUnsigned2D; - this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; - this.formatValues = utils.erect2DPackedFloat; - return null; - } else { - this.TextureConstructor = GLTextureUnsigned; - this.renderStrategy = renderStrategy.PackedPixelToFloat; - this.formatValues = utils.erectPackedFloat; - return null; - } - - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - return this.requestFallback(args); - } - } - } else if (this.precision === 'single') { - this.renderRawOutput = this.readFloatPixelsToFloat32Array; - this.transferValues = this.readFloatPixelsToFloat32Array; - if (this.pipeline) { - this.renderStrategy = renderStrategy.FloatTexture; - this.renderOutput = this.renderTexture; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToTextures; - } - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.optimizeFloatMemory) { - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - return null; - } - } else { - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureFloat3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - return null; - } - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - return null; - } - } - } - this.renderOutput = this.renderValues; - if (this.subKernels !== null) { - this.renderKernels = this.renderKernelsToArrays; - } - if (this.optimizeFloatMemory) { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized3D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; - this.formatValues = utils.erectMemoryOptimized3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureMemoryOptimized2D; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; - this.formatValues = utils.erectMemoryOptimized2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureMemoryOptimized; - this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; - this.formatValues = utils.erectMemoryOptimizedFloat; - return null; - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } - } - } else { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureFloat3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; - this.formatValues = utils.erect3DFloat; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureFloat2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; - this.formatValues = utils.erect2DFloat; - return null; - } else { - this.TextureConstructor = GLTextureFloat; - this.renderStrategy = renderStrategy.FloatPixelToFloat; - this.formatValues = utils.erectFloat; - return null; - } - break; - case 'Array(2)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray2Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; - this.formatValues = utils.erect3DArray2; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray2Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; - this.formatValues = utils.erect2DArray2; - return null; - } else { - this.TextureConstructor = GLTextureArray2Float; - this.renderStrategy = renderStrategy.FloatPixelToArray2; - this.formatValues = utils.erectArray2; - return null; - } - break; - case 'Array(3)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray3Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; - this.formatValues = utils.erect3DArray3; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray3Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; - this.formatValues = utils.erect2DArray3; - return null; - } else { - this.TextureConstructor = GLTextureArray3Float; - this.renderStrategy = renderStrategy.FloatPixelToArray3; - this.formatValues = utils.erectArray3; - return null; - } - break; - case 'Array(4)': - if (this.output[2] > 0) { - this.TextureConstructor = GLTextureArray4Float3D; - this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; - this.formatValues = utils.erect3DArray4; - return null; - } else if (this.output[1] > 0) { - this.TextureConstructor = GLTextureArray4Float2D; - this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; - this.formatValues = utils.erect2DArray4; - return null; - } else { - this.TextureConstructor = GLTextureArray4Float; - this.renderStrategy = renderStrategy.FloatPixelToArray4; - this.formatValues = utils.erectArray4; - return null; - } - } - } - } else { - throw new Error(`unhandled precision of "${this.precision}"`); - } - - throw new Error(`unhandled return type "${this.returnType}"`); - } - - /** - * @abstract - * @returns String - */ - getKernelString() { - throw new Error(`abstract method call`); - } - - getMainResultTexture() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Float': - case 'Integer': - case 'Number': - return this.getMainResultNumberTexture(); - case 'Array(2)': - return this.getMainResultArray2Texture(); - case 'Array(3)': - return this.getMainResultArray3Texture(); - case 'Array(4)': - return this.getMainResultArray4Texture(); - default: - throw new Error(`unhandled returnType type ${ this.returnType }`); - } - } - - /** - * @abstract - * @returns String[] - */ - getMainResultKernelNumberTexture() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultSubKernelNumberTexture() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultKernelArray2Texture() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultSubKernelArray2Texture() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultKernelArray3Texture() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultSubKernelArray3Texture() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultKernelArray4Texture() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultSubKernelArray4Texture() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultGraphical() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultMemoryOptimizedFloats() { - throw new Error(`abstract method call`); - } - /** - * @abstract - * @returns String[] - */ - getMainResultPackedPixels() { - throw new Error(`abstract method call`); - } - - getMainResultString() { - if (this.graphical) { - return this.getMainResultGraphical(); - } else if (this.precision === 'single') { - if (this.optimizeFloatMemory) { - return this.getMainResultMemoryOptimizedFloats(); - } - return this.getMainResultTexture(); - } else { - return this.getMainResultPackedPixels(); - } - } - - getMainResultNumberTexture() { - return utils.linesToString(this.getMainResultKernelNumberTexture()) + - utils.linesToString(this.getMainResultSubKernelNumberTexture()); - } - - getMainResultArray2Texture() { - return utils.linesToString(this.getMainResultKernelArray2Texture()) + - utils.linesToString(this.getMainResultSubKernelArray2Texture()); - } - - getMainResultArray3Texture() { - return utils.linesToString(this.getMainResultKernelArray3Texture()) + - utils.linesToString(this.getMainResultSubKernelArray3Texture()); - } - - getMainResultArray4Texture() { - return utils.linesToString(this.getMainResultKernelArray4Texture()) + - utils.linesToString(this.getMainResultSubKernelArray4Texture()); - } - - /** - * - * @return {string} - */ - getFloatTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp float;\n'; - case 'performance': - return 'precision highp float;\n'; - case 'balanced': - default: - return 'precision mediump float;\n'; - } - } - - /** - * - * @return {string} - */ - getIntTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp int;\n'; - case 'performance': - return 'precision highp int;\n'; - case 'balanced': - default: - return 'precision mediump int;\n'; - } - } - - /** - * - * @return {string} - */ - getSampler2DTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2D;\n'; - case 'performance': - return 'precision highp sampler2D;\n'; - case 'balanced': - default: - return 'precision mediump sampler2D;\n'; - } - } - - getSampler2DArrayTacticDeclaration() { - switch (this.tactic) { - case 'speed': - return 'precision lowp sampler2DArray;\n'; - case 'performance': - return 'precision highp sampler2DArray;\n'; - case 'balanced': - default: - return 'precision mediump sampler2DArray;\n'; - } - } - - renderTexture() { - return new this.TextureConstructor({ - texture: this.outputTexture, - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - readPackedPixelsToUint8Array() { - if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"'); - const { - texSize, - context: gl - } = this; - const result = new Uint8Array(texSize[0] * texSize[1] * 4); - gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result); - return result; - } - - readPackedPixelsToFloat32Array() { - return new Float32Array(this.readPackedPixelsToUint8Array().buffer); - } - - readFloatPixelsToFloat32Array() { - if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); - const { - texSize, - context: gl - } = this; - const w = texSize[0]; - const h = texSize[1]; - const result = new Float32Array(w * h * 4); - gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); - return result; - } - - readMemoryOptimizedFloatPixelsToFloat32Array() { - if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); - const { - texSize, - context: gl - } = this; - const w = texSize[0]; - const h = texSize[1]; - const result = new Float32Array(w * h * 4); - gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); - return result; - } - - /** - * - * @param {Boolean} [flip] - * @return {Uint8Array} - */ - getPixels(flip) { - const { - context: gl, - output - } = this; - const [width, height] = output; - const pixels = new Uint8Array(width * height * 4); - gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - // flipped by default, so invert - return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer); - } - - renderKernelsToArrays() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }).toArray(); - } - return result; - } - - renderKernelsToTextures() { - const result = { - result: this.renderOutput(), - }; - for (let i = 0; i < this.subKernels.length; i++) { - result[this.subKernels[i].property] = new this.TextureConstructor({ - texture: this.subKernelOutputTextures[i], - size: this.texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - return result; - } - - setOutput(output) { - super.setOutput(output); - if (this.program) { - this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - const { context: gl } = this; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - this.updateMaxTexSize(); - this.framebuffer.width = this.texSize[0]; - this.framebuffer.height = this.texSize[1]; - this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - this.canvas.width = this.maxTexSize[0]; - this.canvas.height = this.maxTexSize[1]; - this._setupOutputTexture(); - if (this.subKernels && this.subKernels.length > 0) { - this._setupSubOutputTextures(); - } - } - return this; - } - renderValues() { - return this.formatValues( - this.transferValues(), - this.output[0], - this.output[1], - this.output[2] - ); - } -} - -const renderStrategy = Object.freeze({ - PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), - PackedPixelToFloat: Symbol('PackedPixelToFloat'), - PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), - PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), - PackedTexture: Symbol('PackedTexture'), - FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), - FloatPixelToFloat: Symbol('FloatPixelToFloat'), - FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), - FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), - FloatPixelToArray2: Symbol('FloatPixelToArray2'), - FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), - FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), - FloatPixelToArray3: Symbol('FloatPixelToArray3'), - FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), - FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), - FloatPixelToArray4: Symbol('FloatPixelToArray4'), - FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), - FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), - FloatTexture: Symbol('FloatTexture'), - MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), - MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), -}); - -const typeMap = { - int: 'Integer', - float: 'Number', - vec2: 'Array(2)', - vec3: 'Array(3)', - vec4: 'Array(4)', -}; - -module.exports = { - GLKernel, - renderStrategy -}; \ No newline at end of file +import { Kernel } from '../kernel'; +import { utils } from '../../utils'; +import { GLTextureArray2Float } from './texture/array-2-float'; +import { GLTextureArray2Float2D } from './texture/array-2-float-2d'; +import { GLTextureArray2Float3D } from './texture/array-2-float-3d'; +import { GLTextureArray3Float } from './texture/array-3-float'; +import { GLTextureArray3Float2D } from './texture/array-3-float-2d'; +import { GLTextureArray3Float3D } from './texture/array-3-float-3d'; +import { GLTextureArray4Float } from './texture/array-4-float'; +import { GLTextureArray4Float2D } from './texture/array-4-float-2d'; +import { GLTextureArray4Float3D } from './texture/array-4-float-3d'; +import { GLTextureFloat } from './texture/float'; +import { GLTextureFloat2D } from './texture/float-2d'; +import { GLTextureFloat3D } from './texture/float-3d'; +import { GLTextureMemoryOptimized } from './texture/memory-optimized'; +import { GLTextureMemoryOptimized2D } from './texture/memory-optimized-2d'; +import { GLTextureMemoryOptimized3D } from './texture/memory-optimized-3d'; +import { GLTextureUnsigned } from './texture/unsigned'; +import { GLTextureUnsigned2D } from './texture/unsigned-2d'; +import { GLTextureUnsigned3D } from './texture/unsigned-3d'; +import { GLTextureGraphical } from './texture/graphical'; + +/** + * @abstract + * @extends Kernel + */ +export class GLKernel extends Kernel { + static get mode() { + return 'gpu'; + } + + static getIsFloatRead() { + const kernelString = `function kernelFunction() { + return 1; + }`; + const kernel = new this(kernelString, { + context: this.testContext, + canvas: this.testCanvas, + validate: false, + output: [1], + precision: 'single', + returnType: 'Number', + tactic: 'speed', + }); + kernel.build(); + kernel.run(); + const result = kernel.renderOutput(); + kernel.destroy(true); + return result[0] === 1; + } + + static getIsIntegerDivisionAccurate() { + function kernelFunction(v1, v2) { + return v1[this.thread.x] / v2[this.thread.x]; + } + const kernel = new this(kernelFunction.toString(), { + context: this.testContext, + canvas: this.testCanvas, + validate: false, + output: [2], + returnType: 'Number', + precision: 'unsigned', + tactic: 'speed', + }); + const args = [ + [6, 6030401], + [3, 3991] + ]; + kernel.build.apply(kernel, args); + kernel.run.apply(kernel, args); + const result = kernel.renderOutput(); + kernel.destroy(true); + // have we not got whole numbers for 6/3 or 6030401/3991 + // add more here if others see this problem + return result[0] === 2 && result[1] === 1511; + } + + /** + * @abstract + */ + static get testCanvas() { + throw new Error(`"testCanvas" not defined on ${ this.name }`); + } + + /** + * @abstract + */ + static get testContext() { + throw new Error(`"testContext" not defined on ${ this.name }`); + } + + /** + * @type {IKernelFeatures} + */ + static get features() { + throw new Error(`"features" not defined on ${ this.name }`); + } + + /** + * @abstract + */ + static setupFeatureChecks() { + throw new Error(`"setupFeatureChecks" not defined on ${ this.name }`); + } + + /** + * @desc Fix division by factor of 3 FP accuracy bug + * @param {Boolean} fix - should fix + */ + setFixIntegerDivisionAccuracy(fix) { + this.fixIntegerDivisionAccuracy = fix; + return this; + } + + /** + * @desc Toggle output mode + * @param {String} flag - 'single' or 'unsigned' + */ + setPrecision(flag) { + this.precision = flag; + return this; + } + + /** + * @desc Toggle texture output mode + * @param {Boolean} flag - true to enable floatTextures + * @deprecated + */ + setFloatTextures(flag) { + utils.warnDeprecated('method', 'setFloatTextures', 'setOptimizeFloatMemory'); + this.floatTextures = flag; + return this; + } + + /** + * A highly readable very forgiving micro-parser for a glsl function that gets argument types + * @param {String} source + * @returns {{argumentTypes: String[], argumentNames: String[]}} + */ + static nativeFunctionArguments(source) { + const argumentTypes = []; + const argumentNames = []; + const states = []; + const isStartingVariableName = /^[a-zA-Z_]/; + const isVariableChar = /[a-zA-Z_0-9]/; + let i = 0; + let argumentName = null; + let argumentType = null; + while (i < source.length) { + const char = source[i]; + const nextChar = source[i + 1]; + const state = states.length > 0 ? states[states.length - 1] : null; + + // begin MULTI_LINE_COMMENT handling + if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '*') { + states.push('MULTI_LINE_COMMENT'); + i += 2; + continue; + } else if (state === 'MULTI_LINE_COMMENT' && char === '*' && nextChar === '/') { + states.pop(); + i += 2; + continue; + } + // end MULTI_LINE_COMMENT handling + + // begin COMMENT handling + else if (state === 'FUNCTION_ARGUMENTS' && char === '/' && nextChar === '/') { + states.push('COMMENT'); + i += 2; + continue; + } else if (state === 'COMMENT' && char === '\n') { + states.pop(); + i++; + continue; + } + // end COMMENT handling + + // being FUNCTION_ARGUMENTS handling + else if (state === null && char === '(') { + states.push('FUNCTION_ARGUMENTS'); + i++; + continue; + } else if (state === 'FUNCTION_ARGUMENTS') { + if (char === ')') { + states.pop(); + break; + } + if (char === 'f' && nextChar === 'l' && source[i + 2] === 'o' && source[i + 3] === 'a' && source[i + 4] === 't' && source[i + 5] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'float'; + argumentName = ''; + i += 6; + continue; + } else if (char === 'i' && nextChar === 'n' && source[i + 2] === 't' && source[i + 3] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'int'; + argumentName = ''; + i += 4; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '2' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec2'; + argumentName = ''; + i += 5; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '3' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec3'; + argumentName = ''; + i += 5; + continue; + } else if (char === 'v' && nextChar === 'e' && source[i + 2] === 'c' && source[i + 3] === '4' && source[i + 4] === ' ') { + states.push('DECLARE_VARIABLE'); + argumentType = 'vec4'; + argumentName = ''; + i += 5; + continue; + } + } + // end FUNCTION_ARGUMENTS handling + + // begin DECLARE_VARIABLE handling + else if (state === 'DECLARE_VARIABLE') { + if (argumentName === '') { + if (char === ' ') { + i++; + continue; + } + if (!isStartingVariableName.test(char)) { + throw new Error('variable name is not expected string'); + } + } + argumentName += char; + if (!isVariableChar.test(nextChar)) { + states.pop(); + argumentNames.push(argumentName); + argumentTypes.push(typeMap[argumentType]); + } + } + // end DECLARE_VARIABLE handling + + // Progress to next character + i++; + } + if (states.length > 0) { + throw new Error('GLSL function was not parsable'); + } + return { + argumentNames, + argumentTypes, + }; + } + + static nativeFunctionReturnType(source) { + return typeMap[source.match(/int|float|vec[2-4]/)[0]]; + } + + static combineKernels(combinedKernel, lastKernel) { + combinedKernel.apply(null, arguments); + const { + texSize, + context, + threadDim + } = lastKernel.texSize; + let result; + if (lastKernel.precision === 'single') { + const w = texSize[0]; + const h = Math.ceil(texSize[1] / 4); + result = new Float32Array(w * h * 4 * 4); + context.readPixels(0, 0, w, h * 4, context.RGBA, context.FLOAT, result); + } else { + const bytes = new Uint8Array(texSize[0] * texSize[1] * 4); + context.readPixels(0, 0, texSize[0], texSize[1], context.RGBA, context.UNSIGNED_BYTE, bytes); + result = new Float32Array(bytes.buffer); + } + + result = result.subarray(0, threadDim[0] * threadDim[1] * threadDim[2]); + + if (lastKernel.output.length === 1) { + return result; + } else if (lastKernel.output.length === 2) { + return utils.splitArray(result, lastKernel.output[0]); + } else if (lastKernel.output.length === 3) { + const cube = utils.splitArray(result, lastKernel.output[0] * lastKernel.output[1]); + return cube.map(function(x) { + return utils.splitArray(x, lastKernel.output[0]); + }); + } + } + + constructor(source, settings) { + super(source, settings); + this.transferValues = null; + this.formatValues = null; + this.TextureConstructor = null; + this.renderOutput = null; + this.renderRawOutput = null; + this.texSize = null; + this.translatedSource = null; + this.renderStrategy = null; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + } + + checkTextureSize() { + const { features } = this.constructor; + if (this.texSize[0] > features.maxTextureSize || this.texSize[1] > features.maxTextureSize) { + throw new Error(`Texture size [${this.texSize[0]},${this.texSize[1]}] generated by kernel is larger than supported size [${features.maxTextureSize},${features.maxTextureSize}]`); + } + } + + translateSource() { + throw new Error(`"translateSource" not defined on ${this.constructor.name}`); + } + + /** + * Picks a render strategy for the now finally parsed kernel + * @param args + * @return {null|KernelOutput} + */ + pickRenderStrategy(args) { + if (this.graphical) { + this.renderRawOutput = this.readPackedPixelsToUint8Array; + this.transferValues = (pixels) => pixels; + this.TextureConstructor = GLTextureGraphical; + return null; + } + if (this.precision === 'unsigned') { + this.renderRawOutput = this.readPackedPixelsToUint8Array; + this.transferValues = this.readPackedPixelsToFloat32Array; + if (this.pipeline) { + this.renderOutput = this.renderTexture; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToTextures; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureUnsigned3D; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + return null; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); + } + } else { + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToArrays; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + this.renderOutput = this.renderValues; + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureUnsigned3D; + this.renderStrategy = renderStrategy.PackedPixelTo3DFloat; + this.formatValues = utils.erect3DPackedFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureUnsigned2D; + this.renderStrategy = renderStrategy.PackedPixelTo2DFloat; + this.formatValues = utils.erect2DPackedFloat; + return null; + } else { + this.TextureConstructor = GLTextureUnsigned; + this.renderStrategy = renderStrategy.PackedPixelToFloat; + this.formatValues = utils.erectPackedFloat; + return null; + } + + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + return this.requestFallback(args); + } + } + } else if (this.precision === 'single') { + this.renderRawOutput = this.readFloatPixelsToFloat32Array; + this.transferValues = this.readFloatPixelsToFloat32Array; + if (this.pipeline) { + this.renderStrategy = renderStrategy.FloatTexture; + this.renderOutput = this.renderTexture; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToTextures; + } + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.optimizeFloatMemory) { + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + return null; + } + } else { + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureFloat3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + return null; + } + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + return null; + } + } + } + this.renderOutput = this.renderValues; + if (this.subKernels !== null) { + this.renderKernels = this.renderKernelsToArrays; + } + if (this.optimizeFloatMemory) { + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized3D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized3DFloat; + this.formatValues = utils.erectMemoryOptimized3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureMemoryOptimized2D; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimized2DFloat; + this.formatValues = utils.erectMemoryOptimized2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureMemoryOptimized; + this.renderStrategy = renderStrategy.MemoryOptimizedFloatPixelToMemoryOptimizedFloat; + this.formatValues = utils.erectMemoryOptimizedFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils.erectArray4; + return null; + } + } + } else { + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureFloat3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DFloat; + this.formatValues = utils.erect3DFloat; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureFloat2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DFloat; + this.formatValues = utils.erect2DFloat; + return null; + } else { + this.TextureConstructor = GLTextureFloat; + this.renderStrategy = renderStrategy.FloatPixelToFloat; + this.formatValues = utils.erectFloat; + return null; + } + break; + case 'Array(2)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray2Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray2; + this.formatValues = utils.erect3DArray2; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray2Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray2; + this.formatValues = utils.erect2DArray2; + return null; + } else { + this.TextureConstructor = GLTextureArray2Float; + this.renderStrategy = renderStrategy.FloatPixelToArray2; + this.formatValues = utils.erectArray2; + return null; + } + break; + case 'Array(3)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray3Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray3; + this.formatValues = utils.erect3DArray3; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray3Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray3; + this.formatValues = utils.erect2DArray3; + return null; + } else { + this.TextureConstructor = GLTextureArray3Float; + this.renderStrategy = renderStrategy.FloatPixelToArray3; + this.formatValues = utils.erectArray3; + return null; + } + break; + case 'Array(4)': + if (this.output[2] > 0) { + this.TextureConstructor = GLTextureArray4Float3D; + this.renderStrategy = renderStrategy.FloatPixelTo3DArray4; + this.formatValues = utils.erect3DArray4; + return null; + } else if (this.output[1] > 0) { + this.TextureConstructor = GLTextureArray4Float2D; + this.renderStrategy = renderStrategy.FloatPixelTo2DArray4; + this.formatValues = utils.erect2DArray4; + return null; + } else { + this.TextureConstructor = GLTextureArray4Float; + this.renderStrategy = renderStrategy.FloatPixelToArray4; + this.formatValues = utils.erectArray4; + return null; + } + } + } + } else { + throw new Error(`unhandled precision of "${this.precision}"`); + } + + throw new Error(`unhandled return type "${this.returnType}"`); + } + + /** + * @abstract + * @returns String + */ + getKernelString() { + throw new Error(`abstract method call`); + } + + getMainResultTexture() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Float': + case 'Integer': + case 'Number': + return this.getMainResultNumberTexture(); + case 'Array(2)': + return this.getMainResultArray2Texture(); + case 'Array(3)': + return this.getMainResultArray3Texture(); + case 'Array(4)': + return this.getMainResultArray4Texture(); + default: + throw new Error(`unhandled returnType type ${ this.returnType }`); + } + } + + /** + * @abstract + * @returns String[] + */ + getMainResultKernelNumberTexture() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultSubKernelNumberTexture() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultKernelArray2Texture() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultSubKernelArray2Texture() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultKernelArray3Texture() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultSubKernelArray3Texture() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultKernelArray4Texture() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultSubKernelArray4Texture() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultGraphical() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultMemoryOptimizedFloats() { + throw new Error(`abstract method call`); + } + /** + * @abstract + * @returns String[] + */ + getMainResultPackedPixels() { + throw new Error(`abstract method call`); + } + + getMainResultString() { + if (this.graphical) { + return this.getMainResultGraphical(); + } else if (this.precision === 'single') { + if (this.optimizeFloatMemory) { + return this.getMainResultMemoryOptimizedFloats(); + } + return this.getMainResultTexture(); + } else { + return this.getMainResultPackedPixels(); + } + } + + getMainResultNumberTexture() { + return utils.linesToString(this.getMainResultKernelNumberTexture()) + + utils.linesToString(this.getMainResultSubKernelNumberTexture()); + } + + getMainResultArray2Texture() { + return utils.linesToString(this.getMainResultKernelArray2Texture()) + + utils.linesToString(this.getMainResultSubKernelArray2Texture()); + } + + getMainResultArray3Texture() { + return utils.linesToString(this.getMainResultKernelArray3Texture()) + + utils.linesToString(this.getMainResultSubKernelArray3Texture()); + } + + getMainResultArray4Texture() { + return utils.linesToString(this.getMainResultKernelArray4Texture()) + + utils.linesToString(this.getMainResultSubKernelArray4Texture()); + } + + /** + * + * @return {string} + */ + getFloatTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp float;\n'; + case 'performance': + return 'precision highp float;\n'; + case 'balanced': + default: + return 'precision mediump float;\n'; + } + } + + /** + * + * @return {string} + */ + getIntTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp int;\n'; + case 'performance': + return 'precision highp int;\n'; + case 'balanced': + default: + return 'precision mediump int;\n'; + } + } + + /** + * + * @return {string} + */ + getSampler2DTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2D;\n'; + case 'performance': + return 'precision highp sampler2D;\n'; + case 'balanced': + default: + return 'precision mediump sampler2D;\n'; + } + } + + getSampler2DArrayTacticDeclaration() { + switch (this.tactic) { + case 'speed': + return 'precision lowp sampler2DArray;\n'; + case 'performance': + return 'precision highp sampler2DArray;\n'; + case 'balanced': + default: + return 'precision mediump sampler2DArray;\n'; + } + } + + renderTexture() { + return new this.TextureConstructor({ + texture: this.outputTexture, + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + readPackedPixelsToUint8Array() { + if (this.precision !== 'unsigned') throw new Error('Requires this.precision to be "unsigned"'); + const { + texSize, + context: gl + } = this; + const result = new Uint8Array(texSize[0] * texSize[1] * 4); + gl.readPixels(0, 0, texSize[0], texSize[1], gl.RGBA, gl.UNSIGNED_BYTE, result); + return result; + } + + readPackedPixelsToFloat32Array() { + return new Float32Array(this.readPackedPixelsToUint8Array().buffer); + } + + readFloatPixelsToFloat32Array() { + if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); + const { + texSize, + context: gl + } = this; + const w = texSize[0]; + const h = texSize[1]; + const result = new Float32Array(w * h * 4); + gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); + return result; + } + + readMemoryOptimizedFloatPixelsToFloat32Array() { + if (this.precision !== 'single') throw new Error('Requires this.precision to be "single"'); + const { + texSize, + context: gl + } = this; + const w = texSize[0]; + const h = texSize[1]; + const result = new Float32Array(w * h * 4); + gl.readPixels(0, 0, w, h, gl.RGBA, gl.FLOAT, result); + return result; + } + + /** + * + * @param {Boolean} [flip] + * @return {Uint8Array} + */ + getPixels(flip) { + const { + context: gl, + output + } = this; + const [width, height] = output; + const pixels = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + // flipped by default, so invert + return new Uint8ClampedArray((flip ? pixels : utils.flipPixels(pixels, width, height)).buffer); + } + + renderKernelsToArrays() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }).toArray(); + } + return result; + } + + renderKernelsToTextures() { + const result = { + result: this.renderOutput(), + }; + for (let i = 0; i < this.subKernels.length; i++) { + result[this.subKernels[i].property] = new this.TextureConstructor({ + texture: this.subKernelOutputTextures[i], + size: this.texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + return result; + } + + setOutput(output) { + super.setOutput(output); + if (this.program) { + this.threadDim = [this.output[0], this.output[1] || 1, this.output[2] || 1]; + this.texSize = utils.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + const { context: gl } = this; + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + this.updateMaxTexSize(); + this.framebuffer.width = this.texSize[0]; + this.framebuffer.height = this.texSize[1]; + this.context.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + this.canvas.width = this.maxTexSize[0]; + this.canvas.height = this.maxTexSize[1]; + this._setupOutputTexture(); + if (this.subKernels && this.subKernels.length > 0) { + this._setupSubOutputTextures(); + } + } + return this; + } + renderValues() { + return this.formatValues( + this.transferValues(), + this.output[0], + this.output[1], + this.output[2] + ); + } +} + +export const renderStrategy = Object.freeze({ + PackedPixelToUint8Array: Symbol('PackedPixelToUint8Array'), + PackedPixelToFloat: Symbol('PackedPixelToFloat'), + PackedPixelTo2DFloat: Symbol('PackedPixelTo2DFloat'), + PackedPixelTo3DFloat: Symbol('PackedPixelTo3DFloat'), + PackedTexture: Symbol('PackedTexture'), + FloatPixelToFloat32Array: Symbol('FloatPixelToFloat32Array'), + FloatPixelToFloat: Symbol('FloatPixelToFloat'), + FloatPixelTo2DFloat: Symbol('FloatPixelTo2DFloat'), + FloatPixelTo3DFloat: Symbol('FloatPixelTo3DFloat'), + FloatPixelToArray2: Symbol('FloatPixelToArray2'), + FloatPixelTo2DArray2: Symbol('FloatPixelTo2DArray2'), + FloatPixelTo3DArray2: Symbol('FloatPixelTo3DArray2'), + FloatPixelToArray3: Symbol('FloatPixelToArray3'), + FloatPixelTo2DArray3: Symbol('FloatPixelTo2DArray3'), + FloatPixelTo3DArray3: Symbol('FloatPixelTo3DArray3'), + FloatPixelToArray4: Symbol('FloatPixelToArray4'), + FloatPixelTo2DArray4: Symbol('FloatPixelTo2DArray4'), + FloatPixelTo3DArray4: Symbol('FloatPixelTo3DArray4'), + FloatTexture: Symbol('FloatTexture'), + MemoryOptimizedFloatPixelToMemoryOptimizedFloat: Symbol('MemoryOptimizedFloatPixelToFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized2DFloat: Symbol('MemoryOptimizedFloatPixelTo2DFloat'), + MemoryOptimizedFloatPixelToMemoryOptimized3DFloat: Symbol('MemoryOptimizedFloatPixelTo3DFloat'), +}); + +const typeMap = { + int: 'Integer', + float: 'Number', + vec2: 'Array(2)', + vec3: 'Array(3)', + vec4: 'Array(4)', +}; diff --git a/src/backend/gl/texture/array-2-float-2d.js b/src/backend/gl/texture/array-2-float-2d.js index a0e7defd..60e14603 100644 --- a/src/backend/gl/texture/array-2-float-2d.js +++ b/src/backend/gl/texture/array-2-float-2d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray2Float2D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray2Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils.erect2DArray2(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/array-2-float-3d.js b/src/backend/gl/texture/array-2-float-3d.js index 28f5b092..fb960a2f 100644 --- a/src/backend/gl/texture/array-2-float-3d.js +++ b/src/backend/gl/texture/array-2-float-3d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray2Float3D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray2Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils.erect3DArray2(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } +} diff --git a/src/backend/gl/texture/array-2-float.js b/src/backend/gl/texture/array-2-float.js index fab1a2ae..122ed4e6 100644 --- a/src/backend/gl/texture/array-2-float.js +++ b/src/backend/gl/texture/array-2-float.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray2Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(2)'; - } - toArray() { - return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray2Float -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray2Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(2)'; + } + toArray() { + return utils.erectArray2(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/array-3-float-2d.js b/src/backend/gl/texture/array-3-float-2d.js index 4f615879..d5292524 100644 --- a/src/backend/gl/texture/array-3-float-2d.js +++ b/src/backend/gl/texture/array-3-float-2d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray3Float2D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray3Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils.erect2DArray3(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/array-3-float-3d.js b/src/backend/gl/texture/array-3-float-3d.js index ea53aee0..ad8910ad 100644 --- a/src/backend/gl/texture/array-3-float-3d.js +++ b/src/backend/gl/texture/array-3-float-3d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray3Float3D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray3Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils.erect3DArray3(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } +} diff --git a/src/backend/gl/texture/array-3-float.js b/src/backend/gl/texture/array-3-float.js index 5f99396b..009ea8d4 100644 --- a/src/backend/gl/texture/array-3-float.js +++ b/src/backend/gl/texture/array-3-float.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray3Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(3)'; - } - toArray() { - return utils.erectArray3(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureArray3Float -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray3Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(3)'; + } + toArray() { + return utils.erectArray3(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/gl/texture/array-4-float-2d.js b/src/backend/gl/texture/array-4-float-2d.js index a370eaa2..2c1a2bbe 100644 --- a/src/backend/gl/texture/array-4-float-2d.js +++ b/src/backend/gl/texture/array-4-float-2d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureArray4Float2D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray4Float2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils.erect2DArray4(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/array-4-float-3d.js b/src/backend/gl/texture/array-4-float-3d.js index 21e09249..6319565a 100644 --- a/src/backend/gl/texture/array-4-float-3d.js +++ b/src/backend/gl/texture/array-4-float-3d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureArray4Float3D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray4Float3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils.erect3DArray4(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } +} diff --git a/src/backend/gl/texture/array-4-float.js b/src/backend/gl/texture/array-4-float.js index 80553d15..4ac9d45a 100644 --- a/src/backend/gl/texture/array-4-float.js +++ b/src/backend/gl/texture/array-4-float.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureArray4Float extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return utils.erectArray4(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureArray4Float -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureArray4Float extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return utils.erectArray4(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/gl/texture/float-2d.js b/src/backend/gl/texture/float-2d.js index 1fb927e9..441e7d71 100644 --- a/src/backend/gl/texture/float-2d.js +++ b/src/backend/gl/texture/float-2d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureFloat2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - toArray() { - return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureFloat2D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureFloat2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils.erect2DFloat(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/float-3d.js b/src/backend/gl/texture/float-3d.js index 9a8a536f..61a19039 100644 --- a/src/backend/gl/texture/float-3d.js +++ b/src/backend/gl/texture/float-3d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureFloat3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - toArray() { - return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureFloat3D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureFloat3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + toArray() { + return utils.erect3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } +} diff --git a/src/backend/gl/texture/float.js b/src/backend/gl/texture/float.js index 8f0b172f..8e050d08 100644 --- a/src/backend/gl/texture/float.js +++ b/src/backend/gl/texture/float.js @@ -1,34 +1,30 @@ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureFloat extends Texture { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(1)'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Float32Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); - return result; - } - renderValues() { - return this.renderRawOutput(); - } - toArray() { - return utils.erectFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureFloat -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { Texture } from '../../../texture'; + +export class GLTextureFloat extends Texture { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(1)'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Float32Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.FLOAT, result); + return result; + } + renderValues() { + return this.renderRawOutput(); + } + toArray() { + return utils.erectFloat(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/gl/texture/graphical.js b/src/backend/gl/texture/graphical.js index 18360021..d2d8b98e 100644 --- a/src/backend/gl/texture/graphical.js +++ b/src/backend/gl/texture/graphical.js @@ -1,15 +1,11 @@ -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureGraphical extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'ArrayTexture(4)'; - } - toArray() { - return this.renderValues(); - } -} - -module.exports = { - GLTextureGraphical -}; \ No newline at end of file +import { GLTextureUnsigned } from './unsigned'; + +export class GLTextureGraphical extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'ArrayTexture(4)'; + } + toArray() { + return this.renderValues(); + } +} diff --git a/src/backend/gl/texture/memory-optimized-2d.js b/src/backend/gl/texture/memory-optimized-2d.js index 20234ee3..f271274f 100644 --- a/src/backend/gl/texture/memory-optimized-2d.js +++ b/src/backend/gl/texture/memory-optimized-2d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized2D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureMemoryOptimized2D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureMemoryOptimized2D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils.erectMemoryOptimized2DFloat(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/memory-optimized-3d.js b/src/backend/gl/texture/memory-optimized-3d.js index f65e5f9f..847b7975 100644 --- a/src/backend/gl/texture/memory-optimized-3d.js +++ b/src/backend/gl/texture/memory-optimized-3d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized3D extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureMemoryOptimized3D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureMemoryOptimized3D extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils.erectMemoryOptimized3DFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } +} diff --git a/src/backend/gl/texture/memory-optimized.js b/src/backend/gl/texture/memory-optimized.js index 03474f58..f686b15a 100644 --- a/src/backend/gl/texture/memory-optimized.js +++ b/src/backend/gl/texture/memory-optimized.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureFloat } = require('./float'); - -class GLTextureMemoryOptimized extends GLTextureFloat { - constructor(settings) { - super(settings); - this.type = 'MemoryOptimizedNumberTexture'; - } - toArray() { - return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureMemoryOptimized -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureFloat } from './float'; + +export class GLTextureMemoryOptimized extends GLTextureFloat { + constructor(settings) { + super(settings); + this.type = 'MemoryOptimizedNumberTexture'; + } + toArray() { + return utils.erectMemoryOptimizedFloat(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/gl/texture/unsigned-2d.js b/src/backend/gl/texture/unsigned-2d.js index 3adba8b1..ab717c9a 100644 --- a/src/backend/gl/texture/unsigned-2d.js +++ b/src/backend/gl/texture/unsigned-2d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureUnsigned2D extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - toArray() { - return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); - } -} - -module.exports = { - GLTextureUnsigned2D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureUnsigned } from './unsigned'; + +export class GLTextureUnsigned2D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils.erect2DPackedFloat(this.renderValues(), this.output[0], this.output[1]); + } +} diff --git a/src/backend/gl/texture/unsigned-3d.js b/src/backend/gl/texture/unsigned-3d.js index ccedf143..343aff56 100644 --- a/src/backend/gl/texture/unsigned-3d.js +++ b/src/backend/gl/texture/unsigned-3d.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { GLTextureUnsigned } = require('./unsigned'); - -class GLTextureUnsigned3D extends GLTextureUnsigned { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - toArray() { - return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); - } -} - -module.exports = { - GLTextureUnsigned3D -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { GLTextureUnsigned } from './unsigned'; + +export class GLTextureUnsigned3D extends GLTextureUnsigned { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + toArray() { + return utils.erect3DPackedFloat(this.renderValues(), this.output[0], this.output[1], this.output[2]); + } +} diff --git a/src/backend/gl/texture/unsigned.js b/src/backend/gl/texture/unsigned.js index e67de8db..294b4f28 100644 --- a/src/backend/gl/texture/unsigned.js +++ b/src/backend/gl/texture/unsigned.js @@ -1,34 +1,30 @@ -const { utils } = require('../../../utils'); -const { Texture } = require('../../../texture'); - -class GLTextureUnsigned extends Texture { - constructor(settings) { - super(settings); - this.type = 'NumberTexture'; - } - renderRawOutput() { - const { context: gl } = this; - const framebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); - gl.framebufferTexture2D( - gl.FRAMEBUFFER, - gl.COLOR_ATTACHMENT0, - gl.TEXTURE_2D, - this.texture, - 0 - ); - const result = new Uint8Array(this.size[0] * this.size[1] * 4); - gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result); - return result; - } - renderValues() { - return new Float32Array(this.renderRawOutput().buffer); - } - toArray() { - return utils.erectPackedFloat(this.renderValues(), this.output[0]); - } -} - -module.exports = { - GLTextureUnsigned -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { Texture } from '../../../texture'; + +export class GLTextureUnsigned extends Texture { + constructor(settings) { + super(settings); + this.type = 'NumberTexture'; + } + renderRawOutput() { + const { context: gl } = this; + const framebuffer = gl.createFramebuffer(); + gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + this.texture, + 0 + ); + const result = new Uint8Array(this.size[0] * this.size[1] * 4); + gl.readPixels(0, 0, this.size[0], this.size[1], gl.RGBA, gl.UNSIGNED_BYTE, result); + return result; + } + renderValues() { + return new Float32Array(this.renderRawOutput().buffer); + } + toArray() { + return utils.erectPackedFloat(this.renderValues(), this.output[0]); + } +} diff --git a/src/backend/headless-gl/kernel.js b/src/backend/headless-gl/kernel.js index 2b3ee845..8f208e82 100644 --- a/src/backend/headless-gl/kernel.js +++ b/src/backend/headless-gl/kernel.js @@ -1,157 +1,154 @@ -const getContext = require('gl'); -const { WebGLKernel } = require('../web-gl/kernel'); -const { glKernelString } = require('../gl/kernel-string'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; -let features = null; - -class HeadlessGLKernel extends WebGLKernel { - static get isSupported() { - if (isSupported !== null) return isSupported; - this.setupFeatureChecks(); - isSupported = testContext !== null; - return isSupported; - } - - static setupFeatureChecks() { - testCanvas = null; - testExtensions = null; - if (typeof getContext !== 'function') return; - try { // just in case, edge cases - testContext = getContext(2, 2, { - preserveDrawingBuffer: true - }); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - STACKGL_resize_drawingbuffer: testContext.getExtension('STACKGL_resize_drawingbuffer'), - STACKGL_destroy_context: testContext.getExtension('STACKGL_destroy_context'), - OES_texture_float: testContext.getExtension('OES_texture_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), - }; - features = this.getFeatures(); - } catch (e) { - console.warn(e); - } - } - - static isContextMatch(context) { - try { - return context.getParameter(context.RENDERER) === 'ANGLE'; - } catch (e) { - return false; - } - } - - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - static getIsTextureFloat() { - return Boolean(testExtensions.OES_texture_float); - } - - static getIsDrawBuffers() { - return Boolean(testExtensions.WEBGL_draw_buffers); - } - - static getChannelCount() { - return testExtensions.WEBGL_draw_buffers ? - testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : - 1; - } - - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); - } - - static get testCanvas() { - return testCanvas; - } - - static get testContext() { - return testContext; - } - - static get features() { - return features; - } - - initCanvas() { - return {}; - } - - initContext() { - const context = getContext(2, 2, { - preserveDrawingBuffer: true - }); - return context; - } - - initExtensions() { - this.extensions = { - STACKGL_resize_drawingbuffer: this.context.getExtension('STACKGL_resize_drawingbuffer'), - STACKGL_destroy_context: this.context.getExtension('STACKGL_destroy_context'), - OES_texture_float: this.context.getExtension('OES_texture_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), - }; - } - - build() { - super.build.apply(this, arguments); - if (!this.fallbackRequested) { - this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); - } - } - - destroyExtensions() { - this.extensions.STACKGL_resize_drawingbuffer = null; - this.extensions.STACKGL_destroy_context = null; - this.extensions.OES_texture_float = null; - this.extensions.OES_texture_float_linear = null; - this.extensions.OES_element_index_uint = null; - this.extensions.WEBGL_draw_buffers = null; - } - - static destroyContext(context) { - const extension = context.getExtension('STACKGL_destroy_context'); - if (extension && extension.destroy) { - extension.destroy(); - } - } - - /** - * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused. - */ - toString() { - const setupContextString = `const gl = context || require('gl')(1, 1);\n`; - const destroyContextString = ` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n`; - return glKernelString(this.constructor, arguments, this, setupContextString, destroyContextString); - } - - setOutput(output) { - super.setOutput(output); - if (this.graphical && this.extensions.STACKGL_resize_drawingbuffer) { - this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); - } - } -} - -module.exports = { - HeadlessGLKernel -}; \ No newline at end of file +import getContext from 'gl' +import { WebGLKernel } from '../web-gl/kernel'; +import { glKernelString } from '../gl/kernel-string'; + +let isSupported = null; +let testCanvas = null; +let testContext = null; +let testExtensions = null; +let features = null; + +export class HeadlessGLKernel extends WebGLKernel { + static get isSupported() { + if (isSupported !== null) return isSupported; + this.setupFeatureChecks(); + isSupported = testContext !== null; + return isSupported; + } + + static setupFeatureChecks() { + testCanvas = null; + testExtensions = null; + if (typeof getContext !== 'function') return; + try { + // Edge cases (just in case) + testContext = getContext(2, 2, { + preserveDrawingBuffer: true + }); + if (!testContext || !testContext.getExtension) return; + testExtensions = { + STACKGL_resize_drawingbuffer: testContext.getExtension('STACKGL_resize_drawingbuffer'), + STACKGL_destroy_context: testContext.getExtension('STACKGL_destroy_context'), + OES_texture_float: testContext.getExtension('OES_texture_float'), + OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), + OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), + WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), + }; + features = this.getFeatures(); + } catch (e) { + console.warn(e); + } + } + + static isContextMatch(context) { + try { + return context.getParameter(context.RENDERER) === 'ANGLE'; + } catch (e) { + return false; + } + } + + static getFeatures() { + const isDrawBuffers = this.getIsDrawBuffers(); + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + isTextureFloat: this.getIsTextureFloat(), + isDrawBuffers, + kernelMap: isDrawBuffers, + channelCount: this.getChannelCount(), + maxTextureSize: this.getMaxTextureSize(), + }); + } + + static getIsTextureFloat() { + return Boolean(testExtensions.OES_texture_float); + } + + static getIsDrawBuffers() { + return Boolean(testExtensions.WEBGL_draw_buffers); + } + + static getChannelCount() { + return testExtensions.WEBGL_draw_buffers ? + testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : + 1; + } + + static get testCanvas() { + return testCanvas; + } + + static getMaxTextureSize() { + return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); + } + + static get testContext() { + return testContext; + } + + static get features() { + return features; + } + + initCanvas() { + return {}; + } + + initContext() { + const context = getContext(2, 2, { + preserveDrawingBuffer: true + }); + return context; + } + + initExtensions() { + this.extensions = { + STACKGL_resize_drawingbuffer: this.context.getExtension('STACKGL_resize_drawingbuffer'), + STACKGL_destroy_context: this.context.getExtension('STACKGL_destroy_context'), + OES_texture_float: this.context.getExtension('OES_texture_float'), + OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), + OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), + WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), + }; + } + + build() { + super.build.apply(this, arguments); + if (!this.fallbackRequested) { + this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); + } + } + + destroyExtensions() { + this.extensions.STACKGL_resize_drawingbuffer = null; + this.extensions.STACKGL_destroy_context = null; + this.extensions.OES_texture_float = null; + this.extensions.OES_texture_float_linear = null; + this.extensions.OES_element_index_uint = null; + this.extensions.WEBGL_draw_buffers = null; + } + + static destroyContext(context) { + const extension = context.getExtension('STACKGL_destroy_context'); + if (extension && extension.destroy) { + extension.destroy(); + } + } + + /** + * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused. + */ + toString() { + const setupContextString = `const gl = context || require('gl')(1, 1);\n`; + const destroyContextString = ` if (!context) { gl.getExtension('STACKGL_destroy_context').destroy(); }\n`; + return glKernelString(this.constructor, arguments, this, setupContextString, destroyContextString); + } + + setOutput(output) { + super.setOutput(output); + if (this.graphical && this.extensions.STACKGL_resize_drawingbuffer) { + this.extensions.STACKGL_resize_drawingbuffer.resize(this.maxTexSize[0], this.maxTexSize[1]); + } + } +}; diff --git a/src/backend/kernel-value.js b/src/backend/kernel-value.js index ca1f9211..826de1f8 100644 --- a/src/backend/kernel-value.js +++ b/src/backend/kernel-value.js @@ -1,70 +1,67 @@ -/** - * @class KernelValue - */ -class KernelValue { - /** - * @param {KernelVariable} value - * @param {IKernelValueSettings} settings - */ - constructor(value, settings) { - const { - name, - kernel, - context, - checkContext, - onRequestContextHandle, - onUpdateValueMismatch, - origin, - strictIntegers, - type, - tactic, - } = settings; - if (!name) { - throw new Error('name not set'); - } - if (!type) { - throw new Error('type not set'); - } - if (!origin) { - throw new Error('origin not set'); - } - if (!tactic) { - throw new Error('tactic not set'); - } - if (origin !== 'user' && origin !== 'constants') { - throw new Error(`origin must be "user" or "constants" value is "${ origin }"`); - } - if (!onRequestContextHandle) { - throw new Error('onRequestContextHandle is not set'); - } - this.name = name; - this.origin = origin; - this.tactic = tactic; - this.id = `${this.origin}_${name}`; - this.varName = origin === 'constants' ? `constants.${name}` : name; - this.kernel = kernel; - this.strictIntegers = strictIntegers; - // handle textures - this.type = value.type || type; - this.size = value.size || null; - this.index = null; - this.context = context; - this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true; - this.contextHandle = null; - this.onRequestContextHandle = onRequestContextHandle; - this.onUpdateValueMismatch = onUpdateValueMismatch; - this.forceUploadEachRun = null; - } - - getSource() { - throw new Error(`"getSource" not defined on ${ this.constructor.name }`); - } - - updateValue(value) { - throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); - } -} - -module.exports = { - KernelValue -}; \ No newline at end of file +/** + * @class KernelValue + */ +export class KernelValue { + /** + * + * @param {KernelVariable} value + * @param {IKernelValueSettings} settings + */ + constructor(value, settings) { + const { + name, + kernel, + context, + checkContext, + onRequestContextHandle, + onUpdateValueMismatch, + origin, + strictIntegers, + type, + tactic, + } = settings; + if (!name) { + throw new Error('name not set'); + } + if (!type) { + throw new Error('type not set'); + } + if (!origin) { + throw new Error('origin not set'); + } + if (!tactic) { + throw new Error('tactic not set'); + } + if (origin !== 'user' && origin !== 'constants') { + throw new Error(`origin must be "user" or "constants" value is "${ origin }"`); + } + if (!onRequestContextHandle) { + throw new Error('onRequestContextHandle is not set'); + } + this.name = name; + this.origin = origin; + this.tactic = tactic; + this.id = `${this.origin}_${name}`; + this.varName = origin === 'constants' ? `constants.${name}` : name; + this.kernel = kernel; + this.strictIntegers = strictIntegers; + // handle textures + this.type = value.type || type; + this.size = value.size || null; + this.index = null; + this.context = context; + this.checkContext = checkContext !== null && checkContext !== undefined ? checkContext : true; + this.contextHandle = null; + this.onRequestContextHandle = onRequestContextHandle; + this.onUpdateValueMismatch = onUpdateValueMismatch; + this.forceUploadEachRun = null; + } + + getSource() { + throw new Error(`"getSource" not defined on ${ this.constructor.name }`); + } + + updateValue(value) { + throw new Error(`"updateValue" not defined on ${ this.constructor.name }`); + } +} diff --git a/src/backend/kernel.js b/src/backend/kernel.js index ebcb48c4..58d9fcb6 100644 --- a/src/backend/kernel.js +++ b/src/backend/kernel.js @@ -1,736 +1,738 @@ -const { utils } = require('../utils'); -const { Input } = require('../input'); - -class Kernel { - /** - * @type {Boolean} - */ - static get isSupported() { - throw new Error(`"isSupported" not implemented on ${ this.name }`); - } - - /** - * @type {Boolean} - */ - static isContextMatch(context) { - throw new Error(`"isContextMatch" not implemented on ${ this.name }`); - } - - /** - * @type {IKernelFeatures} - * Used internally to populate the kernel.feature, which is a getter for the output of this value - */ - static getFeatures() { - throw new Error(`"getFeatures" not implemented on ${ this.name }`); - } - - static destroyContext(context) { - throw new Error(`"destroyContext" called on ${ this.name }`); - } - - static nativeFunctionArguments() { - throw new Error(`"nativeFunctionArguments" called on ${ this.name }`); - } - - static nativeFunctionReturnType() { - throw new Error(`"nativeFunctionReturnType" called on ${ this.name }`); - } - - static combineKernels() { - throw new Error(`"combineKernels" called on ${ this.name }`); - } - - /** - * - * @param {string|object} source - * @param [settings] - */ - constructor(source, settings) { - if (typeof source !== 'object') { - if (typeof source !== 'string') { - throw new Error('source not a string'); - } - if (!utils.isFunctionString(source)) { - throw new Error('source not a function string'); - } - } - this.useLegacyEncoder = false; - this.fallbackRequested = false; - this.onRequestFallback = null; - - /** - * Name of the arguments found from parsing source argument - * @type {String[]} - */ - this.argumentNames = typeof source === 'string' ? utils.getArgumentNamesFromString(source) : null; - this.argumentTypes = null; - this.argumentSizes = null; - this.argumentBitRatios = null; - this.kernelArguments = null; - this.kernelConstants = null; - this.forceUploadKernelConstants = null; - - - /** - * The function source - * @type {String} - */ - this.source = source; - - /** - * The size of the kernel's output - * @type {Number[]} - */ - this.output = null; - - /** - * Debug mode - * @type {Boolean} - */ - this.debug = false; - - /** - * Graphical mode - * @type {Boolean} - */ - this.graphical = false; - - /** - * Maximum loops when using argument values to prevent infinity - * @type {Number} - */ - this.loopMaxIterations = 0; - - /** - * Constants used in kernel via `this.constants` - * @type {Object} - */ - this.constants = null; - this.constantTypes = null; - this.constantBitRatios = null; - this.dynamicArguments = false; - this.dynamicOutput = false; - - /** - * - * @type {Object} - */ - this.canvas = null; - - /** - * - * @type {WebGLRenderingContext} - */ - this.context = null; - - /** - * - * @type {Boolean} - */ - this.checkContext = null; - - /** - * - * @type {GPU} - */ - this.gpu = null; - - /** - * - * @type {IGPUFunction[]} - */ - this.functions = null; - - /** - * - * @type {IGPUNativeFunction[]} - */ - this.nativeFunctions = null; - - /** - * - * @type {String} - */ - this.injectedNative = null; - - /** - * - * @type {ISubKernel[]} - */ - this.subKernels = null; - - /** - * - * @type {Boolean} - */ - this.validate = true; - - /** - * Enforces kernel to write to a new array or texture on run - * @type {Boolean} - */ - this.immutable = false; - - /** - * Enforces kernel to write to a texture on run - * @type {Boolean} - */ - this.pipeline = false; - - /** - * Make GPU use single precison or unsigned. Acceptable values: 'single' or 'unsigned' - * @type {String|null} - * @enum 'single' | 'unsigned' - */ - this.precision = null; - - /** - * - * @type {String|null} - * @enum 'speed' | 'balanced' | 'precision' - */ - this.tactic = 'balanced'; - - this.plugins = null; - - this.returnType = null; - this.leadingReturnStatement = null; - this.followingReturnStatement = null; - this.optimizeFloatMemory = null; - this.strictIntegers = false; - this.fixIntegerDivisionAccuracy = null; - this.warnVarUsage = true; - } - - mergeSettings(settings) { - for (let p in settings) { - if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue; - switch (p) { - case 'output': - if (!Array.isArray(settings.output)) { - this.setOutput(settings.output); // Flatten output object - continue; - } - break; - case 'functions': - if (typeof settings.functions[0] === 'function') { - this.functions = settings.functions.map(source => utils.functionToIFunction(source)); - continue; - } - break; - case 'graphical': - if (settings[p] && !settings.hasOwnProperty('precision')) { - this.precision = 'unsigned'; - } - this[p] = settings[p]; - continue; - } - this[p] = settings[p]; - } - - if (!this.canvas) this.canvas = this.initCanvas(); - if (!this.context) this.context = this.initContext(); - if (!this.plugins) this.plugins = this.initPlugins(settings); - } - /** - * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders, - * and instantiates the program. - * @abstract - */ - build() { - throw new Error(`"build" not defined on ${ this.constructor.name }`); - } - - /** - * @desc Run the kernel program, and send the output to renderOutput - *

This method calls a helper method *renderOutput* to return the result.

- * @returns {Float32Array|Float32Array[]|Float32Array[][]|void} Result The final output of the program, as float, and as Textures for reuse. - * @abstract - */ - run() { - throw new Error(`"run" not defined on ${ this.constructor.name }`) - } - - /** - * @abstract - * @return {Object} - */ - initCanvas() { - throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`); - } - - /** - * @abstract - * @return {Object} - */ - initContext() { - throw new Error(`"initContext" not defined on ${ this.constructor.name }`); - } - - /** - * @param {IFunctionSettings} settings - * @return {Object}; - * @abstract - */ - initPlugins(settings) { - throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`); - } - - /** - * @desc Setup the parameter types for the parameters - * supplied to the Kernel function - * - * @param {IArguments} args - The actual parameters sent to the Kernel - */ - setupArguments(args) { - this.kernelArguments = []; - if (!this.argumentTypes) { - if (!this.argumentTypes) { - this.argumentTypes = []; - for (let i = 0; i < args.length; i++) { - const argType = utils.getVariableType(args[i], this.strictIntegers); - const type = argType === 'Integer' ? 'Number' : argType; - this.argumentTypes.push(type); - this.kernelArguments.push({ - type - }); - } - } - } else { - for (let i = 0; i < this.argumentTypes.length; i++) { - this.kernelArguments.push({ - type: this.argumentTypes[i] - }); - } - } - - // setup sizes - this.argumentSizes = new Array(args.length); - this.argumentBitRatios = new Int32Array(args.length); - - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - this.argumentSizes[i] = arg.constructor === Input ? arg.size : null; - this.argumentBitRatios[i] = this.getBitRatio(arg); - } - - if (this.argumentNames.length !== args.length) { - throw new Error(`arguments are miss-aligned`); - } - } - - /** - * Setup constants - */ - setupConstants() { - this.kernelConstants = []; - let needsConstantTypes = this.constantTypes === null; - if (needsConstantTypes) { - this.constantTypes = {}; - } - this.constantBitRatios = {}; - if (this.constants) { - for (let name in this.constants) { - if (needsConstantTypes) { - const type = utils.getVariableType(this.constants[name], this.strictIntegers); - this.constantTypes[name] = type; - this.kernelConstants.push({ - name, - type - }); - } else { - this.kernelConstants.push({ - name, - type: this.constantTypes[name] - }); - } - this.constantBitRatios[name] = this.getBitRatio(this.constants[name]); - } - } - } - - /** - * - * @param flag - * @return {Kernel} - */ - setOptimizeFloatMemory(flag) { - this.optimizeFloatMemory = flag; - return this; - } - - /** - * @desc Set output dimensions of the kernel function - * @param {Array|Object} output - The output array to set the kernel output size to - */ - setOutput(output) { - if (output.hasOwnProperty('x')) { - if (output.hasOwnProperty('y')) { - if (output.hasOwnProperty('z')) { - this.output = [output.x, output.y, output.z]; - } else { - this.output = [output.x, output.y]; - } - } else { - this.output = [output.x]; - } - } else { - this.output = output; - } - return this; - } - - /** - * @desc Toggle debug mode - * @param {Boolean} flag - true to enable debug - */ - setDebug(flag) { - this.debug = flag; - return this; - } - - /** - * @desc Toggle graphical output mode - * @param {Boolean} flag - true to enable graphical output - */ - setGraphical(flag) { - this.graphical = flag; - this.precision = 'unsigned'; - return this; - } - - /** - * @desc Set the maximum number of loop iterations - * @param {number} max - iterations count - * - */ - setLoopMaxIterations(max) { - this.loopMaxIterations = max; - return this; - } - - /** - * @desc Set Constants - */ - setConstants(constants) { - this.constants = constants; - return this; - } - - /** - * - * @param [IKernelValueTypes] constantTypes - * @return {Kernel} - */ - setConstantTypes(constantTypes) { - this.constantTypes = constantTypes; - return this; - } - - /** - * - * @param {IFunction[]|KernelFunction[]} functions - * @return {Kernel} - */ - setFunctions(functions) { - if (typeof functions[0] === 'function') { - this.functions = functions.map(source => utils.functionToIFunction(source)); - } else { - this.functions = functions; - } - return this; - } - - /** - * - * @param {IGPUNativeFunction} nativeFunctions - * @return {Kernel} - */ - setNativeFunctions(nativeFunctions) { - this.nativeFunctions = nativeFunctions; - return this; - } - - /** - * - * @param {String} injectedNative - * @return {Kernel} - */ - setInjectedNative(injectedNative) { - this.injectedNative = injectedNative; - return this; - } - - /** - * Set writing to texture on/off - * @param flag - * @return {Kernel} - */ - setPipeline(flag) { - this.pipeline = flag; - return this; - } - - /** - * Set precision to 'unsigned' or 'single' - * @param {String} flag 'unsigned' or 'single' - * @return {Kernel} - */ - setPrecision(flag) { - this.precision = flag; - return this; - } - - /** - * @param flag - * @return {Kernel} - * @deprecated - */ - setOutputToTexture(flag) { - utils.warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); - this.pipeline = flag; - return this; - } - - /** - * Set to immutable - * @param flag - * @return {Kernel} - */ - setImmutable(flag) { - this.immutable = flag; - return this; - } - - /** - * @desc Bind the canvas to kernel - * @param {Object} canvas - */ - setCanvas(canvas) { - this.canvas = canvas; - return this; - } - - /** - * @param {Boolean} flag - * @return {Kernel} - */ - setStrictIntegers(flag) { - this.strictIntegers = flag; - return this; - } - - /** - * - * @param flag - * @return {Kernel} - */ - setDynamicOutput(flag) { - this.dynamicOutput = flag; - return this; - } - - /** - * @deprecated - * @param flag - * @return {Kernel} - */ - setHardcodeConstants(flag) { - utils.warnDeprecated('method', 'setHardcodeConstants'); - this.setDynamicOutput(flag); - this.setDynamicArguments(flag); - return this; - } - - /** - * - * @param flag - * @return {Kernel} - */ - setDynamicArguments(flag) { - this.dynamicArguments = flag; - return this; - } - - /** - * @param {Boolean} flag - * @return {Kernel} - */ - setUseLegacyEncoder(flag) { - this.useLegacyEncoder = flag; - return this; - } - - /** - * - * @param {Boolean} flag - * @return {Kernel} - */ - setWarnVarUsage(flag) { - this.warnVarUsage = flag; - return this; - } - - /** - * @deprecated - * @returns {Object} - */ - getCanvas() { - utils.warnDeprecated('method', 'getCanvas'); - return this.canvas; - } - - /** - * @deprecated - * @returns {Object} - */ - getWebGl() { - utils.warnDeprecated('method', 'getWebGl'); - return this.context; - } - - /** - * @desc Bind the webGL instance to kernel - * @param {WebGLRenderingContext} context - webGl instance to bind - */ - setContext(context) { - this.context = context; - return this; - } - - /** - * - * @param [IKernelValueTypes|GPUVariableType[]] argumentTypes - * @return {Kernel} - */ - setArgumentTypes(argumentTypes) { - if (Array.isArray(argumentTypes)) { - this.argumentTypes = argumentTypes; - } else { - this.argumentTypes = []; - for (const p in argumentTypes) { - const argumentIndex = this.argumentNames.indexOf(p); - if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); - this.argumentTypes[argumentIndex] = argumentTypes[p]; - } - } - return this; - } - - /** - * - * @param [Tactic] tactic - * @return {Kernel} - */ - setTactic(tactic) { - this.tactic = tactic; - return this; - } - - requestFallback(args) { - if (!this.onRequestFallback) { - throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); - } - this.fallbackRequested = true; - return this.onRequestFallback(args); - } - - /** - * @desc Validate settings - * @abstract - */ - validateSettings() { - throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`); - } - - /** - * @desc Add a sub kernel to the root kernel instance. - * This is what `createKernelMap` uses. - * - * @param {ISubKernel} subKernel - function (as a String) of the subKernel to add - */ - addSubKernel(subKernel) { - if (this.subKernels === null) { - this.subKernels = []; - } - if (!subKernel.source) throw new Error('subKernel missing "source" property'); - if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property'); - if (!subKernel.name) throw new Error('subKernel missing "name" property'); - this.subKernels.push(subKernel); - return this; - } - - /** - * @desc Destroys all memory associated with this kernel - * @param {Boolean} [removeCanvasReferences] remove any associated canvas references - */ - destroy(removeCanvasReferences) { - throw new Error(`"destroy" called on ${ this.constructor.name }`); - } - - /** - * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4 - * @param value - * @returns {number} - */ - getBitRatio(value) { - if (this.precision === 'single') { - // 8 and 16 are upconverted to float32 - return 4; - } else if (Array.isArray(value[0])) { - return this.getBitRatio(value[0]); - } else if (value.constructor === Input) { - return this.getBitRatio(value.value); - } - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - return 1; - case Uint16Array: - case Int16Array: - return 2; - case Float32Array: - case Int32Array: - default: - return 4; - } - } - - /** - * @returns {number[]} - */ - getPixels() { - throw new Error(`"getPixels" called on ${ this.constructor.name }`); - } - - checkOutput() { - if (!this.output || !utils.isArray(this.output)) throw new Error('kernel.output not an array'); - if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value'); - for (let i = 0; i < this.output.length; i++) { - if (isNaN(this.output[i]) || this.output[i] < 1) { - throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`); - } - } - } - - toJSON() { - const settings = { - output: this.output, - threadDim: this.threadDim, - pipeline: this.pipeline, - argumentNames: this.argumentNames, - argumentsTypes: this.argumentTypes, - constants: this.constants, - pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null, - returnType: this.returnType, - }; - return { - settings - }; - } -} - -module.exports = { - Kernel -}; \ No newline at end of file +import { Input } from '../input'; +import { + functionToIFunction, + getArgumentNamesFromString, + isArray, + isFunctionString, + warnDeprecated +} from '../common'; +import { getVariableType } from '../utils'; + +export class Kernel { + /** + * @type {Boolean} + */ + static get isSupported() { + throw new Error(`"isSupported" not implemented on ${ this.name }`); + } + + /** + * @type {Boolean} + */ + static isContextMatch(context) { + throw new Error(`"isContextMatch" not implemented on ${ this.name }`); + } + + /** + * @type {IKernelFeatures} + * Used internally to populate the kernel.feature, which is a getter for the output of this value + */ + static getFeatures() { + throw new Error(`"getFeatures" not implemented on ${ this.name }`); + } + + static destroyContext(context) { + throw new Error(`"destroyContext" called on ${ this.name }`); + } + + static nativeFunctionArguments() { + throw new Error(`"nativeFunctionArguments" called on ${ this.name }`); + } + + static nativeFunctionReturnType() { + throw new Error(`"nativeFunctionReturnType" called on ${ this.name }`); + } + + static combineKernels() { + throw new Error(`"combineKernels" called on ${ this.name }`); + } + + /** + * + * @param {string|object} source + * @param [settings] + */ + constructor(source, settings) { + if (typeof source !== 'object') { + if (typeof source !== 'string') { + throw new Error('source not a string'); + } + if (!isFunctionString(source)) { + throw new Error('source not a function string'); + } + } + this.useLegacyEncoder = false; + this.fallbackRequested = false; + this.onRequestFallback = null; + + /** + * Name of the arguments found from parsing source argument + * @type {String[]} + */ + this.argumentNames = typeof source === 'string' ? getArgumentNamesFromString(source) : null; + this.argumentTypes = null; + this.argumentSizes = null; + this.argumentBitRatios = null; + this.kernelArguments = null; + this.kernelConstants = null; + + + /** + * The function source + * @type {String} + */ + this.source = source; + + /** + * The size of the kernel's output + * @type {Number[]} + */ + this.output = null; + + /** + * Debug mode + * @type {Boolean} + */ + this.debug = false; + + /** + * Graphical mode + * @type {Boolean} + */ + this.graphical = false; + + /** + * Maximum loops when using argument values to prevent infinity + * @type {Number} + */ + this.loopMaxIterations = 0; + + /** + * Constants used in kernel via `this.constants` + * @type {Object} + */ + this.constants = null; + this.constantTypes = null; + this.constantBitRatios = null; + this.dynamicArguments = false; + this.dynamicOutput = false; + + /** + * + * @type {Object} + */ + this.canvas = null; + + /** + * + * @type {WebGLRenderingContext} + */ + this.context = null; + + /** + * + * @type {Boolean} + */ + this.checkContext = null; + + /** + * + * @type {GPU} + */ + this.gpu = null; + + /** + * + * @type {IGPUFunction[]} + */ + this.functions = null; + + /** + * + * @type {IGPUNativeFunction[]} + */ + this.nativeFunctions = null; + + /** + * + * @type {String} + */ + this.injectedNative = null; + + /** + * + * @type {ISubKernel[]} + */ + this.subKernels = null; + + /** + * + * @type {Boolean} + */ + this.validate = true; + + /** + * Enforces kernel to write to a new array or texture on run + * @type {Boolean} + */ + this.immutable = false; + + /** + * Enforces kernel to write to a texture on run + * @type {Boolean} + */ + this.pipeline = false; + + /** + * Make GPU use single precison or unsigned. Acceptable values: 'single' or 'unsigned' + * @type {String|null} + * @enum 'single' | 'unsigned' + */ + this.precision = null; + + /** + * + * @type {String|null} + * @enum 'speed' | 'balanced' | 'precision' + */ + this.tactic = 'balanced'; + + this.plugins = null; + + this.returnType = null; + this.leadingReturnStatement = null; + this.followingReturnStatement = null; + this.optimizeFloatMemory = null; + this.strictIntegers = false; + this.fixIntegerDivisionAccuracy = null; + this.warnVarUsage = true; + } + + mergeSettings(settings) { + for (let p in settings) { + if (!settings.hasOwnProperty(p) || !this.hasOwnProperty(p)) continue; + switch (p) { + case 'output': + if (!Array.isArray(settings.output)) { + this.setOutput(settings.output); // Flatten output object + continue; + } + break; + case 'functions': + if (typeof settings.functions[0] === 'function') { + this.functions = settings.functions.map(source => functionToIFunction(source)); + continue; + } + break; + case 'graphical': + if (settings[p] && !settings.hasOwnProperty('precision')) { + this.precision = 'unsigned'; + } + this[p] = settings[p]; + continue; + } + this[p] = settings[p]; + } + + if (!this.canvas) this.canvas = this.initCanvas(); + if (!this.context) this.context = this.initContext(); + if (!this.plugins) this.plugins = this.initPlugins(settings); + } + /** + * @desc Builds the Kernel, by compiling Fragment and Vertical Shaders, + * and instantiates the program. + * @abstract + */ + build() { + throw new Error(`"build" not defined on ${ this.constructor.name }`); + } + + /** + * @desc Run the kernel program, and send the output to renderOutput + *

This method calls a helper method *renderOutput* to return the result.

+ * @returns {Float32Array|Float32Array[]|Float32Array[][]|void} Result The final output of the program, as float, and as Textures for reuse. + * @abstract + */ + run() { + throw new Error(`"run" not defined on ${ this.constructor.name }`) + } + + /** + * @abstract + * @return {Object} + */ + initCanvas() { + throw new Error(`"initCanvas" not defined on ${ this.constructor.name }`); + } + + /** + * @abstract + * @return {Object} + */ + initContext() { + throw new Error(`"initContext" not defined on ${ this.constructor.name }`); + } + + /** + * @param {IFunctionSettings} settings + * @return {Object}; + * @abstract + */ + initPlugins(settings) { + throw new Error(`"initPlugins" not defined on ${ this.constructor.name }`); + } + + /** + * @desc Setup the parameter types for the parameters + * supplied to the Kernel function + * + * @param {IArguments} args - The actual parameters sent to the Kernel + */ + setupArguments(args) { + this.kernelArguments = []; + if (!this.argumentTypes) { + if (!this.argumentTypes) { + this.argumentTypes = []; + for (let i = 0; i < args.length; i++) { + const argType = getVariableType(args[i], this.strictIntegers); + const type = argType === 'Integer' ? 'Number' : argType; + this.argumentTypes.push(type); + this.kernelArguments.push({ + type + }); + } + } + } else { + for (let i = 0; i < this.argumentTypes.length; i++) { + this.kernelArguments.push({ + type: this.argumentTypes[i] + }); + } + } + + // setup sizes + this.argumentSizes = new Array(args.length); + this.argumentBitRatios = new Int32Array(args.length); + + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + this.argumentSizes[i] = arg.constructor === Input ? arg.size : null; + this.argumentBitRatios[i] = this.getBitRatio(arg); + } + + if (this.argumentNames.length !== args.length) { + throw new Error(`arguments are miss-aligned`); + } + } + + /** + * Setup constants + */ + setupConstants() { + this.kernelConstants = []; + let needsConstantTypes = this.constantTypes === null; + if (needsConstantTypes) { + this.constantTypes = {}; + } + this.constantBitRatios = {}; + if (this.constants) { + for (let name in this.constants) { + if (needsConstantTypes) { + const type = getVariableType(this.constants[name], this.strictIntegers); + this.constantTypes[name] = type; + this.kernelConstants.push({ + name, + type + }); + } else { + this.kernelConstants.push({ + name, + type: this.constantTypes[name] + }); + } + this.constantBitRatios[name] = this.getBitRatio(this.constants[name]); + } + } + } + + /** + * + * @param flag + * @return {Kernel} + */ + setOptimizeFloatMemory(flag) { + this.optimizeFloatMemory = flag; + return this; + } + + /** + * @desc Set output dimensions of the kernel function + * @param {Array|Object} output - The output array to set the kernel output size to + */ + setOutput(output) { + if (output.hasOwnProperty('x')) { + if (output.hasOwnProperty('y')) { + if (output.hasOwnProperty('z')) { + this.output = [output.x, output.y, output.z]; + } else { + this.output = [output.x, output.y]; + } + } else { + this.output = [output.x]; + } + } else { + this.output = output; + } + return this; + } + + /** + * @desc Toggle debug mode + * @param {Boolean} flag - true to enable debug + */ + setDebug(flag) { + this.debug = flag; + return this; + } + + /** + * @desc Toggle graphical output mode + * @param {Boolean} flag - true to enable graphical output + */ + setGraphical(flag) { + this.graphical = flag; + this.precision = 'unsigned'; + return this; + } + + /** + * @desc Set the maximum number of loop iterations + * @param {number} max - iterations count + * + */ + setLoopMaxIterations(max) { + this.loopMaxIterations = max; + return this; + } + + /** + * @desc Set Constants + */ + setConstants(constants) { + this.constants = constants; + return this; + } + + /** + * + * @param [IKernelValueTypes] constantTypes + * @return {Kernel} + */ + setConstantTypes(constantTypes) { + this.constantTypes = constantTypes; + return this; + } + + /** + * + * @param {IFunction[]|KernelFunction[]} functions + * @return {Kernel} + */ + setFunctions(functions) { + if (typeof functions[0] === 'function') { + this.functions = functions.map(source => functionToIFunction(source)); + } else { + this.functions = functions; + } + return this; + } + + /** + * + * @param {IGPUNativeFunction} nativeFunctions + * @return {Kernel} + */ + setNativeFunctions(nativeFunctions) { + this.nativeFunctions = nativeFunctions; + return this; + } + + /** + * + * @param {String} injectedNative + * @return {Kernel} + */ + setInjectedNative(injectedNative) { + this.injectedNative = injectedNative; + return this; + } + + /** + * Set writing to texture on/off + * @param flag + * @return {Kernel} + */ + setPipeline(flag) { + this.pipeline = flag; + return this; + } + + /** + * Set precision to 'unsigned' or 'single' + * @param {String} flag 'unsigned' or 'single' + * @return {Kernel} + */ + setPrecision(flag) { + this.precision = flag; + return this; + } + + /** + * @param flag + * @return {Kernel} + * @deprecated + */ + setOutputToTexture(flag) { + warnDeprecated('method', 'setOutputToTexture', 'setPipeline'); + this.pipeline = flag; + return this; + } + + /** + * Set to immutable + * @param flag + * @return {Kernel} + */ + setImmutable(flag) { + this.immutable = flag; + return this; + } + + /** + * @desc Bind the canvas to kernel + * @param {Object} canvas + */ + setCanvas(canvas) { + this.canvas = canvas; + return this; + } + + /** + * @param {Boolean} flag + * @return {Kernel} + */ + setStrictIntegers(flag) { + this.strictIntegers = flag; + return this; + } + + /** + * + * @param flag + * @return {Kernel} + */ + setDynamicOutput(flag) { + this.dynamicOutput = flag; + return this; + } + + /** + * @deprecated + * @param flag + * @return {Kernel} + */ + setHardcodeConstants(flag) { + warnDeprecated('method', 'setHardcodeConstants'); + this.setDynamicOutput(flag); + this.setDynamicArguments(flag); + return this; + } + + /** + * + * @param flag + * @return {Kernel} + */ + setDynamicArguments(flag) { + this.dynamicArguments = flag; + return this; + } + + /** + * @param {Boolean} flag + * @return {Kernel} + */ + setUseLegacyEncoder(flag) { + this.useLegacyEncoder = flag; + return this; + } + + /** + * + * @param {Boolean} flag + * @return {Kernel} + */ + setWarnVarUsage(flag) { + this.warnVarUsage = flag; + return this; + } + + /** + * @deprecated + * @returns {Object} + */ + getCanvas() { + warnDeprecated('method', 'getCanvas'); + return this.canvas; + } + + /** + * @deprecated + * @returns {Object} + */ + getWebGl() { + warnDeprecated('method', 'getWebGl'); + return this.context; + } + + /** + * @desc Bind the webGL instance to kernel + * @param {WebGLRenderingContext} context - webGl instance to bind + */ + setContext(context) { + this.context = context; + return this; + } + + /** + * + * @param [IKernelValueTypes|GPUVariableType[]] argumentTypes + * @return {Kernel} + */ + setArgumentTypes(argumentTypes) { + if (Array.isArray(argumentTypes)) { + this.argumentTypes = argumentTypes; + } else { + this.argumentTypes = []; + for (const p in argumentTypes) { + const argumentIndex = this.argumentNames.indexOf(p); + if (argumentIndex === -1) throw new Error(`unable to find argument ${ p }`); + this.argumentTypes[argumentIndex] = argumentTypes[p]; + } + } + return this; + } + + /** + * + * @param [Tactic] tactic + * @return {Kernel} + */ + setTactic(tactic) { + this.tactic = tactic; + return this; + } + + requestFallback(args) { + if (!this.onRequestFallback) { + throw new Error(`"onRequestFallback" not defined on ${ this.constructor.name }`); + } + this.fallbackRequested = true; + return this.onRequestFallback(args); + } + + /** + * @desc Validate settings + * @abstract + */ + validateSettings() { + throw new Error(`"validateSettings" not defined on ${ this.constructor.name }`); + } + + /** + * @desc Add a sub kernel to the root kernel instance. + * This is what `createKernelMap` uses. + * + * @param {ISubKernel} subKernel - function (as a String) of the subKernel to add + */ + addSubKernel(subKernel) { + if (this.subKernels === null) { + this.subKernels = []; + } + if (!subKernel.source) throw new Error('subKernel missing "source" property'); + if (!subKernel.property && isNaN(subKernel.property)) throw new Error('subKernel missing "property" property'); + if (!subKernel.name) throw new Error('subKernel missing "name" property'); + this.subKernels.push(subKernel); + return this; + } + + /** + * @desc Destroys all memory associated with this kernel + * @param {Boolean} [removeCanvasReferences] remove any associated canvas references + */ + destroy(removeCanvasReferences) { + throw new Error(`"destroy" called on ${ this.constructor.name }`); + } + + /** + * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4 + * @param value + * @returns {number} + */ + getBitRatio(value) { + if (this.precision === 'single') { + // 8 and 16 are upconverted to float32 + return 4; + } else if (Array.isArray(value[0])) { + return this.getBitRatio(value[0]); + } else if (value.constructor === Input) { + return this.getBitRatio(value.value); + } + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + return 1; + case Uint16Array: + case Int16Array: + return 2; + case Float32Array: + case Int32Array: + default: + return 4; + } + } + + /** + * @returns {number[]} + */ + getPixels() { + throw new Error(`"getPixels" called on ${ this.constructor.name }`); + } + + checkOutput() { + if (!this.output || !isArray(this.output)) throw new Error('kernel.output not an array'); + if (this.output.length < 1) throw new Error('kernel.output is empty, needs at least 1 value'); + for (let i = 0; i < this.output.length; i++) { + if (isNaN(this.output[i]) || this.output[i] < 1) { + throw new Error(`${ this.constructor.name }.output[${ i }] incorrectly defined as \`${ this.output[i] }\`, needs to be numeric, and greater than 0`); + } + } + } + + toJSON() { + const settings = { + output: this.output, + threadDim: this.threadDim, + pipeline: this.pipeline, + argumentNames: this.argumentNames, + argumentsTypes: this.argumentTypes, + constants: this.constants, + pluginNames: this.plugins ? this.plugins.map(plugin => plugin.name) : null, + returnType: this.returnType, + }; + return { + settings + }; + } +} diff --git a/src/backend/web-gl/fragment-shader.js b/src/backend/web-gl/fragment-shader.js index e281035a..5d8f0366 100644 --- a/src/backend/web-gl/fragment-shader.js +++ b/src/backend/web-gl/fragment-shader.js @@ -1,407 +1,403 @@ -// language=GLSL -const fragmentShader = `__HEADER__; -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -const int LOOP_MAX = __LOOP_MAX__; - -__PLUGINS__; -__CONSTANTS__; - -varying vec2 vTexCoord; - -vec4 round(vec4 x) { - return floor(x + 0.5); -} - -float round(float x) { - return floor(x + 0.5); -} - -const int BIT_COUNT = 32; -int modi(int x, int y) { - return x - y * (x / y); -} - -int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; -} -int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; -} -int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; - } - } - return result; -} -int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; -} -int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); -} - -int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); -} - -int integerMod(int x, int y) { - return x - (y * int(x / y)); -} - -__DIVIDE_WITH_INTEGER_CHECK__; - -// Here be dragons! -// DO NOT OPTIMIZE THIS CODE -// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE -// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME -const vec2 MAGIC_VEC = vec2(1.0, -256.0); -const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); -const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 -float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; -} - -float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; - if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; - return 0.0; -} - -float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - if (channel == 0) return texel.r * 255.0; - if (channel == 1) return texel.g * 255.0; - if (channel == 2) return texel.b * 255.0; - if (channel == 3) return texel.a * 255.0; - return 0.0; -} - -vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; -} - -// https://github.com/gpujs/gpu.js/wiki/Encoder-details -vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; -} -// Dragons end here - -int index; -ivec3 threadId; - -ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); -} - -float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return decode32(texel); -} - -float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); -} - -float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); -} - -float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return texel.r; - if (channel == 1) return texel.g; - if (channel == 2) return texel.b; - if (channel == 3) return texel.a; - return 0.0; -} - -vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture2D(tex, st / vec2(texSize)); -} - -float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; -} - -vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); -} - -vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); -} - -vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); -} - -vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); - } - } -} - -vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); -} - -vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture2D(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); -} - -vec4 actualColor; -void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); -} - -void color(float r, float g, float b) { - color(r,g,b,1.0); -} - -void color(sampler2D image) { - actualColor = texture2D(image, vTexCoord); -} - -__INJECTED_NATIVE__; -__MAIN_CONSTANTS__; -__MAIN_ARGUMENTS__; -__KERNEL__; - -void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; -}`; - -module.exports = { - fragmentShader -}; \ No newline at end of file +// language=GLSL +export const fragmentShader = `__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +varying vec2 vTexCoord; + +vec4 round(vec4 x) { + return floor(x + 0.5); +} + +float round(float x) { + return floor(x + 0.5); +} + +const int BIT_COUNT = 32; +int modi(int x, int y) { + return x - y * (x / y); +} + +int bitwiseOr(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseXOR(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseAnd(int a, int b) { + int result = 0; + int n = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 && b > 0)) { + break; + } + } + return result; +} +int bitwiseNot(int a) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if (modi(a, 2) == 0) { + result += n; + } + a = a / 2; + n = n * 2; + } + return result; +} +int bitwiseZeroFillLeftShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n *= 2; + } + + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +int bitwiseSignedRightShift(int num, int shifts) { + return int(floor(float(num) / pow(2.0, float(shifts)))); +} + +int bitwiseZeroFillRightShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n /= 2; + } + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +vec2 integerMod(vec2 x, float y) { + vec2 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec3 integerMod(vec3 x, float y) { + vec3 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec4 integerMod(vec4 x, vec4 y) { + vec4 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +float integerMod(float x, float y) { + float res = floor(mod(x, y)); + return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); +} + +int integerMod(int x, int y) { + return x - (y * int(x / y)); +} + +__DIVIDE_WITH_INTEGER_CHECK__; + +// Here be dragons! +// DO NOT OPTIMIZE THIS CODE +// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE +// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME +const vec2 MAGIC_VEC = vec2(1.0, -256.0); +const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); +const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 +float decode32(vec4 texel) { + __DECODE32_ENDIANNESS__; + texel *= 255.0; + vec2 gte128; + gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; + gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; + float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); + float res = exp2(round(exponent)); + texel.b = texel.b - 128.0 * gte128.x; + res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; + res *= gte128.y * -2.0 + 1.0; + return res; +} + +float decode16(vec4 texel, int index) { + int channel = integerMod(index, 2); + if (channel == 0) return texel.r * 255.0 + texel.g * 65280.0; + if (channel == 1) return texel.b * 255.0 + texel.a * 65280.0; + return 0.0; +} + +float decode8(vec4 texel, int index) { + int channel = integerMod(index, 4); + if (channel == 0) return texel.r * 255.0; + if (channel == 1) return texel.g * 255.0; + if (channel == 2) return texel.b * 255.0; + if (channel == 3) return texel.a * 255.0; + return 0.0; +} + +vec4 legacyEncode32(float f) { + float F = abs(f); + float sign = f < 0.0 ? 1.0 : 0.0; + float exponent = floor(log2(F)); + float mantissa = (exp2(-exponent) * F); + // exponent += floor(log2(mantissa)); + vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; + texel.rg = integerMod(texel.rg, 256.0); + texel.b = integerMod(texel.b, 128.0); + texel.a = exponent*0.5 + 63.5; + texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; + texel = floor(texel); + texel *= 0.003921569; // 1/255 + __ENCODE32_ENDIANNESS__; + return texel; +} + +// https://github.com/gpujs/gpu.js/wiki/Encoder-details +vec4 encode32(float value) { + if (value == 0.0) return vec4(0, 0, 0, 0); + + float exponent; + float mantissa; + vec4 result; + float sgn; + + sgn = step(0.0, -value); + value = abs(value); + + exponent = floor(log2(value)); + + mantissa = value*pow(2.0, -exponent)-1.0; + exponent = exponent+127.0; + result = vec4(0,0,0,0); + + result.a = floor(exponent/2.0); + exponent = exponent - result.a*2.0; + result.a = result.a + 128.0*sgn; + + result.b = floor(mantissa * 128.0); + mantissa = mantissa - result.b / 128.0; + result.b = result.b + exponent*128.0; + + result.g = floor(mantissa*32768.0); + mantissa = mantissa - result.g/32768.0; + + result.r = floor(mantissa*8388608.0); + return result/255.0; +} +// Dragons end here + +int index; +ivec3 threadId; + +ivec3 indexTo3D(int idx, ivec3 texDim) { + int z = int(idx / (texDim.x * texDim.y)); + idx -= z * int(texDim.x * texDim.y); + int y = int(idx / texDim.x); + int x = int(integerMod(idx, texDim.x)); + return ivec3(x, y, z); +} + +float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + return decode32(texel); +} + +float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x * 2; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize.x * 2, texSize.y)); + return decode16(texel, index); +} + +float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x * 4; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize.x * 4, texSize.y)); + return decode8(texel, index); +} + +float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 4); + index = index / 4; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + if (channel == 0) return texel.r; + if (channel == 1) return texel.g; + if (channel == 2) return texel.b; + if (channel == 3) return texel.a; + return 0.0; +} + +vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture2D(tex, st / vec2(texSize)); +} + +float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return result[0]; +} + +vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec2(result[0], result[1]); +} + +vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int channel = integerMod(index, 2); + index = index / 2; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + if (channel == 0) return vec2(texel.r, texel.g); + if (channel == 1) return vec2(texel.b, texel.a); + return vec2(0.0, 0.0); +} + +vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec3(result[0], result[1], result[2]); +} + +vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); + int vectorIndex = fieldIndex / 4; + int vectorOffset = fieldIndex - vectorIndex * 4; + int readY = vectorIndex / texSize.x; + int readX = vectorIndex - readY * texSize.x; + vec4 tex1 = texture2D(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); + + if (vectorOffset == 0) { + return tex1.xyz; + } else if (vectorOffset == 1) { + return tex1.yzw; + } else { + readX++; + if (readX >= texSize.x) { + readX = 0; + readY++; + } + vec4 tex2 = texture2D(tex, vec2(readX, readY) / vec2(texSize)); + if (vectorOffset == 2) { + return vec3(tex1.z, tex1.w, tex2.x); + } else { + return vec3(tex1.w, tex2.x, tex2.y); + } + } +} + +vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + return getImage2D(tex, texSize, texDim, z, y, x); +} + +vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture2D(tex, st / vec2(texSize)); + return vec4(texel.r, texel.g, texel.b, texel.a); +} + +vec4 actualColor; +void color(float r, float g, float b, float a) { + actualColor = vec4(r,g,b,a); +} + +void color(float r, float g, float b) { + color(r,g,b,1.0); +} + +void color(sampler2D image) { + actualColor = texture2D(image, vTexCoord); +} + +__INJECTED_NATIVE__; +__MAIN_CONSTANTS__; +__MAIN_ARGUMENTS__; +__KERNEL__; + +void main(void) { + index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; + __MAIN_RESULT__; +}`; diff --git a/src/backend/web-gl/function-node.js b/src/backend/web-gl/function-node.js index bac93d1b..79e5b8a6 100644 --- a/src/backend/web-gl/function-node.js +++ b/src/backend/web-gl/function-node.js @@ -1,1537 +1,1530 @@ -const { utils } = require('../../utils'); -const { FunctionNode } = require('../function-node'); -// Closure capture for the ast function, prevent collision with existing AST functions -// The prefixes to use -const jsMathPrefix = 'Math.'; -const localPrefix = 'this.'; - -/** - * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code - * @extends FunctionNode - * @returns the converted WebGL function string - */ -class WebGLFunctionNode extends FunctionNode { - constructor(source, settings) { - super(source, settings); - if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { - this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; - } - } - - /** - * @desc Parses the abstract syntax tree for to its *named function* - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astFunction(ast, retArr) { - // Setup function return type and name - if (this.isRootKernel) { - retArr.push('void'); - } else { - // looking up return type, this is a little expensive, and can be avoided if returnType is set - let lastReturn = null; - if (!this.returnType) { - const lastReturn = this.findLastReturn(); - if (lastReturn) { - this.returnType = this.getType(ast.body); - if (this.returnType === 'LiteralInteger') { - this.returnType = 'Number'; - } - } - } - - const { returnType } = this; - if (!returnType) { - retArr.push('void'); - } else { - const type = typeMap[returnType]; - if (!type) { - throw new Error(`unknown type ${returnType}`); - } - retArr.push(type); - } - } - retArr.push(' '); - retArr.push(this.name); - retArr.push('('); - - if (!this.isRootKernel) { - // Arguments handling - for (let i = 0; i < this.argumentNames.length; ++i) { - const argumentName = this.argumentNames[i]; - - if (i > 0) { - retArr.push(', '); - } - let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; - // The type is too loose ended, here we descide to solidify a type, lets go with float - if (!argumentType) { - throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast); - } - if (argumentType === 'LiteralInteger') { - this.argumentTypes[i] = argumentType = 'Number'; - } - const type = typeMap[argumentType]; - if (!type) { - throw this.astErrorOutput('Unexpected expression', ast); - } - - if (type === 'sampler2D' || type === 'sampler2DArray') { - // mash needed arguments together, since now we have end to end inference - retArr.push(`${type} user_${argumentName},ivec2 user_${argumentName}Size,ivec3 user_${argumentName}Dim`); - } else { - retArr.push(`${type} user_${argumentName}`); - } - } - } - - // Function opening - retArr.push(') {\n'); - - // Body statement iteration - for (let i = 0; i < ast.body.body.length; ++i) { - this.astGeneric(ast.body.body[i], retArr); - retArr.push('\n'); - } - - // Function closing - retArr.push('}\n'); - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for to *return* statement - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astReturnStatement(ast, retArr) { - if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast); - this.pushState('skip-literal-correction'); - const type = this.getType(ast.argument); - this.popState('skip-literal-correction'); - - const result = []; - - if (!this.returnType) { - if (type === 'LiteralInteger' || type === 'Integer') { - this.returnType = 'Number'; - } else { - this.returnType = type; - } - } - - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Float': - switch (type) { - case 'Integer': - result.push('float('); - this.astGeneric(ast.argument, result); - result.push(')'); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.argument, result); - - // Running astGeneric forces the LiteralInteger to pick a type, and here, if we are returning a float, yet - // the LiteralInteger has picked to be an integer because of constraints on it we cast it to float. - if (this.getType(ast) === 'Integer') { - result.unshift('float('); - result.push(')'); - } - break; - default: - this.astGeneric(ast.argument, result); - } - break; - case 'Integer': - switch (type) { - case 'Float': - case 'Number': - this.castValueToInteger(ast.argument, result); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.argument, result); - break; - default: - this.astGeneric(ast.argument, result); - } - break; - case 'Array(4)': - case 'Array(3)': - case 'Array(2)': - case 'Input': - this.astGeneric(ast.argument, result); - break; - default: - throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); - } - - if (this.isRootKernel) { - retArr.push(`kernelResult = ${ result.join('') };`); - retArr.push('return;'); - } else if (this.isSubKernel) { - retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`); - retArr.push(`return subKernelResult_${ this.name };`); - } else { - retArr.push(`return ${ result.join('') };`); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *literal value* - * - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * - * @returns {Array} the append retArr - */ - astLiteral(ast, retArr) { - // Reject non numeric literals - if (isNaN(ast.value)) { - throw this.astErrorOutput( - 'Non-numeric literal not supported : ' + ast.value, - ast - ); - } - - const key = `${ast.start},${ast.end}`; - if (Number.isInteger(ast.value)) { - if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) { - this.literalTypes[key] = 'Integer'; - retArr.push(`${ast.value}`); - } else if (this.isState('casting-to-float') || this.isState('building-float')) { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}.0`); - } else { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}.0`); - } - } else if (this.isState('casting-to-integer') || this.isState('building-integer')) { - this.literalTypes[key] = 'Integer'; - retArr.push(Math.round(ast.value)); - } else { - this.literalTypes[key] = 'Number'; - retArr.push(`${ast.value}`); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *binary* expression - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astBinaryExpression(ast, retArr) { - if (this.checkAndUpconvertOperator(ast, retArr)) { - return retArr; - } - - if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { - retArr.push('div_with_int_check('); - this.pushState('building-float'); - switch (this.getType(ast.left)) { - case 'Integer': - this.castValueToFloat(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.left, retArr); - break; - default: - this.astGeneric(ast.left, retArr); - } - retArr.push(', '); - switch (this.getType(ast.right)) { - case 'Integer': - this.castValueToFloat(ast.right, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.right, retArr); - break; - default: - this.astGeneric(ast.right, retArr); - } - this.popState('building-float'); - retArr.push(')'); - return retArr; - } - - retArr.push('('); - const leftType = this.getType(ast.left) || 'Number'; - const rightType = this.getType(ast.right) || 'Number'; - if (!leftType || !rightType) { - throw this.astErrorOutput(`Unhandled binary expression`, ast); - } - const key = leftType + ' & ' + rightType; - switch (key) { - case 'Integer & Integer': - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-integer'); - break; - case 'Number & Float': - case 'Float & Number': - case 'Float & Float': - case 'Number & Number': - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-float'); - break; - case 'LiteralInteger & LiteralInteger': - if (this.isState('casting-to-integer') || this.isState('building-integer')) { - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-integer'); - } else { - this.pushState('building-float'); - this.castLiteralToFloat(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); - this.popState('building-float'); - } - break; - - case 'Integer & Float': - case 'Integer & Number': - if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') { - // if right value is actually a float, don't loose that information, cast left to right rather than the usual right to left - if (!Number.isInteger(ast.right.value)) { - this.pushState('building-float'); - this.castValueToFloat(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-float'); - break; - } - } - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.pushState('casting-to-integer'); - if (ast.right.type === 'Literal') { - const literalResult = []; - this.astGeneric(ast.right, literalResult); - const literalType = this.getType(ast.right); - if (literalType === 'Integer') { - retArr.push(literalResult.join('')); - } else { - throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); - } - } else { - retArr.push('int('); - this.astGeneric(ast.right, retArr); - retArr.push(')'); - } - this.popState('casting-to-integer'); - this.popState('building-integer'); - break; - case 'Integer & LiteralInteger': - this.pushState('building-integer'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToInteger(ast.right, retArr); - this.popState('building-integer'); - break; - - case 'Number & Integer': - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToFloat(ast.right, retArr); - this.popState('building-float'); - break; - case 'Float & LiteralInteger': - case 'Number & LiteralInteger': - if (this.isState('in-for-loop-test')) { - this.pushState('building-integer'); - retArr.push('int('); - this.astGeneric(ast.left, retArr); - retArr.push(')'); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToInteger(ast.right, retArr); - this.popState('building-integer'); - } else { - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castLiteralToFloat(ast.right, retArr); - this.popState('building-float'); - } - break; - case 'LiteralInteger & Float': - case 'LiteralInteger & Number': - if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) { - this.pushState('building-integer'); - this.castLiteralToInteger(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToInteger(ast.right, retArr); - this.popState('building-integer'); - } else { - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.pushState('casting-to-float'); - this.astGeneric(ast.right, retArr); - this.popState('casting-to-float'); - this.popState('building-float'); - } - break; - case 'LiteralInteger & Integer': - this.pushState('building-integer'); - this.castLiteralToInteger(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-integer'); - break; - - case 'Boolean & Boolean': - this.pushState('building-boolean'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.astGeneric(ast.right, retArr); - this.popState('building-boolean'); - break; - - case 'Float & Integer': - this.pushState('building-float'); - this.astGeneric(ast.left, retArr); - retArr.push(operatorMap[ast.operator] || ast.operator); - this.castValueToFloat(ast.right, retArr); - this.popState('building-float'); - break; - - default: - throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); - } - retArr.push(')'); - - return retArr; - } - - checkAndUpconvertOperator(ast, retArr) { - const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); - if (bitwiseResult) { - return bitwiseResult; - } - const upconvertableOperators = { - '%': 'mod', - '**': 'pow', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - switch (this.getType(ast.left)) { - case 'Integer': - this.castValueToFloat(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.left, retArr); - break; - default: - this.astGeneric(ast.left, retArr); - } - retArr.push(','); - switch (this.getType(ast.right)) { - case 'Integer': - this.castValueToFloat(ast.right, retArr); - break; - case 'LiteralInteger': - this.castLiteralToFloat(ast.right, retArr); - break; - default: - this.astGeneric(ast.right, retArr); - } - retArr.push(')'); - return retArr; - } - - checkAndUpconvertBitwiseOperators(ast, retArr) { - const upconvertableOperators = { - '&': 'bitwiseAnd', - '|': 'bitwiseOr', - '^': 'bitwiseXOR', - '<<': 'bitwiseZeroFillLeftShift', - '>>': 'bitwiseSignedRightShift', - '>>>': 'bitwiseZeroFillRightShift', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - const leftType = this.getType(ast.left); - switch (leftType) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.left, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.left, retArr); - break; - default: - this.astGeneric(ast.left, retArr); - } - retArr.push(','); - const rightType = this.getType(ast.right); - switch (rightType) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.right, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.right, retArr); - break; - default: - this.astGeneric(ast.right, retArr); - } - retArr.push(')'); - return retArr; - } - - checkAndUpconvertBitwiseUnary(ast, retArr) { - const upconvertableOperators = { - '~': 'bitwiseNot', - }; - const foundOperator = upconvertableOperators[ast.operator]; - if (!foundOperator) return null; - retArr.push(foundOperator); - retArr.push('('); - switch (this.getType(ast.argument)) { - case 'Number': - case 'Float': - this.castValueToInteger(ast.argument, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(ast.argument, retArr); - break; - default: - this.astGeneric(ast.argument, retArr); - } - retArr.push(')'); - return retArr; - } - - /** - * - * @param {Object} ast - * @param {Array} retArr - * @return {String[]} - */ - castLiteralToInteger(ast, retArr) { - this.pushState('casting-to-integer'); - this.astGeneric(ast, retArr); - this.popState('casting-to-integer'); - return retArr; - } - - /** - * - * @param {Object} ast - * @param {Array} retArr - * @return {String[]} - */ - castLiteralToFloat(ast, retArr) { - this.pushState('casting-to-float'); - this.astGeneric(ast, retArr); - this.popState('casting-to-float'); - return retArr; - } - - /** - * - * @param {Object} ast - * @param {Array} retArr - * @return {String[]} - */ - castValueToInteger(ast, retArr) { - this.pushState('casting-to-integer'); - retArr.push('int('); - this.astGeneric(ast, retArr); - retArr.push(')'); - this.popState('casting-to-integer'); - return retArr; - } - - /** - * - * @param {Object} ast - * @param {Array} retArr - * @return {String[]} - */ - castValueToFloat(ast, retArr) { - this.pushState('casting-to-float'); - retArr.push('float('); - this.astGeneric(ast, retArr); - retArr.push(')'); - this.popState('casting-to-float'); - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *identifier* expression - * @param {Object} idtNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); - } - - const type = this.getType(idtNode); - - if (idtNode.name === 'Infinity') { - // https://stackoverflow.com/a/47543127/1324039 - retArr.push('3.402823466e+38'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${idtNode.name}`); - } - } else { - retArr.push(`user_${idtNode.name}`); - } - - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *for-loop* expression - * @param {Object} forNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the parsed webgl string - */ - astForStatement(forNode, retArr) { - if (forNode.type !== 'ForStatement') { - throw this.astErrorOutput('Invalid for statement', forNode); - } - - const initArr = []; - const testArr = []; - const updateArr = []; - const bodyArr = []; - let isSafe = null; - - if (forNode.init) { - this.pushState('in-for-loop-init'); - this.astGeneric(forNode.init, initArr); - const { declarations } = forNode.init; - for (let i = 0; i < declarations.length; i++) { - if (declarations[i].init && declarations[i].init.type !== 'Literal') { - isSafe = false; - } - } - if (isSafe) { - for (let i = 0; i < initArr.length; i++) { - if (initArr[i].includes && initArr[i].includes(',')) { - isSafe = false; - } - } - } - this.popState('in-for-loop-init'); - } else { - isSafe = false; - } - - if (forNode.test) { - this.pushState('in-for-loop-test'); - this.astGeneric(forNode.test, testArr); - this.popState('in-for-loop-test'); - } else { - isSafe = false; - } - - if (forNode.update) { - this.astGeneric(forNode.update, updateArr); - } else { - isSafe = false; - } - - if (forNode.body) { - this.pushState('loop-body'); - this.astGeneric(forNode.body, bodyArr); - this.popState('loop-body'); - } - - // have all parts, now make them safe - if (isSafe === null) { - isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); - } - - if (isSafe) { - retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); - retArr.push(bodyArr.join('')); - retArr.push('}\n'); - } else { - const iVariableName = this.getInternalVariableName('safeI'); - if (initArr.length > 0) { - retArr.push(initArr.join(''), ';\n'); - } - retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) { - retArr.push(`if (!${testArr.join('')}) break;\n`); - } - retArr.push(bodyArr.join('')); - retArr.push(`\n${updateArr.join('')};`); - retArr.push('}\n'); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *while* loop - * @param {Object} whileNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the parsed webgl string - */ - astWhileStatement(whileNode, retArr) { - if (whileNode.type !== 'WhileStatement') { - throw this.astErrorOutput('Invalid while statement', whileNode); - } - - const iVariableName = this.getInternalVariableName('safeI'); - retArr.push(`for (int ${iVariableName}=0;${iVariableName} i + 1) { - movingDefaultToEnd = true; - this.astGeneric(cases[i].consequent, defaultResult); - continue; - } else { - retArr.push(' else {\n'); - } - } else { - // all others - if (i === 0 || !pastFirstIf) { - pastFirstIf = true; - retArr.push(`if (${varName} == `); - } else { - if (fallingThrough) { - retArr.push(`${varName} == `); - fallingThrough = false; - } else { - retArr.push(` else if (${varName} == `); - } - } - if (type === 'Integer') { - const testType = this.getType(cases[i].test); - switch (testType) { - case 'Number': - case 'Float': - this.castValueToInteger(cases[i].test, retArr); - break; - case 'LiteralInteger': - this.castLiteralToInteger(cases[i].test, retArr); - break; - } - } else if (type === 'Float') { - const testType = this.getType(cases[i].test); - switch (testType) { - case 'LiteralInteger': - this.castLiteralToFloat(cases[i].test, retArr); - break; - case 'Integer': - this.castValueToFloat(cases[i].test, retArr); - break; - } - } else { - throw new Error('unhanlded'); - } - if (!cases[i].consequent || cases[i].consequent.length === 0) { - fallingThrough = true; - retArr.push(' || '); - continue; - } - retArr.push(`) {\n`); - } - this.astGeneric(cases[i].consequent, retArr); - retArr.push('\n}'); - } - if (movingDefaultToEnd) { - retArr.push(' else {'); - retArr.push(defaultResult.join('')); - retArr.push('}'); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *This* expression - * @param {Object} tNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astThisExpression(tNode, retArr) { - retArr.push('this'); - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *Member* Expression - * @param {Object} mNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astMemberExpression(mNode, retArr) { - const { - property, - name, - signature, - origin, - type, - xProperty, - yProperty, - zProperty - } = this.getMemberExpressionDetails(mNode); - switch (signature) { - case 'value.thread.value': - case 'this.thread.value': - if (name !== 'x' && name !== 'y' && name !== 'z') { - throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode); - } - retArr.push(`threadId.${name}`); - return retArr; - case 'this.output.value': - if (this.dynamicOutput) { - switch (name) { - case 'x': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.x)'); - } else { - retArr.push('uOutputDim.x'); - } - break; - case 'y': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.y)'); - } else { - retArr.push('uOutputDim.y'); - } - break; - case 'z': - if (this.isState('casting-to-float')) { - retArr.push('float(uOutputDim.z)'); - } else { - retArr.push('uOutputDim.z'); - } - break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - } else { - switch (name) { - case 'x': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[0]); - } else { - retArr.push(this.output[0], '.0'); - } - break; - case 'y': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[1]); - } else { - retArr.push(this.output[1], '.0'); - } - break; - case 'z': - if (this.isState('casting-to-integer')) { - retArr.push(this.output[2]); - } else { - retArr.push(this.output[2], '.0'); - } - break; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - } - return retArr; - case 'value': - throw this.astErrorOutput('Unexpected expression', mNode); - case 'value[]': - case 'value[][]': - case 'value[][][]': - case 'value[][][][]': - case 'value.value': - if (origin === 'Math') { - retArr.push(Math[name]); - return retArr; - } - switch (property) { - case 'r': - retArr.push(`user_${ name }.r`); - return retArr; - case 'g': - retArr.push(`user_${ name }.g`); - return retArr; - case 'b': - retArr.push(`user_${ name }.b`); - return retArr; - case 'a': - retArr.push(`user_${ name }.a`); - return retArr; - } - break; - case 'this.constants.value': - if (typeof xProperty === 'undefined') { - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - retArr.push(`constants_${ name }`); - return retArr; - } - } - case 'this.constants.value[]': - case 'this.constants.value[][]': - case 'this.constants.value[][][]': - case 'this.constants.value[][][][]': - break; - case 'fn()[]': - this.astCallExpression(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(property)); - retArr.push(']'); - return retArr; - case '[][]': - this.astArrayExpression(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(property)); - retArr.push(']'); - return retArr; - default: - throw this.astErrorOutput('Unexpected expression', mNode); - } - - if (mNode.computed === false) { - // handle simple types - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'Boolean': - retArr.push(`${origin}_${name}`); - return retArr; - } - } - - // handle more complex types - // argument may have come from a parent - const markupName = `${origin}_${name}`; - - switch (type) { - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - // Get from local vec4 - this.astGeneric(mNode.object, retArr); - retArr.push('['); - retArr.push(this.memberExpressionPropertyMarkup(xProperty)); - retArr.push(']'); - break; - case 'HTMLImageArray': - retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(1)': - retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(2)': - case 'Array2D(2)': - case 'Array3D(2)': - retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(2)': - retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(3)': - case 'Array2D(3)': - case 'Array3D(3)': - retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(3)': - retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'Array1D(4)': - case 'Array2D(4)': - case 'Array3D(4)': - retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'ArrayTexture(4)': - case 'HTMLImage': - case 'HTMLVideo': - retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - case 'NumberTexture': - case 'Array': - case 'Array2D': - case 'Array3D': - case 'Array4D': - case 'Input': - case 'Number': - case 'Float': - case 'Integer': - if (this.precision === 'single') { - // bitRatio is always 4 here, javascript doesn't yet have 8 or 16 bit support - // TODO: make 8 or 16 bit work anyway! - retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - } else { - const bitRatio = (origin === 'user' ? - this.lookupFunctionArgumentBitRatio(this.name, name) : - this.constantBitRatios[name] - ); - switch (bitRatio) { - case 1: - retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - case 2: - retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - case 4: - case 0: - retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `); - break; - default: - throw new Error(`unhandled bit ratio of ${bitRatio}`); - } - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - } - break; - case 'MemoryOptimizedNumberTexture': - retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); - this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); - retArr.push(')'); - break; - default: - throw new Error(`unhandled member expression "${ type }"`); - } - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *call* expression - * @param {Object} ast - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astCallExpression(ast, retArr) { - if (!ast.callee) { - throw this.astErrorOutput('Unknown CallExpression', ast); - } - - let functionName = null; - const isMathFunction = this.isAstMathFunction(ast); - - // Its a math operator or this.something(), remove the prefix - if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) { - functionName = ast.callee.property.name; - } - // Issue #212, BABEL! - else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) { - functionName = ast.callee.expressions[1].property.name; - } else { - functionName = ast.callee.name; - } - - if (!functionName) { - throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); - } - - // if this if grows to more than one, lets use a switch - if (functionName === 'atan2') { - functionName = 'atan'; - } - - // Register the function into the called registry - if (this.calledFunctions.indexOf(functionName) < 0) { - this.calledFunctions.push(functionName); - } - - if (functionName === 'random' && this.plugins && this.plugins.length > 0) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) { - retArr.push(plugin.functionReplace); - return retArr; - } - } - } - - // track the function was called - if (this.onFunctionCall) { - this.onFunctionCall(this.name, functionName, ast.arguments); - } - - // Call the function - retArr.push(functionName); - - // Open arguments space - retArr.push('('); - - // Add the arguments - if (isMathFunction) { - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - const argumentType = this.getType(argument); - if (i > 0) { - retArr.push(', '); - } - - switch (argumentType) { - case 'Integer': - this.castValueToFloat(argument, retArr); - break; - default: - this.astGeneric(argument, retArr); - break; - } - } - } else { - const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; - for (let i = 0; i < ast.arguments.length; ++i) { - const argument = ast.arguments[i]; - let targetType = targetTypes[i]; - if (i > 0) { - retArr.push(', '); - } - const argumentType = this.getType(argument); - if (!targetType) { - this.triggerImplyArgumentType(functionName, i, argumentType, this); - targetType = argumentType; - } - switch (argumentType) { - case 'Number': - case 'Float': - if (targetType === 'Integer') { - retArr.push('int('); - this.astGeneric(argument, retArr); - retArr.push(')'); - continue; - } else if (targetType === 'Number' || targetType === 'Float') { - this.astGeneric(argument, retArr); - continue; - } else if (targetType === 'LiteralInteger') { - this.castLiteralToFloat(argument, retArr); - continue; - } - break; - case 'Integer': - if (targetType === 'Number' || targetType === 'Float') { - retArr.push('float('); - this.astGeneric(argument, retArr); - retArr.push(')'); - continue; - } else if (targetType === 'Integer') { - this.astGeneric(argument, retArr); - continue; - } - break; - case 'LiteralInteger': - if (targetType === 'Integer') { - this.castLiteralToInteger(argument, retArr); - continue; - } else if (targetType === 'Number' || targetType === 'Float') { - this.castLiteralToFloat(argument, retArr); - continue; - } else if (targetType === 'LiteralInteger') { - this.astGeneric(argument, retArr); - continue; - } - break; - case 'Array(2)': - case 'Array(3)': - case 'Array(4)': - if (targetType === argumentType) { - if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name}`); - continue; - } - break; - case 'HTMLImage': - case 'HTMLImageArray': - case 'HTMLVideo': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - case 'Array': - case 'Input': - if (targetType === argumentType) { - if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); - this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); - retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); - continue; - } - break; - } - throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); - } - } - // Close arguments space - retArr.push(')'); - - return retArr; - } - - /** - * @desc Parses the abstract syntax tree for *Array* Expression - * @param {Object} arrNode - the AST object to parse - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astArrayExpression(arrNode, retArr) { - const arrLen = arrNode.elements.length; - - retArr.push('vec' + arrLen + '('); - for (let i = 0; i < arrLen; ++i) { - if (i > 0) { - retArr.push(', '); - } - const subNode = arrNode.elements[i]; - this.astGeneric(subNode, retArr) - } - retArr.push(')'); - - return retArr; - } - - memberExpressionXYZ(x, y, z, retArr) { - if (z) { - retArr.push(this.memberExpressionPropertyMarkup(z), ', '); - } else { - retArr.push('0, '); - } - if (y) { - retArr.push(this.memberExpressionPropertyMarkup(y), ', '); - } else { - retArr.push('0, '); - } - retArr.push(this.memberExpressionPropertyMarkup(x)); - return retArr; - } - - memberExpressionPropertyMarkup(property) { - if (!property) { - throw new Error('Property not set'); - } - const type = this.getType(property); - const result = []; - switch (type) { - case 'Number': - case 'Float': - this.castValueToInteger(property, result); - break; - case 'LiteralInteger': - this.castLiteralToInteger(property, result); - break; - default: - this.astGeneric(property, result); - } - return result.join(''); - } -} - -const typeMap = { - 'Array': 'sampler2D', - 'Array(2)': 'vec2', - 'Array(3)': 'vec3', - 'Array(4)': 'vec4', - 'Array2D': 'sampler2D', - 'Array3D': 'sampler2D', - 'Boolean': 'bool', - 'Float': 'float', - 'Input': 'sampler2D', - 'Integer': 'int', - 'Number': 'float', - 'LiteralInteger': 'float', - 'NumberTexture': 'sampler2D', - 'MemoryOptimizedNumberTexture': 'sampler2D', - 'ArrayTexture(1)': 'sampler2D', - 'ArrayTexture(2)': 'sampler2D', - 'ArrayTexture(3)': 'sampler2D', - 'ArrayTexture(4)': 'sampler2D', - 'HTMLVideo': 'sampler2D', - 'HTMLImage': 'sampler2D', - 'HTMLImageArray': 'sampler2DArray', -}; - -const operatorMap = { - '===': '==', - '!==': '!=' -}; - -module.exports = { - WebGLFunctionNode -}; \ No newline at end of file +import { utils } from '../../utils'; +import { FunctionNode } from '../function-node'; +// Closure capture for the ast function, prevent collision with existing AST functions +// The prefixes to use +const jsMathPrefix = 'Math.'; +const localPrefix = 'this.'; + +/** + * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective WebGL code + * @extends FunctionNode + * @returns the converted WebGL function string + */ +export class WebGLFunctionNode extends FunctionNode { + constructor(source, settings) { + super(source, settings); + if (settings && settings.hasOwnProperty('fixIntegerDivisionAccuracy')) { + this.fixIntegerDivisionAccuracy = settings.fixIntegerDivisionAccuracy; + } + } + + /** + * @desc Parses the abstract syntax tree for to its *named function* + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astFunction(ast, retArr) { + // Setup function return type and name + if (this.isRootKernel) { + retArr.push('void'); + } else { + // looking up return type, this is a little expensive, and can be avoided if returnType is set + let lastReturn = null; + if (!this.returnType) { + const lastReturn = this.findLastReturn(); + if (lastReturn) { + this.returnType = this.getType(ast.body); + if (this.returnType === 'LiteralInteger') { + this.returnType = 'Number'; + } + } + } + + const { returnType } = this; + if (!returnType) { + retArr.push('void'); + } else { + const type = typeMap[returnType]; + if (!type) { + throw new Error(`unknown type ${returnType}`); + } + retArr.push(type); + } + } + retArr.push(' '); + retArr.push(this.name); + retArr.push('('); + + if (!this.isRootKernel) { + // Arguments handling + for (let i = 0; i < this.argumentNames.length; ++i) { + const argumentName = this.argumentNames[i]; + + if (i > 0) { + retArr.push(', '); + } + let argumentType = this.argumentTypes[this.argumentNames.indexOf(argumentName)]; + // The type is too loose ended, here we descide to solidify a type, lets go with float + if (!argumentType) { + throw this.astErrorOutput(`Unknown argument ${argumentName} type`, ast); + } + if (argumentType === 'LiteralInteger') { + this.argumentTypes[i] = argumentType = 'Number'; + } + const type = typeMap[argumentType]; + if (!type) { + throw this.astErrorOutput('Unexpected expression', ast); + } + retArr.push(type); + retArr.push(' '); + retArr.push('user_'); + retArr.push(argumentName); + } + } + + // Function opening + retArr.push(') {\n'); + + // Body statement iteration + for (let i = 0; i < ast.body.body.length; ++i) { + this.astGeneric(ast.body.body[i], retArr); + retArr.push('\n'); + } + + // Function closing + retArr.push('}\n'); + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for to *return* statement + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astReturnStatement(ast, retArr) { + if (!ast.argument) throw this.astErrorOutput('Unexpected return statement', ast); + this.pushState('skip-literal-correction'); + const type = this.getType(ast.argument); + this.popState('skip-literal-correction'); + + const result = []; + + if (!this.returnType) { + if (type === 'LiteralInteger' || type === 'Integer') { + this.returnType = 'Number'; + } else { + this.returnType = type; + } + } + + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Float': + switch (type) { + case 'Integer': + result.push('float('); + this.astGeneric(ast.argument, result); + result.push(')'); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.argument, result); + + // Running astGeneric forces the LiteralInteger to pick a type, and here, if we are returning a float, yet + // the LiteralInteger has picked to be an integer because of constraints on it we cast it to float. + if (this.getType(ast) === 'Integer') { + result.unshift('float('); + result.push(')'); + } + break; + default: + this.astGeneric(ast.argument, result); + } + break; + case 'Integer': + switch (type) { + case 'Float': + case 'Number': + this.castValueToInteger(ast.argument, result); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, result); + break; + default: + this.astGeneric(ast.argument, result); + } + break; + case 'Array(4)': + case 'Array(3)': + case 'Array(2)': + case 'Input': + this.astGeneric(ast.argument, result); + break; + default: + throw this.astErrorOutput(`unhandled return type ${this.returnType}`, ast); + } + + if (this.isRootKernel) { + retArr.push(`kernelResult = ${ result.join('') };`); + retArr.push('return;'); + } else if (this.isSubKernel) { + retArr.push(`subKernelResult_${ this.name } = ${ result.join('') };`); + retArr.push(`return subKernelResult_${ this.name };`); + } else { + retArr.push(`return ${ result.join('') };`); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *literal value* + * + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * + * @returns {Array} the append retArr + */ + astLiteral(ast, retArr) { + // Reject non numeric literals + if (isNaN(ast.value)) { + throw this.astErrorOutput( + 'Non-numeric literal not supported : ' + ast.value, + ast + ); + } + + const key = `${ast.start},${ast.end}`; + if (Number.isInteger(ast.value)) { + if (this.isState('in-for-loop-init') || this.isState('casting-to-integer') || this.isState('building-integer')) { + this.literalTypes[key] = 'Integer'; + retArr.push(`${ast.value}`); + } else if (this.isState('casting-to-float') || this.isState('building-float')) { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}.0`); + } else { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}.0`); + } + } else if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.literalTypes[key] = 'Integer'; + retArr.push(Math.round(ast.value)); + } else { + this.literalTypes[key] = 'Number'; + retArr.push(`${ast.value}`); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *binary* expression + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astBinaryExpression(ast, retArr) { + if (this.checkAndUpconvertOperator(ast, retArr)) { + return retArr; + } + + if (this.fixIntegerDivisionAccuracy && ast.operator === '/') { + retArr.push('div_with_int_check('); + this.pushState('building-float'); + switch (this.getType(ast.left)) { + case 'Integer': + this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(', '); + switch (this.getType(ast.right)) { + case 'Integer': + this.castValueToFloat(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } + this.popState('building-float'); + retArr.push(')'); + return retArr; + } + + retArr.push('('); + const leftType = this.getType(ast.left) || 'Number'; + const rightType = this.getType(ast.right) || 'Number'; + if (!leftType || !rightType) { + throw this.astErrorOutput(`Unhandled binary expression`, ast); + } + const key = leftType + ' & ' + rightType; + switch (key) { + case 'Integer & Integer': + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-integer'); + break; + case 'Number & Float': + case 'Float & Number': + case 'Float & Float': + case 'Number & Number': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-float'); + break; + case 'LiteralInteger & LiteralInteger': + if (this.isState('casting-to-integer') || this.isState('building-integer')) { + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.castLiteralToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + } + break; + + case 'Integer & Float': + case 'Integer & Number': + if (ast.operator === '>' || ast.operator === '<' && ast.right.type === 'Literal') { + // if right value is actually a float, don't loose that information, cast left to right rather than the usual right to left + if (!Number.isInteger(ast.right.value)) { + this.pushState('building-float'); + this.castValueToFloat(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-float'); + break; + } + } + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState('casting-to-integer'); + if (ast.right.type === 'Literal') { + const literalResult = []; + this.astGeneric(ast.right, literalResult); + const literalType = this.getType(ast.right); + if (literalType === 'Integer') { + retArr.push(literalResult.join('')); + } else { + throw this.astErrorOutput(`Unhandled binary expression with literal`, ast); + } + } else { + retArr.push('int('); + this.astGeneric(ast.right, retArr); + retArr.push(')'); + } + this.popState('casting-to-integer'); + this.popState('building-integer'); + break; + case 'Integer & LiteralInteger': + this.pushState('building-integer'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(ast.right, retArr); + this.popState('building-integer'); + break; + + case 'Number & Integer': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState('building-float'); + break; + case 'Float & LiteralInteger': + case 'Number & LiteralInteger': + if (this.isState('in-for-loop-test')) { + this.pushState('building-integer'); + retArr.push('int('); + this.astGeneric(ast.left, retArr); + retArr.push(')'); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToInteger(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castLiteralToFloat(ast.right, retArr); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Float': + case 'LiteralInteger & Number': + if (this.isState('in-for-loop-test') || this.isState('in-for-loop-init') || this.isState('casting-to-integer')) { + this.pushState('building-integer'); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToInteger(ast.right, retArr); + this.popState('building-integer'); + } else { + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.pushState('casting-to-float'); + this.astGeneric(ast.right, retArr); + this.popState('casting-to-float'); + this.popState('building-float'); + } + break; + case 'LiteralInteger & Integer': + this.pushState('building-integer'); + this.castLiteralToInteger(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-integer'); + break; + + case 'Boolean & Boolean': + this.pushState('building-boolean'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.astGeneric(ast.right, retArr); + this.popState('building-boolean'); + break; + + case 'Float & Integer': + this.pushState('building-float'); + this.astGeneric(ast.left, retArr); + retArr.push(operatorMap[ast.operator] || ast.operator); + this.castValueToFloat(ast.right, retArr); + this.popState('building-float'); + break; + + default: + throw this.astErrorOutput(`Unhandled binary expression between ${key}`, ast); + } + retArr.push(')'); + + return retArr; + } + + checkAndUpconvertOperator(ast, retArr) { + const bitwiseResult = this.checkAndUpconvertBitwiseOperators(ast, retArr); + if (bitwiseResult) { + return bitwiseResult; + } + const upconvertableOperators = { + '%': 'mod', + '**': 'pow', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + switch (this.getType(ast.left)) { + case 'Integer': + this.castValueToFloat(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(','); + switch (this.getType(ast.right)) { + case 'Integer': + this.castValueToFloat(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToFloat(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } + retArr.push(')'); + return retArr; + } + + checkAndUpconvertBitwiseOperators(ast, retArr) { + const upconvertableOperators = { + '&': 'bitwiseAnd', + '|': 'bitwiseOr', + '^': 'bitwiseXOR', + '<<': 'bitwiseZeroFillLeftShift', + '>>': 'bitwiseSignedRightShift', + '>>>': 'bitwiseZeroFillRightShift', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + const leftType = this.getType(ast.left); + switch (leftType) { + case 'Number': + case 'Float': + this.castValueToInteger(ast.left, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.left, retArr); + break; + default: + this.astGeneric(ast.left, retArr); + } + retArr.push(','); + const rightType = this.getType(ast.right); + switch (rightType) { + case 'Number': + case 'Float': + this.castValueToInteger(ast.right, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.right, retArr); + break; + default: + this.astGeneric(ast.right, retArr); + } + retArr.push(')'); + return retArr; + } + + checkAndUpconvertBitwiseUnary(ast, retArr) { + const upconvertableOperators = { + '~': 'bitwiseNot', + }; + const foundOperator = upconvertableOperators[ast.operator]; + if (!foundOperator) return null; + retArr.push(foundOperator); + retArr.push('('); + switch (this.getType(ast.argument)) { + case 'Number': + case 'Float': + this.castValueToInteger(ast.argument, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(ast.argument, retArr); + break; + default: + this.astGeneric(ast.argument, retArr); + } + retArr.push(')'); + return retArr; + } + + /** + * + * @param {Object} ast + * @param {Array} retArr + * @return {String[]} + */ + castLiteralToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + this.astGeneric(ast, retArr); + this.popState('casting-to-integer'); + return retArr; + } + + /** + * + * @param {Object} ast + * @param {Array} retArr + * @return {String[]} + */ + castLiteralToFloat(ast, retArr) { + this.pushState('casting-to-float'); + this.astGeneric(ast, retArr); + this.popState('casting-to-float'); + return retArr; + } + + /** + * + * @param {Object} ast + * @param {Array} retArr + * @return {String[]} + */ + castValueToInteger(ast, retArr) { + this.pushState('casting-to-integer'); + retArr.push('int('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-integer'); + return retArr; + } + + /** + * + * @param {Object} ast + * @param {Array} retArr + * @return {String[]} + */ + castValueToFloat(ast, retArr) { + this.pushState('casting-to-float'); + retArr.push('float('); + this.astGeneric(ast, retArr); + retArr.push(')'); + this.popState('casting-to-float'); + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *identifier* expression + * @param {Object} idtNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput('IdentifierExpression - not an Identifier', idtNode); + } + + const type = this.getType(idtNode); + + if (idtNode.name === 'Infinity') { + // https://stackoverflow.com/a/47543127/1324039 + retArr.push('3.402823466e+38'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); + } else { + retArr.push(`user_${idtNode.name}`); + } + } else { + retArr.push(`user_${idtNode.name}`); + } + + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *for-loop* expression + * @param {Object} forNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the parsed webgl string + */ + astForStatement(forNode, retArr) { + if (forNode.type !== 'ForStatement') { + throw this.astErrorOutput('Invalid for statement', forNode); + } + + const initArr = []; + const testArr = []; + const updateArr = []; + const bodyArr = []; + let isSafe = null; + + if (forNode.init) { + this.pushState('in-for-loop-init'); + this.astGeneric(forNode.init, initArr); + const { declarations } = forNode.init; + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init && declarations[i].init.type !== 'Literal') { + isSafe = false; + } + } + if (isSafe) { + for (let i = 0; i < initArr.length; i++) { + if (initArr[i].includes && initArr[i].includes(',')) { + isSafe = false; + } + } + } + this.popState('in-for-loop-init'); + } else { + isSafe = false; + } + + if (forNode.test) { + this.pushState('in-for-loop-test'); + this.astGeneric(forNode.test, testArr); + this.popState('in-for-loop-test'); + } else { + isSafe = false; + } + + if (forNode.update) { + this.astGeneric(forNode.update, updateArr); + } else { + isSafe = false; + } + + if (forNode.body) { + this.pushState('loop-body'); + this.astGeneric(forNode.body, bodyArr); + this.popState('loop-body'); + } + + // have all parts, now make them safe + if (isSafe === null) { + isSafe = this.isSafe(forNode.init) && this.isSafe(forNode.test); + } + + if (isSafe) { + retArr.push(`for (${initArr.join('')};${testArr.join('')};${updateArr.join('')}){\n`); + retArr.push(bodyArr.join('')); + retArr.push('}\n'); + } else { + const iVariableName = this.getInternalVariableName('safeI'); + if (initArr.length > 0) { + retArr.push(initArr.join(''), ';\n'); + } + retArr.push(`for (int ${iVariableName}=0;${iVariableName} 0) { + retArr.push(`if (!${testArr.join('')}) break;\n`); + } + retArr.push(bodyArr.join('')); + retArr.push(`\n${updateArr.join('')};`); + retArr.push('}\n'); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *while* loop + * @param {Object} whileNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the parsed webgl string + */ + astWhileStatement(whileNode, retArr) { + if (whileNode.type !== 'WhileStatement') { + throw this.astErrorOutput('Invalid while statement', whileNode); + } + + const iVariableName = this.getInternalVariableName('safeI'); + retArr.push(`for (int ${iVariableName}=0;${iVariableName} i + 1) { + movingDefaultToEnd = true; + this.astGeneric(cases[i].consequent, defaultResult); + continue; + } else { + retArr.push(' else {\n'); + } + } else { + // all others + if (i === 0 || !pastFirstIf) { + pastFirstIf = true; + retArr.push(`if (${varName} == `); + } else { + if (fallingThrough) { + retArr.push(`${varName} == `); + fallingThrough = false; + } else { + retArr.push(` else if (${varName} == `); + } + } + if (type === 'Integer') { + const testType = this.getType(cases[i].test); + switch (testType) { + case 'Number': + case 'Float': + this.castValueToInteger(cases[i].test, retArr); + break; + case 'LiteralInteger': + this.castLiteralToInteger(cases[i].test, retArr); + break; + } + } else if (type === 'Float') { + const testType = this.getType(cases[i].test); + switch (testType) { + case 'LiteralInteger': + this.castLiteralToFloat(cases[i].test, retArr); + break; + case 'Integer': + this.castValueToFloat(cases[i].test, retArr); + break; + } + } else { + throw new Error('unhanlded'); + } + if (!cases[i].consequent || cases[i].consequent.length === 0) { + fallingThrough = true; + retArr.push(' || '); + continue; + } + retArr.push(`) {\n`); + } + this.astGeneric(cases[i].consequent, retArr); + retArr.push('\n}'); + } + if (movingDefaultToEnd) { + retArr.push(' else {'); + retArr.push(defaultResult.join('')); + retArr.push('}'); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *This* expression + * @param {Object} tNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astThisExpression(tNode, retArr) { + retArr.push('this'); + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *Member* Expression + * @param {Object} mNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astMemberExpression(mNode, retArr) { + const { + property, + name, + signature, + origin, + type, + xProperty, + yProperty, + zProperty + } = this.getMemberExpressionDetails(mNode); + switch (signature) { + case 'value.thread.value': + case 'this.thread.value': + if (name !== 'x' && name !== 'y' && name !== 'z') { + throw this.astErrorOutput('Unexpected expression, expected `this.thread.x`, `this.thread.y`, or `this.thread.z`', mNode); + } + retArr.push(`threadId.${name}`); + return retArr; + case 'this.output.value': + if (this.dynamicOutput) { + switch (name) { + case 'x': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.x)'); + } else { + retArr.push('uOutputDim.x'); + } + break; + case 'y': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.y)'); + } else { + retArr.push('uOutputDim.y'); + } + break; + case 'z': + if (this.isState('casting-to-float')) { + retArr.push('float(uOutputDim.z)'); + } else { + retArr.push('uOutputDim.z'); + } + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + } else { + switch (name) { + case 'x': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[0]); + } else { + retArr.push(this.output[0], '.0'); + } + break; + case 'y': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[1]); + } else { + retArr.push(this.output[1], '.0'); + } + break; + case 'z': + if (this.isState('casting-to-integer')) { + retArr.push(this.output[2]); + } else { + retArr.push(this.output[2], '.0'); + } + break; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + } + return retArr; + case 'value': + throw this.astErrorOutput('Unexpected expression', mNode); + case 'value[]': + case 'value[][]': + case 'value[][][]': + case 'value[][][][]': + case 'value.value': + if (origin === 'Math') { + retArr.push(Math[name]); + return retArr; + } + switch (property) { + case 'r': + retArr.push(`user_${ name }.r`); + return retArr; + case 'g': + retArr.push(`user_${ name }.g`); + return retArr; + case 'b': + retArr.push(`user_${ name }.b`); + return retArr; + case 'a': + retArr.push(`user_${ name }.a`); + return retArr; + } + break; + case 'this.constants.value': + if (typeof xProperty === 'undefined') { + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + retArr.push(`constants_${ name }`); + return retArr; + } + } + case 'this.constants.value[]': + case 'this.constants.value[][]': + case 'this.constants.value[][][]': + case 'this.constants.value[][][][]': + break; + case 'fn()[]': + this.astCallExpression(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push(']'); + return retArr; + case '[][]': + this.astArrayExpression(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(property)); + retArr.push(']'); + return retArr; + default: + throw this.astErrorOutput('Unexpected expression', mNode); + } + + if (mNode.computed === false) { + // handle simple types + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'Boolean': + retArr.push(`${origin}_${name}`); + return retArr; + } + } + + // handle more complex types + // argument may have come from a parent + const markupName = `${origin}_${name}`; + + switch (type) { + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + // Get from local vec4 + this.astGeneric(mNode.object, retArr); + retArr.push('['); + retArr.push(this.memberExpressionPropertyMarkup(xProperty)); + retArr.push(']'); + break; + case 'HTMLImageArray': + retArr.push(`getImage3D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(1)': + retArr.push(`getFloatFromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(2)': + case 'Array2D(2)': + case 'Array3D(2)': + retArr.push(`getMemoryOptimizedVec2(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(2)': + retArr.push(`getVec2FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(3)': + case 'Array2D(3)': + case 'Array3D(3)': + retArr.push(`getMemoryOptimizedVec3(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(3)': + retArr.push(`getVec3FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'Array1D(4)': + case 'Array2D(4)': + case 'Array3D(4)': + retArr.push(`getMemoryOptimizedVec4(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'ArrayTexture(4)': + case 'HTMLImage': + case 'HTMLVideo': + retArr.push(`getVec4FromSampler2D(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + case 'NumberTexture': + case 'Array': + case 'Array2D': + case 'Array3D': + case 'Array4D': + case 'Input': + case 'Number': + case 'Float': + case 'Integer': + if (this.precision === 'single') { + // bitRatio is always 4 here, javascript doesn't yet have 8 or 16 bit support + // TODO: make 8 or 16 bit work anyway! + retArr.push(`getMemoryOptimized32(${markupName}, ${markupName}Size, ${markupName}Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + } else { + const bitRatio = (origin === 'user' ? + this.lookupFunctionArgumentBitRatio(this.name, name) : + this.constantBitRatios[name] + ); + switch (bitRatio) { + case 1: + retArr.push(`get8(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + case 2: + retArr.push(`get16(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + case 4: + case 0: + retArr.push(`get32(${markupName}, ${markupName}Size, ${markupName}Dim, `); + break; + default: + throw new Error(`unhandled bit ratio of ${bitRatio}`); + } + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + } + break; + case 'MemoryOptimizedNumberTexture': + retArr.push(`getMemoryOptimized32(${ markupName }, ${ markupName }Size, ${ markupName }Dim, `); + this.memberExpressionXYZ(xProperty, yProperty, zProperty, retArr); + retArr.push(')'); + break; + default: + throw new Error(`unhandled member expression "${ type }"`); + } + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *call* expression + * @param {Object} ast - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astCallExpression(ast, retArr) { + if (!ast.callee) { + throw this.astErrorOutput('Unknown CallExpression', ast); + } + + let functionName = null; + const isMathFunction = this.isAstMathFunction(ast); + + // Its a math operator or this.something(), remove the prefix + if (isMathFunction || (ast.callee.object && ast.callee.object.type === 'ThisExpression')) { + functionName = ast.callee.property.name; + } + // Issue #212, BABEL! + else if (ast.callee.type === 'SequenceExpression' && ast.callee.expressions[0].type === 'Literal' && !isNaN(ast.callee.expressions[0].raw)) { + functionName = ast.callee.expressions[1].property.name; + } else { + functionName = ast.callee.name; + } + + if (!functionName) { + throw this.astErrorOutput(`Unhandled function, couldn't find name`, ast); + } + + // if this if grows to more than one, lets use a switch + if (functionName === 'atan2') { + functionName = 'atan'; + } + + // Register the function into the called registry + if (this.calledFunctions.indexOf(functionName) < 0) { + this.calledFunctions.push(functionName); + } + + if (functionName === 'random' && this.plugins && this.plugins.length > 0) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.functionMatch === 'Math.random()' && plugin.functionReplace) { + retArr.push(plugin.functionReplace); + return retArr; + } + } + } + + // track the function was called + if (this.onFunctionCall) { + this.onFunctionCall(this.name, functionName, ast.arguments); + } + + // Call the function + retArr.push(functionName); + + // Open arguments space + retArr.push('('); + + // Add the arguments + if (isMathFunction) { + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + const argumentType = this.getType(argument); + if (i > 0) { + retArr.push(', '); + } + + switch (argumentType) { + case 'Integer': + this.castValueToFloat(argument, retArr); + break; + default: + this.astGeneric(argument, retArr); + break; + } + } + } else { + const targetTypes = this.lookupFunctionArgumentTypes(functionName) || []; + for (let i = 0; i < ast.arguments.length; ++i) { + const argument = ast.arguments[i]; + let targetType = targetTypes[i]; + if (i > 0) { + retArr.push(', '); + } + const argumentType = this.getType(argument); + if (!targetType) { + this.triggerImplyArgumentType(functionName, i, argumentType, this); + targetType = argumentType; + } + switch (argumentType) { + case 'Number': + case 'Float': + if (targetType === 'Integer') { + retArr.push('int('); + this.astGeneric(argument, retArr); + retArr.push(')'); + continue; + } else if (targetType === 'Number' || targetType === 'Float') { + this.astGeneric(argument, retArr); + continue; + } else if (targetType === 'LiteralInteger') { + this.castLiteralToFloat(argument, retArr); + continue; + } + break; + case 'Integer': + if (targetType === 'Number' || targetType === 'Float') { + retArr.push('float('); + this.astGeneric(argument, retArr); + retArr.push(')'); + continue; + } else if (targetType === 'Integer') { + this.astGeneric(argument, retArr); + continue; + } + break; + case 'LiteralInteger': + if (targetType === 'Integer') { + this.castLiteralToInteger(argument, retArr); + continue; + } else if (targetType === 'Number' || targetType === 'Float') { + this.castLiteralToFloat(argument, retArr); + continue; + } else if (targetType === 'LiteralInteger') { + this.astGeneric(argument, retArr); + continue; + } + break; + case 'Array(2)': + case 'Array(3)': + case 'Array(4)': + if (targetType === argumentType) { + if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name}`); + continue; + } + break; + case 'HTMLImage': + case 'HTMLImageArray': + case 'HTMLVideo': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + case 'Array': + case 'Input': + if (targetType === argumentType) { + if (argument.type !== 'Identifier') throw this.astErrorOutput(`Unhandled argument type ${ argument.type }`, ast); + this.triggerImplyArgumentBitRatio(this.name, argument.name, functionName, i); + retArr.push(`user_${argument.name},user_${argument.name}Size,user_${argument.name}Dim`); + continue; + } + break; + } + throw this.astErrorOutput(`Unhandled argument combination of ${ argumentType } and ${ targetType } for argument named "${ argument.name }"`, ast); + } + } + // Close arguments space + retArr.push(')'); + + return retArr; + } + + /** + * @desc Parses the abstract syntax tree for *Array* Expression + * @param {Object} arrNode - the AST object to parse + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astArrayExpression(arrNode, retArr) { + const arrLen = arrNode.elements.length; + + retArr.push('vec' + arrLen + '('); + for (let i = 0; i < arrLen; ++i) { + if (i > 0) { + retArr.push(', '); + } + const subNode = arrNode.elements[i]; + this.astGeneric(subNode, retArr) + } + retArr.push(')'); + + return retArr; + } + + memberExpressionXYZ(x, y, z, retArr) { + if (z) { + retArr.push(this.memberExpressionPropertyMarkup(z), ', '); + } else { + retArr.push('0, '); + } + if (y) { + retArr.push(this.memberExpressionPropertyMarkup(y), ', '); + } else { + retArr.push('0, '); + } + retArr.push(this.memberExpressionPropertyMarkup(x)); + return retArr; + } + + memberExpressionPropertyMarkup(property) { + if (!property) { + throw new Error('Property not set'); + } + const type = this.getType(property); + const result = []; + switch (type) { + case 'Number': + case 'Float': + this.castValueToInteger(property, result); + break; + case 'LiteralInteger': + this.castLiteralToInteger(property, result); + break; + default: + this.astGeneric(property, result); + } + return result.join(''); + } +} + +const typeMap = { + 'Array': 'sampler2D', + 'Array(2)': 'vec2', + 'Array(3)': 'vec3', + 'Array(4)': 'vec4', + 'Array2D': 'sampler2D', + 'Array3D': 'sampler2D', + 'Boolean': 'bool', + 'Float': 'float', + 'Input': 'sampler2D', + 'Integer': 'int', + 'Number': 'float', + 'LiteralInteger': 'float', + 'NumberTexture': 'sampler2D', + 'MemoryOptimizedNumberTexture': 'sampler2D', + 'ArrayTexture(1)': 'sampler2D', + 'ArrayTexture(2)': 'sampler2D', + 'ArrayTexture(3)': 'sampler2D', + 'ArrayTexture(4)': 'sampler2D', + 'HTMLVideo': 'sampler2D', + 'HTMLImage': 'sampler2D', + 'HTMLImageArray': 'sampler2DArray', +}; + +const operatorMap = { + '===': '==', + '!==': '!=' +}; diff --git a/src/backend/web-gl/kernel-value-maps.js b/src/backend/web-gl/kernel-value-maps.js index e0480d68..07b2e0fa 100644 --- a/src/backend/web-gl/kernel-value-maps.js +++ b/src/backend/web-gl/kernel-value-maps.js @@ -1,186 +1,181 @@ -const { WebGLKernelValueBoolean } = require('./kernel-value/boolean'); -const { WebGLKernelValueFloat } = require('./kernel-value/float'); -const { WebGLKernelValueInteger } = require('./kernel-value/integer'); - -const { WebGLKernelValueHTMLImage } = require('./kernel-value/html-image'); -const { WebGLKernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image'); - -const { WebGLKernelValueHTMLVideo } = require('./kernel-value/html-video'); -const { WebGLKernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video'); - -const { WebGLKernelValueSingleInput } = require('./kernel-value/single-input'); -const { WebGLKernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input'); - -const { WebGLKernelValueUnsignedInput } = require('./kernel-value/unsigned-input'); -const { WebGLKernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input'); - -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture'); -const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture'); - -const { WebGLKernelValueNumberTexture } = require('./kernel-value/number-texture'); -const { WebGLKernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture'); - -const { WebGLKernelValueSingleArray } = require('./kernel-value/single-array'); -const { WebGLKernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array'); - -const { WebGLKernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i'); -const { WebGLKernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i'); - -const { WebGLKernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i'); -const { WebGLKernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i'); - -const { WebGLKernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i'); -const { WebGLKernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i'); - -const { WebGLKernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGLKernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGLKernelValueSingleArray4 } = require('./kernel-value/single-array4'); - -const { WebGLKernelValueUnsignedArray } = require('./kernel-value/unsigned-array'); -const { WebGLKernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array'); - -const kernelValueMaps = { - unsigned: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGLKernelValueDynamicUnsignedInput, - 'NumberTexture': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGLKernelValueUnsignedInput, - 'NumberTexture': WebGLKernelValueNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGLKernelValueBoolean, - 'Integer': WebGLKernelValueInteger, - 'Float': WebGLKernelValueFloat, - 'Array': WebGLKernelValueDynamicSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI, - 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI, - 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI, - 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI, - 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI, - 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI, - 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI, - 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI, - 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI, - 'Input': WebGLKernelValueDynamicSingleInput, - 'NumberTexture': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueDynamicHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGLKernelValueBoolean, - 'Float': WebGLKernelValueFloat, - 'Integer': WebGLKernelValueInteger, - 'Array': WebGLKernelValueSingleArray, - 'Array(2)': WebGLKernelValueSingleArray2, - 'Array(3)': WebGLKernelValueSingleArray3, - 'Array(4)': WebGLKernelValueSingleArray4, - 'Array1D(2)': WebGLKernelValueSingleArray1DI, - 'Array1D(3)': WebGLKernelValueSingleArray1DI, - 'Array1D(4)': WebGLKernelValueSingleArray1DI, - 'Array2D(2)': WebGLKernelValueSingleArray2DI, - 'Array2D(3)': WebGLKernelValueSingleArray2DI, - 'Array2D(4)': WebGLKernelValueSingleArray2DI, - 'Array3D(2)': WebGLKernelValueSingleArray3DI, - 'Array3D(3)': WebGLKernelValueSingleArray3DI, - 'Array3D(4)': WebGLKernelValueSingleArray3DI, - 'Input': WebGLKernelValueSingleInput, - 'NumberTexture': WebGLKernelValueNumberTexture, - 'ArrayTexture(1)': WebGLKernelValueNumberTexture, - 'ArrayTexture(2)': WebGLKernelValueNumberTexture, - 'ArrayTexture(3)': WebGLKernelValueNumberTexture, - 'ArrayTexture(4)': WebGLKernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGLKernelValueHTMLImage, - 'HTMLImageArray': false, - 'HTMLVideo': WebGLKernelValueHTMLVideo, - } - }, -}; - -function lookupKernelValueType(type, dynamic, precision, value) { - if (!type) { - throw new Error('type missing'); - } - if (!dynamic) { - throw new Error('dynamic missing'); - } - if (!precision) { - throw new Error('precision missing'); - } - if (value.type) { - type = value.type; - } - const types = kernelValueMaps[precision][dynamic]; - if (types[type] === false) { - return null; - } else if (types[type] === undefined) { - throw new Error(`Could not find a KernelValue for ${ type }`); - } - return types[type]; -} - -module.exports = { - lookupKernelValueType, - kernelValueMaps, -}; \ No newline at end of file +import { WebGLKernelValueBoolean } from './kernel-value/boolean'; +import { WebGLKernelValueFloat } from './kernel-value/float'; +import { WebGLKernelValueInteger } from './kernel-value/integer'; + +import { WebGLKernelValueHTMLImage } from './kernel-value/html-image'; +import { WebGLKernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image'; + +import { WebGLKernelValueHTMLVideo } from './kernel-value/html-video'; +import { WebGLKernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video'; + +import { WebGLKernelValueSingleInput } from './kernel-value/single-input'; +import { WebGLKernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input'; + +import { WebGLKernelValueUnsignedInput } from './kernel-value/unsigned-input'; +import { WebGLKernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input'; + +import { WebGLKernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture'; +import { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture'; + +import { WebGLKernelValueNumberTexture } from './kernel-value/number-texture'; +import { WebGLKernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture'; + +import { WebGLKernelValueSingleArray } from './kernel-value/single-array'; +import { WebGLKernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array'; + +import { WebGLKernelValueSingleArray1DI } from './kernel-value/single-array1d-i'; +import { WebGLKernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i'; + +import { WebGLKernelValueSingleArray2DI } from './kernel-value/single-array2d-i'; +import { WebGLKernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i'; + +import { WebGLKernelValueSingleArray3DI } from './kernel-value/single-array3d-i'; +import { WebGLKernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i'; + +import { WebGLKernelValueSingleArray2 } from './kernel-value/single-array2'; +import { WebGLKernelValueSingleArray3 } from './kernel-value/single-array3'; +import { WebGLKernelValueSingleArray4 } from './kernel-value/single-array4'; + +import { WebGLKernelValueUnsignedArray } from './kernel-value/unsigned-array'; +import { WebGLKernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array'; + +export const kernelValueMaps = { + unsigned: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGLKernelValueDynamicUnsignedInput, + 'NumberTexture': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGLKernelValueUnsignedInput, + 'NumberTexture': WebGLKernelValueNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGLKernelValueBoolean, + 'Integer': WebGLKernelValueInteger, + 'Float': WebGLKernelValueFloat, + 'Array': WebGLKernelValueDynamicSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + 'Array1D(2)': WebGLKernelValueDynamicSingleArray1DI, + 'Array1D(3)': WebGLKernelValueDynamicSingleArray1DI, + 'Array1D(4)': WebGLKernelValueDynamicSingleArray1DI, + 'Array2D(2)': WebGLKernelValueDynamicSingleArray2DI, + 'Array2D(3)': WebGLKernelValueDynamicSingleArray2DI, + 'Array2D(4)': WebGLKernelValueDynamicSingleArray2DI, + 'Array3D(2)': WebGLKernelValueDynamicSingleArray3DI, + 'Array3D(3)': WebGLKernelValueDynamicSingleArray3DI, + 'Array3D(4)': WebGLKernelValueDynamicSingleArray3DI, + 'Input': WebGLKernelValueDynamicSingleInput, + 'NumberTexture': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueDynamicHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGLKernelValueBoolean, + 'Float': WebGLKernelValueFloat, + 'Integer': WebGLKernelValueInteger, + 'Array': WebGLKernelValueSingleArray, + 'Array(2)': WebGLKernelValueSingleArray2, + 'Array(3)': WebGLKernelValueSingleArray3, + 'Array(4)': WebGLKernelValueSingleArray4, + 'Array1D(2)': WebGLKernelValueSingleArray1DI, + 'Array1D(3)': WebGLKernelValueSingleArray1DI, + 'Array1D(4)': WebGLKernelValueSingleArray1DI, + 'Array2D(2)': WebGLKernelValueSingleArray2DI, + 'Array2D(3)': WebGLKernelValueSingleArray2DI, + 'Array2D(4)': WebGLKernelValueSingleArray2DI, + 'Array3D(2)': WebGLKernelValueSingleArray3DI, + 'Array3D(3)': WebGLKernelValueSingleArray3DI, + 'Array3D(4)': WebGLKernelValueSingleArray3DI, + 'Input': WebGLKernelValueSingleInput, + 'NumberTexture': WebGLKernelValueNumberTexture, + 'ArrayTexture(1)': WebGLKernelValueNumberTexture, + 'ArrayTexture(2)': WebGLKernelValueNumberTexture, + 'ArrayTexture(3)': WebGLKernelValueNumberTexture, + 'ArrayTexture(4)': WebGLKernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGLKernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGLKernelValueHTMLImage, + 'HTMLImageArray': false, + 'HTMLVideo': WebGLKernelValueHTMLVideo, + } + }, +}; + +export function lookupKernelValueType(type, dynamic, precision, value) { + if (!type) { + throw new Error('type missing'); + } + if (!dynamic) { + throw new Error('dynamic missing'); + } + if (!precision) { + throw new Error('precision missing'); + } + if (value.type) { + type = value.type; + } + const types = kernelValueMaps[precision][dynamic]; + if (types[type] === false) { + return null; + } else if (types[type] === undefined) { + throw new Error(`Could not find a KernelValue for ${ type }`); + } + return types[type]; +} diff --git a/src/backend/web-gl/kernel-value/boolean.js b/src/backend/web-gl/kernel-value/boolean.js index 895663d0..6015bb0a 100644 --- a/src/backend/web-gl/kernel-value/boolean.js +++ b/src/backend/web-gl/kernel-value/boolean.js @@ -1,28 +1,24 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueBoolean extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const bool ${this.id} = ${value};\n`; - } - return `uniform bool ${this.id};\n`; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueBoolean -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueBoolean extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const bool ${this.id} = ${value};\n`; + } + return `uniform bool ${this.id};\n`; + } + + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-html-image.js b/src/backend/web-gl/kernel-value/dynamic-html-image.js index 926ead66..4a58e819 100644 --- a/src/backend/web-gl/kernel-value/dynamic-html-image.js +++ b/src/backend/web-gl/kernel-value/dynamic-html-image.js @@ -1,26 +1,22 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.textureSize = [width, height]; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicHTMLImage -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueHTMLImage } from './html-image'; + +export class WebGLKernelValueDynamicHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.textureSize = [width, height]; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-html-video.js b/src/backend/web-gl/kernel-value/dynamic-html-video.js index a10a00f6..95e1a790 100644 --- a/src/backend/web-gl/kernel-value/dynamic-html-video.js +++ b/src/backend/web-gl/kernel-value/dynamic-html-video.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} - -module.exports = { - WebGLKernelValueDynamicHTMLVideo -}; \ No newline at end of file +import { WebGLKernelValueDynamicHTMLImage } from './dynamic-html-image'; + +export class WebGLKernelValueDynamicHTMLVideo extends WebGLKernelValueDynamicHTMLImage {} diff --git a/src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js b/src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js index 1083f40f..157fd5d5 100644 --- a/src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js +++ b/src/backend/web-gl/kernel-value/dynamic-memory-optimized-number-texture.js @@ -1,25 +1,21 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('./memory-optimized-number-texture'); - -class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(inputTexture) { - this.checkSize(inputTexture.size[0], inputTexture.size[1]); - this.dimensions = inputTexture.dimensions; - this.textureSize = inputTexture.size; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(inputTexture); - } -} - -module.exports = { - WebGLKernelValueDynamicMemoryOptimizedNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueMemoryOptimizedNumberTexture } from './memory-optimized-number-texture'; + +export class WebGLKernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(inputTexture) { + this.checkSize(inputTexture.size[0], inputTexture.size[1]); + this.dimensions = inputTexture.dimensions; + this.textureSize = inputTexture.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(inputTexture); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-number-texture.js b/src/backend/web-gl/kernel-value/dynamic-number-texture.js index edf5980d..3526a1ca 100644 --- a/src/backend/web-gl/kernel-value/dynamic-number-texture.js +++ b/src/backend/web-gl/kernel-value/dynamic-number-texture.js @@ -1,25 +1,21 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueNumberTexture } = require('./number-texture'); - -class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = value.dimensions; - this.checkSize(value.size[0], value.size[1]); - this.textureSize = value.size; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueNumberTexture } from './number-texture'; + +export class WebGLKernelValueDynamicNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.dimensions = value.dimensions; + this.checkSize(value.size[0], value.size[1]); + this.textureSize = value.size; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array.js b/src/backend/web-gl/kernel-value/dynamic-single-array.js index ed0135eb..7f26eae7 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-array.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-array.js @@ -1,27 +1,23 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray } = require('./single-array'); - -class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray } from './single-array'; + +export class WebGLKernelValueDynamicSingleArray extends WebGLKernelValueSingleArray { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.dimensions = utils.getDimensions(value, true); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js b/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js index 0c9489ce..89cd81f5 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-array1d-i.js @@ -1,23 +1,19 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray1DI } = require('./single-array1d-i'); - -class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray1DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray1DI } from './single-array1d-i'; + +export class WebGLKernelValueDynamicSingleArray1DI extends WebGLKernelValueSingleArray1DI { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js b/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js index b164f3c1..ba9b474f 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-array2d-i.js @@ -1,23 +1,19 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray2DI } = require('./single-array2d-i'); - -class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray2DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray2DI } from './single-array2d-i'; + +export class WebGLKernelValueDynamicSingleArray2DI extends WebGLKernelValueSingleArray2DI { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js b/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js index b1d52a5d..a6d8deeb 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-array3d-i.js @@ -1,23 +1,19 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray3DI } = require('./single-array3d-i'); - -class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleArray3DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray3DI } from './single-array3d-i'; + +export class WebGLKernelValueDynamicSingleArray3DI extends WebGLKernelValueSingleArray3DI { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-single-input.js b/src/backend/web-gl/kernel-value/dynamic-single-input.js index a2efbdb1..38684525 100644 --- a/src/backend/web-gl/kernel-value/dynamic-single-input.js +++ b/src/backend/web-gl/kernel-value/dynamic-single-input.js @@ -1,28 +1,24 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleInput } = require('./single-input'); - -class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicSingleInput -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleInput } from './single-input'; + +export class WebGLKernelValueDynamicSingleInput extends WebGLKernelValueSingleInput { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js b/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js index ca0db3ac..2e1a9b8e 100644 --- a/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js +++ b/src/backend/web-gl/kernel-value/dynamic-unsigned-array.js @@ -1,29 +1,25 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedArray } = require('./unsigned-array'); - -class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - const Type = this.getTransferArrayType(value); - this.preUploadValue = new Type(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicUnsignedArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueUnsignedArray } from './unsigned-array'; + +export class WebGLKernelValueDynamicUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.dimensions = utils.getDimensions(value, true); + this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + const Type = this.getTransferArrayType(value); + this.preUploadValue = new Type(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js b/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js index bba6c923..51482dc8 100644 --- a/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js +++ b/src/backend/web-gl/kernel-value/dynamic-unsigned-input.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedInput } = require('./unsigned-input'); - -class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - const Type = this.getTransferArrayType(value.value); - this.preUploadValue = new Type(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGLKernelValueDynamicUnsignedInput -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueUnsignedInput } from './unsigned-input'; + +export class WebGLKernelValueDynamicUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + const Type = this.getTransferArrayType(value.value); + this.preUploadValue = new Type(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl/kernel-value/float.js b/src/backend/web-gl/kernel-value/float.js index 3668bfb6..8685a881 100644 --- a/src/backend/web-gl/kernel-value/float.js +++ b/src/backend/web-gl/kernel-value/float.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueFloat extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - getSource(value) { - if (this.origin === 'constants') { - if (Number.isInteger(value)) { - return `const float ${this.id} = ${value}.0;\n`; - } - return `const float ${this.id} = ${value};\n`; - } - return `uniform float ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1f(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueFloat -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueFloat extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource(value) { + if (this.origin === 'constants') { + if (Number.isInteger(value)) { + return `const float ${this.id} = ${value}.0;\n`; + } + return `const float ${this.id} = ${value};\n`; + } + return `uniform float ${this.id};\n`; + } + + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1f(this.id, this.uploadValue = value); + } +} diff --git a/src/backend/web-gl/kernel-value/html-image.js b/src/backend/web-gl/kernel-value/html-image.js index eaf2404c..7a9cc9c7 100644 --- a/src/backend/web-gl/kernel-value/html-image.js +++ b/src/backend/web-gl/kernel-value/html-image.js @@ -1,47 +1,43 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueHTMLImage extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const { width, height } = value; - this.checkSize(width, height); - this.dimensions = [width, height, 1]; - this.requestTexture(); - this.textureSize = [width, height]; - this.uploadValue = value; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputImage) { - if (inputImage.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueHTMLImage -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueHTMLImage extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const { width, height } = value; + this.checkSize(width, height); + this.dimensions = [width, height, 1]; + this.requestTexture(); + this.textureSize = [width, height]; + this.uploadValue = value; + } + + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(inputImage) { + if (inputImage.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue = inputImage); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/html-video.js b/src/backend/web-gl/kernel-value/html-video.js index 64a2793e..bc18180b 100644 --- a/src/backend/web-gl/kernel-value/html-video.js +++ b/src/backend/web-gl/kernel-value/html-video.js @@ -1,8 +1,3 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('./html-image'); - -class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} - -module.exports = { - WebGLKernelValueHTMLVideo -}; \ No newline at end of file +import { WebGLKernelValueHTMLImage } from './html-image'; + +export class WebGLKernelValueHTMLVideo extends WebGLKernelValueHTMLImage {} diff --git a/src/backend/web-gl/kernel-value/index.js b/src/backend/web-gl/kernel-value/index.js index 9b64f165..741118f6 100644 --- a/src/backend/web-gl/kernel-value/index.js +++ b/src/backend/web-gl/kernel-value/index.js @@ -1,157 +1,153 @@ -const { utils } = require('../../../utils'); -const { Input } = require('../../../input'); -const { KernelValue } = require('../../kernel-value'); - -class WebGLKernelValue extends KernelValue { - /** - * @param {KernelVariable} value - * @param {IWebGLKernelValueSettings} settings - */ - constructor(value, settings) { - super(value, settings); - this.dimensionsId = null; - this.sizeId = null; - this.initialValueConstructor = value.constructor; - this.onRequestTexture = settings.onRequestTexture; - this.onRequestIndex = settings.onRequestIndex; - this.uploadValue = null; - this.textureSize = null; - this.bitRatio = null; - } - - /** - * - * @param {number} width - * @param {number} height - */ - checkSize(width, height) { - if (!this.kernel.validate) return; - const { maxTextureSize } = this.kernel.constructor.features; - if (width > maxTextureSize || height > maxTextureSize) { - if (width > height) { - throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); - } else { - throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); - } - } - } - - requestTexture() { - this.texture = this.onRequestTexture(); - this.setupTexture(); - } - - setupTexture() { - this.contextHandle = this.onRequestContextHandle(); - this.index = this.onRequestIndex(); - this.dimensionsId = this.id + 'Dim'; - this.sizeId = this.id + 'Size'; - } - - getTransferArrayType(value) { - if (Array.isArray(value[0])) { - return this.getTransferArrayType(value[0]); - } - switch (value.constructor) { - case Array: - case Int32Array: - case Int16Array: - case Int8Array: - return Float32Array; - case Uint8ClampedArray: - case Uint8Array: - case Uint16Array: - case Uint32Array: - case Float32Array: - case Float64Array: - return value.constructor; - } - console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros'); - return value.constructor; - } - /** - * @desc Adds kernel parameters to the Value Texture, - * binding it to the context, etc. - * - * @param {Array|Float32Array|Uint16Array} value - The actual Value supplied to the kernel - * @param {Number} length - the expected total length of the output array - * @param {Object} [Type] - * @returns {Float32Array|Uint16Array|Uint8Array} flattened array to transfer - */ - formatArrayTransfer(value, length, Type) { - if (utils.isArray(value[0]) || this.optimizeFloatMemory) { - // not already flat - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } else { - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - case Uint16Array: - case Int16Array: - case Float32Array: - case Int32Array: { - const valuesFlat = new(Type || value.constructor)(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - default: { - const valuesFlat = new Float32Array(length); - utils.flattenTo(value, valuesFlat); - return valuesFlat; - } - } - } - } - - /** - * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4 - * @param value - * @returns {number} - */ - getBitRatio(value) { - if (Array.isArray(value[0])) { - return this.getBitRatio(value[0]); - } else if (value.constructor === Input) { - return this.getBitRatio(value.value); - } - switch (value.constructor) { - case Uint8ClampedArray: - case Uint8Array: - case Int8Array: - return 1; - case Uint16Array: - case Int16Array: - return 2; - case Float32Array: - case Int32Array: - default: - return 4; - } - } - - /** - * Used for when we want a string output of our kernel, so we can still input values to the kernel - */ - getStringValueHandler() { - throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); - } - - getVariablePrecisionString() { - switch (this.tactic) { - case 'speed': - return 'lowp'; - case 'performance': - return 'highp'; - case 'balanced': - default: - return 'mediump'; - } - } -} - -module.exports = { - WebGLKernelValue -}; \ No newline at end of file +import { Input } from '../../../input'; +import { KernelValue } from '../../kernel-value'; +import { utils } from '../../../utils'; + +export class WebGLKernelValue extends KernelValue { + /** + * @param {KernelVariable} value + * @param {IWebGLKernelValueSettings} settings + */ + constructor(value, settings) { + super(value, settings); + this.dimensionsId = null; + this.sizeId = null; + this.initialValueConstructor = value.constructor; + this.onRequestTexture = settings.onRequestTexture; + this.onRequestIndex = settings.onRequestIndex; + this.uploadValue = null; + this.textureSize = null; + this.bitRatio = null; + } + + /** + * + * @param {number} width + * @param {number} height + */ + checkSize(width, height) { + if (!this.kernel.validate) return; + const { maxTextureSize } = this.kernel.constructor.features; + if (width > maxTextureSize || height > maxTextureSize) { + if (width > height) { + throw new Error(`Argument width of ${width} larger than maximum size of ${maxTextureSize} for your GPU`); + } else { + throw new Error(`Argument height of ${height} larger than maximum size of ${maxTextureSize} for your GPU`); + } + } + } + + requestTexture() { + this.texture = this.onRequestTexture(); + this.setupTexture(); + } + + setupTexture() { + this.contextHandle = this.onRequestContextHandle(); + this.index = this.onRequestIndex(); + this.dimensionsId = this.id + 'Dim'; + this.sizeId = this.id + 'Size'; + } + + getTransferArrayType(value) { + if (Array.isArray(value[0])) { + return this.getTransferArrayType(value[0]); + } + switch (value.constructor) { + case Array: + case Int32Array: + case Int16Array: + case Int8Array: + return Float32Array; + case Uint8ClampedArray: + case Uint8Array: + case Uint16Array: + case Uint32Array: + case Float32Array: + case Float64Array: + return value.constructor; + } + console.warn('Unfamiliar constructor type. Will go ahead and use, but likley this may result in a transfer of zeros'); + return value.constructor; + } + /** + * @desc Adds kernel parameters to the Value Texture, + * binding it to the context, etc. + * + * @param {Array|Float32Array|Uint16Array} value - The actual Value supplied to the kernel + * @param {Number} length - the expected total length of the output array + * @param {Object} [Type] + * @returns {Float32Array|Uint16Array|Uint8Array} flattened array to transfer + */ + formatArrayTransfer(value, length, Type) { + if (utils.isArray(value[0]) || this.optimizeFloatMemory) { + // not already flat + const valuesFlat = new Float32Array(length); + utils.flattenTo(value, valuesFlat); + return valuesFlat; + } else { + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + case Uint16Array: + case Int16Array: + case Float32Array: + case Int32Array: { + const valuesFlat = new(Type || value.constructor)(length); + utils.flattenTo(value, valuesFlat); + return valuesFlat; + } + default: { + const valuesFlat = new Float32Array(length); + utils.flattenTo(value, valuesFlat); + return valuesFlat; + } + } + } + } + + /** + * bit storage ratio of source to target 'buffer', i.e. if 8bit array -> 32bit tex = 4 + * @param value + * @returns {number} + */ + getBitRatio(value) { + if (Array.isArray(value[0])) { + return this.getBitRatio(value[0]); + } else if (value.constructor === Input) { + return this.getBitRatio(value.value); + } + switch (value.constructor) { + case Uint8ClampedArray: + case Uint8Array: + case Int8Array: + return 1; + case Uint16Array: + case Int16Array: + return 2; + case Float32Array: + case Int32Array: + default: + return 4; + } + } + + /** + * Used for when we want a string output of our kernel, so we can still input values to the kernel + */ + getStringValueHandler() { + throw new Error(`"getStringValueHandler" not implemented on ${this.constructor.name}`); + } + + getVariablePrecisionString() { + switch (this.tactic) { + case 'speed': + return 'lowp'; + case 'performance': + return 'highp'; + case 'balanced': + default: + return 'mediump'; + } + } +} diff --git a/src/backend/web-gl/kernel-value/integer.js b/src/backend/web-gl/kernel-value/integer.js index c7dad4ac..f79c2925 100644 --- a/src/backend/web-gl/kernel-value/integer.js +++ b/src/backend/web-gl/kernel-value/integer.js @@ -1,27 +1,23 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueInteger extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - getSource(value) { - if (this.origin === 'constants') { - return `const int ${this.id} = ${ parseInt(value) };\n`; - } - return `uniform int ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueInteger -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueInteger extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource(value) { + if (this.origin === 'constants') { + return `const int ${this.id} = ${ parseInt(value) };\n`; + } + return `uniform int ${this.id};\n`; + } + + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); + } +} diff --git a/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js b/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js index 418e2a5f..05f45ff8 100644 --- a/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js +++ b/src/backend/web-gl/kernel-value/memory-optimized-number-texture.js @@ -1,45 +1,41 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - this.dimensions = value.dimensions; - this.textureSize = value.size; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputTexture) { - if (inputTexture.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type }) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueMemoryOptimizedNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueMemoryOptimizedNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + this.dimensions = value.dimensions; + this.textureSize = value.size; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(inputTexture) { + if (inputTexture.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type }) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/number-texture.js b/src/backend/web-gl/kernel-value/number-texture.js index 2548c9a9..ae80f249 100644 --- a/src/backend/web-gl/kernel-value/number-texture.js +++ b/src/backend/web-gl/kernel-value/number-texture.js @@ -1,47 +1,43 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueNumberTexture extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - const [width, height] = value.size; - this.checkSize(width, height); - this.setupTexture(); - const { size: textureSize, dimensions } = value; - this.bitRatio = this.getBitRatio(value); - this.dimensions = dimensions; - this.textureSize = textureSize; - this.uploadValue = value.texture; - this.forceUploadEachRun = true; - } - - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(inputTexture) { - if (inputTexture.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - if (this.checkContext && inputTexture.context !== this.context) { - throw new Error(`Value ${this.name} (${this.type}) must be from same context`); - } - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueNumberTexture extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + const [width, height] = value.size; + this.checkSize(width, height); + this.setupTexture(); + const { size: textureSize, dimensions } = value; + this.bitRatio = this.getBitRatio(value); + this.dimensions = dimensions; + this.textureSize = textureSize; + this.uploadValue = value.texture; + this.forceUploadEachRun = true; + } + + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName}.texture;\n`; + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(inputTexture) { + if (inputTexture.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + if (this.checkContext && inputTexture.context !== this.context) { + throw new Error(`Value ${this.name} (${this.type}) must be from same context`); + } + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.uploadValue = inputTexture.texture); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array.js b/src/backend/web-gl/kernel-value/single-array.js index 1cca1b0b..0dc477b1 100644 --- a/src/backend/web-gl/kernel-value/single-array.js +++ b/src/backend/web-gl/kernel-value/single-array.js @@ -1,51 +1,47 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.dimensions = utils.getDimensions(value, true); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + + getStringValueHandler() { + return utils.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array1d-i.js b/src/backend/web-gl/kernel-value/single-array1d-i.js index 999f7820..9d6a3d46 100644 --- a/src/backend/web-gl/kernel-value/single-array1d-i.js +++ b/src/backend/web-gl/kernel-value/single-array1d-i.js @@ -1,56 +1,52 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], 1, 1]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten2dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray1DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray1DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + + setShape(value) { + const valueDimensions = utils.getDimensions(value, true); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], 1, 1]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + + getStringValueHandler() { + return utils.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flatten2dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array2.js b/src/backend/web-gl/kernel-value/single-array2.js index 4121a675..fa1edd27 100644 --- a/src/backend/web-gl/kernel-value/single-array2.js +++ b/src/backend/web-gl/kernel-value/single-array2.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`; - } - return `uniform vec2 ${this.id};\n`; - } - - getStringValueHandler() { - // resetting isn't supported for Array(2) - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform2fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray2 -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray2 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec2 ${this.id} = vec2(${value[0]},${value[1]});\n`; + } + return `uniform vec2 ${this.id};\n`; + } + + getStringValueHandler() { + // resetting isn't supported for Array(2) + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform2fv(this.id, this.uploadValue = value); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array2d-i.js b/src/backend/web-gl/kernel-value/single-array2d-i.js index 22419a3a..b9f378f8 100644 --- a/src/backend/web-gl/kernel-value/single-array2d-i.js +++ b/src/backend/web-gl/kernel-value/single-array2d-i.js @@ -1,56 +1,52 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten3dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray2DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray2DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + + setShape(value) { + const valueDimensions = utils.getDimensions(value, true); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], 1]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + + getStringValueHandler() { + return utils.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flatten3dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array3.js b/src/backend/web-gl/kernel-value/single-array3.js index 56781a8b..ce318c2c 100644 --- a/src/backend/web-gl/kernel-value/single-array3.js +++ b/src/backend/web-gl/kernel-value/single-array3.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`; - } - return `uniform vec3 ${this.id};\n`; - } - - getStringValueHandler() { - // resetting isn't supported for Array(3) - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform3fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray3 -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray3 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec3 ${this.id} = vec3(${value[0]},${value[1]},${value[2]});\n`; + } + return `uniform vec3 ${this.id};\n`; + } + + getStringValueHandler() { + // resetting isn't supported for Array(3) + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform3fv(this.id, this.uploadValue = value); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array3d-i.js b/src/backend/web-gl/kernel-value/single-array3d-i.js index 236829a8..27aa7319 100644 --- a/src/backend/web-gl/kernel-value/single-array3d-i.js +++ b/src/backend/web-gl/kernel-value/single-array3d-i.js @@ -1,56 +1,52 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - this.setShape(value); - } - - setShape(value) { - const valueDimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); - this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flatten4dArrayTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleArray3DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray3DI extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + this.setShape(value); + } + + setShape(value) { + const valueDimensions = utils.getDimensions(value, true); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(valueDimensions, this.bitRatio); + this.dimensions = new Int32Array([valueDimensions[1], valueDimensions[2], valueDimensions[3]]); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + + getStringValueHandler() { + return utils.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}, uploadValue_${this.name})`, + ]); + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flatten4dArrayTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/single-array4.js b/src/backend/web-gl/kernel-value/single-array4.js index c5d93f48..4fd5512c 100644 --- a/src/backend/web-gl/kernel-value/single-array4.js +++ b/src/backend/web-gl/kernel-value/single-array4.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleArray4 extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.uploadValue = value; - } - getSource(value) { - if (this.origin === 'constants') { - return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`; - } - return `uniform vec4 ${this.id};\n`; - } - - getStringValueHandler() { - // resetting isn't supported for Array(4) - if (this.origin === 'constants') return ''; - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform4fv(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGLKernelValueSingleArray4 -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleArray4 extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.uploadValue = value; + } + getSource(value) { + if (this.origin === 'constants') { + return `const vec4 ${this.id} = vec4(${value[0]},${value[1]},${value[2]},${value[3]});\n`; + } + return `uniform vec4 ${this.id};\n`; + } + + getStringValueHandler() { + // resetting isn't supported for Array(4) + if (this.origin === 'constants') return ''; + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform4fv(this.id, this.uploadValue = value); + } +} diff --git a/src/backend/web-gl/kernel-value/single-input.js b/src/backend/web-gl/kernel-value/single-input.js index 2124d43d..651074d7 100644 --- a/src/backend/web-gl/kernel-value/single-input.js +++ b/src/backend/web-gl/kernel-value/single-input.js @@ -1,52 +1,48 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueSingleInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = 4; - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - } - - getStringValueHandler() { - return utils.linesToString([ - `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, - `flattenTo(${this.varName}.value, uploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(input) { - if (input.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueSingleInput -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueSingleInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = 4; + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + } + + getStringValueHandler() { + return utils.linesToString([ + `const uploadValue_${this.name} = new Float32Array(${this.uploadArrayLength})`, + `flattenTo(${this.varName}.value, uploadValue_${this.name})`, + ]); + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(input) { + if (input.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(input.value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/unsigned-array.js b/src/backend/web-gl/kernel-value/unsigned-array.js index 753932e0..f3bfed0c 100644 --- a/src/backend/web-gl/kernel-value/unsigned-array.js +++ b/src/backend/web-gl/kernel-value/unsigned-array.js @@ -1,54 +1,50 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = this.getBitRatio(value); - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - this.TranserArrayType = this.getTransferArrayType(value); - this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - } - - getStringValueHandler() { - return utils.linesToString([ - `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, - `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, - `flattenTo(${this.varName}, preUploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.preUploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueUnsignedArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueUnsignedArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + this.dimensions = utils.getDimensions(value, true); + this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + + getStringValueHandler() { + return utils.linesToString([ + `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, + `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, + `flattenTo(${this.varName}, preUploadValue_${this.name})`, + ]); + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.preUploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel-value/unsigned-input.js b/src/backend/web-gl/kernel-value/unsigned-input.js index 9cb720bc..a9397e62 100644 --- a/src/backend/web-gl/kernel-value/unsigned-input.js +++ b/src/backend/web-gl/kernel-value/unsigned-input.js @@ -1,55 +1,51 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('./index'); - -class WebGLKernelValueUnsignedInput extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.requestTexture(); - this.bitRatio = this.getBitRatio(value); - const [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); - this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); - this.TranserArrayType = this.getTransferArrayType(value.value); - this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); - this.uploadValue = new Uint8Array(this.preUploadValue.buffer); - } - - getStringValueHandler() { - return utils.linesToString([ - `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, - `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, - `flattenTo(${this.varName}.value, preUploadValue_${this.name})`, - ]); - } - - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(input) { - if (input.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(input.value, this.preUploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGLKernelValueUnsignedInput -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from './index'; + +export class WebGLKernelValueUnsignedInput extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.requestTexture(); + this.bitRatio = this.getBitRatio(value); + const [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils.getMemoryOptimizedPackedTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * (4 / this.bitRatio); + this.checkSize(this.textureSize[0] * (4 / this.bitRatio), this.textureSize[1] * (4 / this.bitRatio)); + this.TranserArrayType = this.getTransferArrayType(value.value); + this.preUploadValue = new this.TranserArrayType(this.uploadArrayLength); + this.uploadValue = new Uint8Array(this.preUploadValue.buffer); + } + + getStringValueHandler() { + return utils.linesToString([ + `const preUploadValue_${this.name} = new ${this.TranserArrayType.name}(${this.uploadArrayLength})`, + `const uploadValue_${this.name} = new Uint8Array(preUploadValue_${this.name}.buffer)`, + `flattenTo(${this.varName}.value, preUploadValue_${this.name})`, + ]); + } + + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(input) { + if (input.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(input.value, this.preUploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl/kernel.js b/src/backend/web-gl/kernel.js index e7340391..ad15f268 100644 --- a/src/backend/web-gl/kernel.js +++ b/src/backend/web-gl/kernel.js @@ -1,1567 +1,1557 @@ -const { GLKernel } = require('../gl/kernel'); -const { FunctionBuilder } = require('../function-builder'); -const { WebGLFunctionNode } = require('./function-node'); -const { utils } = require('../../utils'); -const triangleNoise = require('../../plugins/triangle-noise'); -const { fragmentShader } = require('./fragment-shader'); -const { vertexShader } = require('./vertex-shader'); -const { glKernelString } = require('../gl/kernel-string'); -const { lookupKernelValueType } = require('./kernel-value-maps'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; -let features = null; - -const plugins = [triangleNoise]; -const canvases = []; -const maxTexSizes = {}; - - -/** - * @desc Kernel Implementation for WebGL. - *

This builds the shaders and runs them on the GPU, - * the outputs the result back as float(enabled by default) and Texture.

- * - * @prop {Object} textureCache - webGl Texture cache - * @prop {Object} programUniformLocationCache - Location of program variables in memory - * @prop {Object} framebuffer - Webgl frameBuffer - * @prop {Object} buffer - WebGL buffer - * @prop {Object} program - The webGl Program - * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel - * @prop {Boolean} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float - * @prop {String} endianness - Endian information like Little-endian, Big-endian. - * @prop {Array} argumentTypes - Types of parameters sent to the Kernel - * @prop {String} compiledFragmentShader - Compiled fragment shader string - * @prop {String} compiledVertexShader - Compiled Vertical shader string - * @extends GLKernel - */ -class WebGLKernel extends GLKernel { - static get isSupported() { - if (isSupported !== null) { - return isSupported; - } - this.setupFeatureChecks(); - isSupported = this.isContextMatch(testContext); - return isSupported; - } - - static setupFeatureChecks() { - if (typeof document !== 'undefined') { - testCanvas = document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - testCanvas = new OffscreenCanvas(0, 0); - } - if (!testCanvas) return; - testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - OES_texture_float: testContext.getExtension('OES_texture_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), - }; - features = this.getFeatures(); - } - - static isContextMatch(context) { - if (typeof WebGLRenderingContext !== 'undefined') { - return context instanceof WebGLRenderingContext; - } - return false; - } - - static getFeatures() { - const isDrawBuffers = this.getIsDrawBuffers(); - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - isTextureFloat: this.getIsTextureFloat(), - isDrawBuffers, - kernelMap: isDrawBuffers, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - static getIsTextureFloat() { - return Boolean(testExtensions.OES_texture_float); - } - - static getIsDrawBuffers() { - return Boolean(testExtensions.WEBGL_draw_buffers); - } - - static getChannelCount() { - return testExtensions.WEBGL_draw_buffers ? - testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : - 1; - } - - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); - } - - static lookupKernelValueType(type, dynamic, precision, value) { - return lookupKernelValueType(type, dynamic, precision, value); - } - - static get testCanvas() { - return testCanvas; - } - - static get testContext() { - return testContext; - } - - static get features() { - return features; - } - - static get fragmentShader() { - return fragmentShader; - } - - static get vertexShader() { - return vertexShader; - } - - /** - * - * @param {String} source - * @param {IKernelSettings} settings - */ - constructor(source, settings) { - super(source, settings); - this.program = null; - this.pipeline = settings.pipeline; - this.endianness = utils.systemEndianness(); - this.extensions = {}; - this.subKernelOutputTextures = null; - this.kernelArguments = null; - this.argumentTextureCount = 0; - this.constantTextureCount = 0; - this.compiledFragmentShader = null; - this.compiledVertexShader = null; - this.fragShader = null; - this.vertShader = null; - this.drawBuffersMap = null; - this.outputTexture = null; - - /** - * - * @type {Int32Array|null} - */ - this.maxTexSize = null; - this.switchingKernels = false; - this.onRequestSwitchKernel = null; - - this.mergeSettings(source.settings || settings); - - /** - * The thread dimensions, x, y and z - * @type {Array|null} - */ - this.threadDim = null; - this.framebuffer = null; - this.buffer = null; - this.textureCache = {}; - this.programUniformLocationCache = {}; - this.uniform1fCache = {}; - this.uniform1iCache = {}; - this.uniform2fCache = {}; - this.uniform2fvCache = {}; - this.uniform2ivCache = {}; - this.uniform3fvCache = {}; - this.uniform3ivCache = {}; - this.uniform4fvCache = {}; - this.uniform4ivCache = {}; - } - - initCanvas() { - if (typeof document !== 'undefined') { - const canvas = document.createElement('canvas'); - // Default width and height, to fix webgl issue in safari - canvas.width = 2; - canvas.height = 2; - return canvas; - } else if (typeof OffscreenCanvas !== 'undefined') { - return new OffscreenCanvas(0, 0); - } - } - - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings); - } - - initPlugins(settings) { - // default plugins - const pluginsToUse = []; - const { source } = this; - if (typeof source === 'string') { - for (let i = 0; i < plugins.length; i++) { - const plugin = plugins[i]; - if (source.match(plugin.functionMatch)) { - pluginsToUse.push(plugin); - } - } - } else if (typeof source === 'object') { - // `source` is from object, json - if (settings.pluginNames) { //TODO: in context of JSON support, pluginNames may not exist here - for (let i = 0; i < plugins.length; i++) { - const plugin = plugins[i]; - const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name); - if (usePlugin) { - pluginsToUse.push(plugin); - } - } - } - } - return pluginsToUse; - } - - initExtensions() { - this.extensions = { - OES_texture_float: this.context.getExtension('OES_texture_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), - WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), - WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'), - }; - } - - /** - * @desc Validate settings related to Kernel, such as dimensions size, and auto output support. - * @param {IArguments} args - */ - validateSettings(args) { - if (!this.validate) { - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - return; - } - - const { features } = this.constructor; - - if (this.optimizeFloatMemory === true && !features.isTextureFloat) { - throw new Error('Float textures are not supported'); - } else if (this.precision === 'single' && !features.isFloatRead) { - throw new Error('Single precision not supported'); - } else if (!this.graphical && this.precision === null && features.isTextureFloat) { - this.precision = features.isFloatRead ? 'single' : 'unsigned'; - } - - if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) { - throw new Error('could not instantiate draw buffers extension'); - } - - if (this.fixIntegerDivisionAccuracy === null) { - this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; - } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { - this.fixIntegerDivisionAccuracy = false; - } - - this.checkOutput(); - - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); - } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - if (argType === 'Array') { - this.output = utils.getDimensions(argType); - } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { - this.output = args[0].output; - } else { - throw new Error('Auto output not supported for input type: ' + argType); - } - } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); - } - - if (this.precision === 'precision') { - this.precision = 'unsigned'; - console.warn('Cannot use graphical mode and single precision at the same time'); - } - - this.texSize = utils.clone(this.output); - return; - } else if (this.precision === null && features.isTextureFloat) { - this.precision = 'single'; - } - - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - - this.checkTextureSize(); - } - - updateMaxTexSize() { - const { texSize, canvas } = this; - if (this.maxTexSize === null) { - let canvasIndex = canvases.indexOf(canvas); - if (canvasIndex === -1) { - canvasIndex = canvases.length; - canvases.push(canvas); - maxTexSizes[canvasIndex] = [texSize[0], texSize[1]]; - } - this.maxTexSize = maxTexSizes[canvasIndex]; - } - if (this.maxTexSize[0] < texSize[0]) { - this.maxTexSize[0] = texSize[0]; - } - if (this.maxTexSize[1] < texSize[1]) { - this.maxTexSize[1] = texSize[1]; - } - } - - // TODO: move channel checks to new place - _oldtranslateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - - // need this line to automatically get returnType - const translatedSource = functionBuilder.getPrototypeString('kernel'); - - if (!this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - - let requiredChannels = 0; - const returnTypes = functionBuilder.getReturnTypes(); - for (let i = 0; i < returnTypes.length; i++) { - switch (returnTypes[i]) { - case 'Float': - case 'Number': - case 'Integer': - requiredChannels++; - break; - case 'Array(2)': - requiredChannels += 2; - break; - case 'Array(3)': - requiredChannels += 3; - break; - case 'Array(4)': - requiredChannels += 4; - break; - } - } - - if (features && requiredChannels > features.channelCount) { - throw new Error('Too many channels!'); - } - - return this.translatedSource = translatedSource; - } - - setupArguments(args) { - this.kernelArguments = []; - this.argumentTextureCount = 0; - const needsArgumentTypes = this.argumentTypes === null; - // TODO: remove - if (needsArgumentTypes) { - this.argumentTypes = []; - } - this.argumentSizes = []; - this.argumentBitRatios = []; - // TODO: end remove - - if (args.length < this.argumentNames.length) { - throw new Error('not enough arguments for kernel'); - } else if (args.length > this.argumentNames.length) { - throw new Error('too many arguments for kernel'); - } - - const { context: gl } = this; - let textureIndexes = 0; - for (let index = 0; index < args.length; index++) { - const value = args[index]; - const name = this.argumentNames[index]; - let type; - if (needsArgumentTypes) { - type = utils.getVariableType(value, this.strictIntegers); - this.argumentTypes.push(type); - } else { - type = this.argumentTypes[index]; - } - const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]); - if (KernelValue === null) { - return this.requestFallback(args); - } - const kernelArgument = new KernelValue(value, { - name, - type, - tactic: this.tactic, - origin: 'user', - context: gl, - checkContext: this.checkContext, - kernel: this, - strictIntegers: this.strictIntegers, - onRequestTexture: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onUpdateValueMismatch: () => { - this.switchingKernels = true; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; - } - }); - this.kernelArguments.push(kernelArgument); - this.argumentSizes.push(kernelArgument.textureSize); - this.argumentBitRatios[index] = kernelArgument.bitRatio; - } - } - - setupConstants(args) { - const { context: gl } = this; - this.kernelConstants = []; - this.forceUploadKernelConstants = []; - let needsConstantTypes = this.constantTypes === null; - if (needsConstantTypes) { - this.constantTypes = {}; - } - this.constantBitRatios = {}; - let textureIndexes = 0; - for (const name in this.constants) { - const value = this.constants[name]; - let type; - if (needsConstantTypes) { - type = utils.getVariableType(value, this.strictIntegers); - this.constantTypes[name] = type; - } else { - type = this.constantTypes[name]; - } - const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value); - if (KernelValue === null) { - return this.requestFallback(args); - } - const kernelValue = new KernelValue(value, { - name, - type, - tactic: this.tactic, - origin: 'constants', - context: this.context, - checkContext: this.checkContext, - kernel: this, - strictIntegers: this.strictIntegers, - onRequestTexture: () => { - return this.context.createTexture(); - }, - onRequestIndex: () => { - return textureIndexes++; - }, - onRequestContextHandle: () => { - return gl.TEXTURE0 + this.constantTextureCount++; - } - }); - this.constantBitRatios[name] = kernelValue.bitRatio; - this.kernelConstants.push(kernelValue); - if (kernelValue.forceUploadEachRun) { - this.forceUploadKernelConstants.push(kernelValue); - } - } - } - - build() { - this.initExtensions(); - this.validateSettings(arguments); - this.setupConstants(arguments); - if (this.fallbackRequested) return; - this.setupArguments(arguments); - if (this.fallbackRequested) return; - this.updateMaxTexSize(); - this.translateSource(); - const failureResult = this.pickRenderStrategy(arguments); - if (failureResult) { - return failureResult; - } - const { texSize, context: gl, canvas } = this; - gl.enable(gl.SCISSOR_TEST); - if (this.pipeline && this.precision === 'single') { - gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - canvas.width = this.maxTexSize[0]; - canvas.height = this.maxTexSize[1]; - } else { - gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); - canvas.width = this.maxTexSize[0]; - canvas.height = this.maxTexSize[1]; - } - const threadDim = this.threadDim = Array.from(this.output); - while (threadDim.length < 3) { - threadDim.push(1); - } - - const compiledVertexShader = this.getVertexShader(arguments); - const vertShader = gl.createShader(gl.VERTEX_SHADER); - gl.shaderSource(vertShader, compiledVertexShader); - gl.compileShader(vertShader); - this.vertShader = vertShader; - - const compiledFragmentShader = this.getFragmentShader(arguments); - const fragShader = gl.createShader(gl.FRAGMENT_SHADER); - gl.shaderSource(fragShader, compiledFragmentShader); - gl.compileShader(fragShader); - this.fragShader = fragShader; - - if (this.debug) { - console.log('GLSL Shader Output:'); - console.log(compiledFragmentShader); - } - - if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) { - throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader)); - } - if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) { - throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader)); - } - - const program = this.program = gl.createProgram(); - gl.attachShader(program, vertShader); - gl.attachShader(program, fragShader); - gl.linkProgram(program); - this.framebuffer = gl.createFramebuffer(); - this.framebuffer.width = texSize[0]; - this.framebuffer.height = texSize[1]; - - const vertices = new Float32Array([-1, -1, - 1, -1, -1, 1, - 1, 1 - ]); - const texCoords = new Float32Array([ - 0, 0, - 1, 0, - 0, 1, - 1, 1 - ]); - - const texCoordOffset = vertices.byteLength; - - let buffer = this.buffer; - if (!buffer) { - buffer = this.buffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW); - } else { - gl.bindBuffer(gl.ARRAY_BUFFER, buffer); - } - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); - gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords); - - const aPosLoc = gl.getAttribLocation(this.program, 'aPos'); - gl.enableVertexAttribArray(aPosLoc); - gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0); - const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord'); - gl.enableVertexAttribArray(aTexCoordLoc); - gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - - let i = 0; - gl.useProgram(this.program); - for (let p in this.constants) { - this.kernelConstants[i++].updateValue(this.constants[p]); - } - - if (!this.immutable) { - this._setupOutputTexture(); - if ( - this.subKernels !== null && - this.subKernels.length > 0 - ) { - this._setupSubOutputTextures(); - } - } - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - - if (this.subKernels && this.subKernels.length > 0) { - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (!subKernel.returnType) { - subKernel.returnType = functionBuilder.getSubKernelResultType(i); - } - } - } - } - - run() { - const { kernelArguments, forceUploadKernelConstants } = this; - const texSize = this.texSize; - const gl = this.context; - - gl.useProgram(this.program); - gl.scissor(0, 0, texSize[0], texSize[1]); - - if (this.dynamicOutput) { - this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); - this.setUniform2iv('uTexSize', texSize); - } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.switchingKernels = false; - for (let i = 0; i < forceUploadKernelConstants.length; i++) { - const constant = forceUploadKernelConstants[i]; - constant.updateValue(this.constants[constant.name]); - if (this.switchingKernels) return; - } - for (let i = 0; i < kernelArguments.length; i++) { - kernelArguments[i].updateValue(arguments[i]); - if (this.switchingKernels) return; - } - - if (this.plugins) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.onBeforeRun) { - plugin.onBeforeRun(this); - } - } - } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); - } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context, - }); - } - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return; - } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.immutable) { - this._setupOutputTexture(); - } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); - } - this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); - } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - /** - * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run() - * @returns {Object} Output Texture Cache - */ - getOutputTexture() { - return this.outputTexture; - } - - /** - * @desc Setup and replace output texture - */ - _setupOutputTexture() { - const gl = this.context; - const texSize = this.texSize; - const texture = this.outputTexture = this.context.createTexture(); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - // if (this.precision === 'single') { - // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - // } else { - // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - // } - if (this.precision === 'single') { - if (this.pipeline) { - // TODO: investigate if webgl1 can handle gl.RED usage in gl.texImage2D, otherwise, simplify the below - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - if (this.optimizeFloatMemory) { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } - break; - case 'Array(2)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - case 'Array(3)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - case 'Array(4)': - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - break; - default: - if (!this.graphical) { - throw new Error('Unhandled return type'); - } - } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - /** - * @desc Setup and replace sub-output textures - */ - _setupSubOutputTextures() { - const gl = this.context; - const texSize = this.texSize; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.precision === 'single') { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); - } - } - - /** - * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument) - * @param {String} name - Name of the subkernel, argument, or kernel. - * @returns {Object} Texture cache - */ - getTextureCache(name) { - if (this.textureCache.hasOwnProperty(name)) { - return this.textureCache[name]; - } - return this.textureCache[name] = this.context.createTexture(); - } - - /** - * @desc removes a texture from the kernel's cache - * @param {String} name - Name of texture - */ - detachTextureCache(name) { - delete this.textureCache[name]; - } - - setUniform1f(name, value) { - if (this.uniform1fCache.hasOwnProperty(name)) { - const cache = this.uniform1fCache[name]; - if (value === cache) { - return; - } - } - this.uniform1fCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform1f(loc, value); - } - - setUniform1i(name, value) { - if (this.uniform1iCache.hasOwnProperty(name)) { - const cache = this.uniform1iCache[name]; - if (value === cache) { - return; - } - } - this.uniform1iCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform1i(loc, value); - } - - setUniform2f(name, value1, value2) { - if (this.uniform2fCache.hasOwnProperty(name)) { - const cache = this.uniform2fCache[name]; - if ( - value1 === cache[0] && - value2 === cache[1] - ) { - return; - } - } - this.uniform2fCache[name] = [value1, value2]; - const loc = this.getUniformLocation(name); - this.context.uniform2f(loc, value1, value2); - } - - setUniform2fv(name, value) { - if (this.uniform2fvCache.hasOwnProperty(name)) { - const cache = this.uniform2fvCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] - ) { - return; - } - } - this.uniform2fvCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform2fv(loc, value); - } - - setUniform2iv(name, value) { - if (this.uniform2ivCache.hasOwnProperty(name)) { - const cache = this.uniform2ivCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] - ) { - return; - } - } - this.uniform2ivCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform2iv(loc, value); - } - - setUniform3fv(name, value) { - if (this.uniform3fvCache.hasOwnProperty(name)) { - const cache = this.uniform3fvCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] - ) { - return; - } - } - this.uniform3fvCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform3fv(loc, value); - } - - setUniform3iv(name, value) { - if (this.uniform3ivCache.hasOwnProperty(name)) { - const cache = this.uniform3ivCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] - ) { - return; - } - } - this.uniform3ivCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform3iv(loc, value); - } - - setUniform3fv(name, value) { - if (this.uniform3fvCache.hasOwnProperty(name)) { - const cache = this.uniform3fvCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] - ) { - return; - } - } - this.uniform3fvCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform3fv(loc, value); - } - - setUniform4iv(name, value) { - if (this.uniform4ivCache.hasOwnProperty(name)) { - const cache = this.uniform4ivCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] && - value[3] === cache[3] - ) { - return; - } - } - this.uniform4ivCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform4iv(loc, value); - } - - setUniform4fv(name, value) { - if (this.uniform4fvCache.hasOwnProperty(name)) { - const cache = this.uniform4fvCache[name]; - if ( - value[0] === cache[0] && - value[1] === cache[1] && - value[2] === cache[2] && - value[3] === cache[3] - ) { - return; - } - } - this.uniform4fvCache[name] = value; - const loc = this.getUniformLocation(name); - this.context.uniform4fv(loc, value); - } - - /** - * @desc Return WebGlUniformLocation for various variables - * related to webGl program, such as user-defined variables, - * as well as, dimension sizes, etc. - */ - getUniformLocation(name) { - if (this.programUniformLocationCache.hasOwnProperty(name)) { - return this.programUniformLocationCache[name]; - } - return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name); - } - - /** - * @desc Generate Shader artifacts for the kernel program. - * The final object contains HEADER, KERNEL, MAIN_RESULT, and others. - * - * @param {Array} args - The actual parameters sent to the Kernel - * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.) - */ - _getFragShaderArtifactMap(args) { - return { - HEADER: this._getHeaderString(), - LOOP_MAX: this._getLoopMaxString(), - PLUGINS: this._getPluginsString(), - CONSTANTS: this._getConstantsString(), - DECODE32_ENDIANNESS: this._getDecode32EndiannessString(), - ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(), - DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(), - INJECTED_NATIVE: this._getInjectedNative(), - MAIN_CONSTANTS: this._getMainConstantsString(), - MAIN_ARGUMENTS: this._getMainArgumentsString(args), - KERNEL: this.getKernelString(), - MAIN_RESULT: this.getMainResultString(), - FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), - INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), - SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), - SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), - }; - } - - /** - * @desc Generate Shader artifacts for the kernel program. - * The final object contains HEADER, KERNEL, MAIN_RESULT, and others. - * - * @param {Array} args - The actual parameters sent to the Kernel - * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.) - */ - _getVertShaderArtifactMap(args) { - return { - FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), - INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), - SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), - SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), - }; - } - - /** - * @desc Get the header string for the program. - * This returns an empty string if no sub-kernels are defined. - * - * @returns {String} result - */ - _getHeaderString() { - return ( - this.subKernels !== null ? - '#extension GL_EXT_draw_buffers : require\n' : - '' - ); - } - - /** - * @desc Get the maximum loop size String. - * @returns {String} result - */ - _getLoopMaxString() { - return ( - this.loopMaxIterations ? - ` ${parseInt(this.loopMaxIterations)};\n` : - ' 1000;\n' - ); - } - - _getPluginsString() { - if (!this.plugins) return '\n'; - return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n'); - } - - /** - * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel - * @returns {String} result - */ - _getConstantsString() { - const result = []; - const { threadDim, texSize } = this; - if (this.dynamicOutput) { - result.push( - 'uniform ivec3 uOutputDim', - 'uniform ivec2 uTexSize' - ); - } else { - result.push( - `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`, - `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})` - ); - } - return utils.linesToString(result); - } - - /** - * @desc Get texture coordinate string for the program - * @returns {String} result - */ - _getTextureCoordinate() { - const subKernels = this.subKernels; - if (subKernels === null || subKernels.length < 1) { - return 'varying vec2 vTexCoord;\n'; - } else { - return 'out vec2 vTexCoord;\n'; - } - } - - /** - * @desc Get Decode32 endianness string for little-endian and big-endian - * @returns {String} result - */ - _getDecode32EndiannessString() { - return ( - this.endianness === 'LE' ? - '' : - ' texel.rgba = texel.abgr;\n' - ); - } - - /** - * @desc Get Encode32 endianness string for little-endian and big-endian - * @returns {String} result - */ - _getEncode32EndiannessString() { - return ( - this.endianness === 'LE' ? - '' : - ' texel.rgba = texel.abgr;\n' - ); - } - - /** - * @desc if fixIntegerDivisionAccuracy provide method to replace / - * @returns {String} result - */ - _getDivideWithIntegerCheckString() { - return this.fixIntegerDivisionAccuracy ? - `float div_with_int_check(float x, float y) { - if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { - return float(int(x)/int(y)); - } - return x / y; -}` : - ''; - } - - /** - * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel - * @param {Array} args - The actual parameters sent to the Kernel - * @returns {String} result - */ - _getMainArgumentsString(args) { - const results = []; - const { argumentNames } = this; - for (let i = 0; i < argumentNames.length; i++) { - results.push(this.kernelArguments[i].getSource(args[i])); - } - return results.join(''); - } - - _getInjectedNative() { - return this.injectedNative || ''; - } - - _getMainConstantsString() { - const result = []; - const { constants } = this; - if (constants) { - let i = 0; - for (const name in constants) { - result.push(this.kernelConstants[i++].getSource(this.constants[name])); - } - } - return result.join(''); - } - - /** - * @desc Get Kernel program string (in *glsl*) for a kernel. - * @returns {String} result - */ - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; - } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); - } - } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration - ); - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - for (let i = 0; i < subKernels.length; i++) { - const subKernel = subKernels[i]; - result.push( - subKernel.returnType === 'Integer' ? - `int subKernelResult_${ subKernel.name } = 0` : - `float subKernelResult_${ subKernel.name } = 0.0` - ); - } - break; - case 'Array(2)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec2 subKernelResult_${ subKernels[i].name }` - ); - } - break; - case 'Array(3)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec3 subKernelResult_${ subKernels[i].name }` - ); - } - break; - case 'Array(4)': - for (let i = 0; i < subKernels.length; i++) { - result.push( - `vec4 subKernelResult_${ subKernels[i].name }` - ); - } - break; - } - } else { - result.push( - kernelResultDeclaration - ); - } - - return utils.linesToString(result) + this.translatedSource; - } - - getMainResultGraphical() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragColor = actualColor', - ]); - } - - getMainResultPackedPixels() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return this.getMainResultKernelPackedPixels() + - this.getMainResultSubKernelPackedPixels(); - default: - throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); - } - } - - /** - * @return {String} - */ - getMainResultKernelPackedPixels() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` - ]); - } - - /** - * @return {String} - */ - getMainResultSubKernelPackedPixels() { - const result = []; - if (!this.subKernels) return ''; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` - ); - } else { - result.push( - ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` - ); - } - } - return utils.linesToString(result); - } - - getMainResultMemoryOptimizedFloats() { - const result = [ - ' index *= 4', - ]; - - switch (this.returnType) { - case 'Number': - case 'Integer': - case 'Float': - const channels = ['r', 'g', 'b', 'a']; - for (let i = 0; i < channels.length; i++) { - const channel = channels[i]; - this.getMainResultKernelMemoryOptimizedFloats(result, channel); - this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); - if (i + 1 < channels.length) { - result.push(' index += 1'); - } - } - break; - default: - throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); - } - - return utils.linesToString(result); - } - - getMainResultKernelMemoryOptimizedFloats(result, channel) { - result.push( - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` gl_FragData[0].${channel} = kernelResult`, - ); - } - - getMainResultSubKernelMemoryOptimizedFloats(result, channel) { - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`, - ); - } else { - result.push( - ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`, - ); - } - } - } - - getMainResultKernelNumberTexture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult', - ]; - } - - getMainResultSubKernelNumberTexture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`, - ); - } else { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`, - ); - } - } - return result; - } - - getMainResultKernelArray2Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult[0]', - ' gl_FragData[0][1] = kernelResult[1]', - ]; - } - - getMainResultSubKernelArray2Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ); - } - return result; - } - - getMainResultKernelArray3Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0][0] = kernelResult[0]', - ' gl_FragData[0][1] = kernelResult[1]', - ' gl_FragData[0][2] = kernelResult[2]', - ]; - } - - getMainResultSubKernelArray3Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ); - } - return result; - } - - getMainResultKernelArray4Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' gl_FragData[0] = kernelResult', - ]; - } - - getMainResultSubKernelArray4Texture() { - const result = []; - if (!this.subKernels) return result; - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`, - ); - } else { - result.push( - ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`, - ); - } - } - break; - case 'Array(2)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ); - } - break; - case 'Array(3)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ); - } - break; - case 'Array(4)': - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, - ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, - ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, - ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`, - ); - } - break; - } - - return result; - } - - /** - * @param {String} src - Shader string - * @param {Object} map - Variables/Constants associated with shader - */ - replaceArtifacts(src, map) { - return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => { - if (map.hasOwnProperty(artifact)) { - return map[artifact]; - } - throw `unhandled artifact ${artifact}`; - }); - } - - /** - * @desc Get the fragment shader String. - * If the String hasn't been compiled yet, - * then this method compiles it as well - * - * @param {Array} args - The actual parameters sent to the Kernel - * @returns {string} Fragment Shader string - */ - getFragmentShader(args) { - if (this.compiledFragmentShader !== null) { - return this.compiledFragmentShader; - } - return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args)); - } - - /** - * @desc Get the vertical shader String - * @param {Array|IArguments} args - The actual parameters sent to the Kernel - * @returns {string} Vertical Shader string - */ - getVertexShader(args) { - if (this.compiledVertexShader !== null) { - return this.compiledVertexShader; - } - return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args)); - } - - /** - * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused. - */ - toString() { - const setupContextString = utils.linesToString([ - `const gl = context`, - ]); - return glKernelString(this.constructor, arguments, this, setupContextString); - } - - destroy(removeCanvasReferences) { - if (this.outputTexture) { - this.context.deleteTexture(this.outputTexture); - } - if (this.buffer) { - this.context.deleteBuffer(this.buffer); - } - if (this.framebuffer) { - this.context.deleteFramebuffer(this.framebuffer); - } - if (this.vertShader) { - this.context.deleteShader(this.vertShader); - } - if (this.fragShader) { - this.context.deleteShader(this.fragShader); - } - if (this.program) { - this.context.deleteProgram(this.program); - } - - const keys = Object.keys(this.textureCache); - - for (let i = 0; i < keys.length; i++) { - const name = keys[i]; - this.context.deleteTexture(this.textureCache[name]); - } - - if (this.subKernelOutputTextures) { - for (let i = 0; i < this.subKernelOutputTextures.length; i++) { - this.context.deleteTexture(this.subKernelOutputTextures[i]); - } - } - if (removeCanvasReferences) { - const idx = canvases.indexOf(this.canvas); - if (idx >= 0) { - canvases[idx] = null; - maxTexSizes[idx] = null; - } - } - this.destroyExtensions(); - delete this.context; - delete this.canvas; - } - - destroyExtensions() { - this.extensions.OES_texture_float = null; - this.extensions.OES_texture_float_linear = null; - this.extensions.OES_element_index_uint = null; - this.extensions.WEBGL_draw_buffers = null; - } - - static destroyContext(context) { - const extension = context.getExtension('WEBGL_lose_context'); - if (extension) { - extension.loseContext(); - } - } - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); - return json; - } -} - -module.exports = { - WebGLKernel -}; \ No newline at end of file +import { GLKernel } from '../gl/kernel'; +import { FunctionBuilder } from '../function-builder'; +import { WebGLFunctionNode } from './function-node'; +import { utils } from '../../utils'; +import triangleNoise from '../../plugins/triangle-noise'; +import { fragmentShader } from './fragment-shader'; +import { vertexShader } from './vertex-shader'; +import { glKernelString } from '../gl/kernel-string'; +import { lookupKernelValueType } from './kernel-value-maps'; + +let isSupported = null; +let testCanvas = null; +let testContext = null; +let testExtensions = null; +let features = null; + +const plugins = [triangleNoise]; +const canvases = []; +const maxTexSizes = {}; + +/** + * @desc Kernel Implementation for WebGL. + * + * This builds the shaders and runs them on the GPU, then outputs the result + * back as float (enabled by default) and Texture. + * + * @prop {Object} textureCache - webGl Texture cache + * @prop {Object} programUniformLocationCache - Location of program variables in memory + * @prop {Object} framebuffer - Webgl frameBuffer + * @prop {Object} buffer - WebGL buffer + * @prop {Object} program - The webGl Program + * @prop {Object} functionBuilder - Function Builder instance bound to this Kernel + * @prop {Boolean} pipeline - Set output type to FAST mode (GPU to GPU via Textures), instead of float + * @prop {String} endianness - Endian information like Little-endian, Big-endian. + * @prop {Array} argumentTypes - Types of parameters sent to the Kernel + * @prop {String} compiledFragmentShader - Compiled fragment shader string + * @prop {String} compiledVertexShader - Compiled Vertical shader string + * @extends GLKernel + */ +export class WebGLKernel extends GLKernel { + static get isSupported() { + if (isSupported !== null) { + return isSupported; + } + this.setupFeatureChecks(); + isSupported = this.isContextMatch(testContext); + return isSupported; + } + + static setupFeatureChecks() { + if (typeof document !== 'undefined') { + testCanvas = document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + testCanvas = new OffscreenCanvas(0, 0); + } + if (!testCanvas) return; + testContext = testCanvas.getContext('webgl') || testCanvas.getContext('experimental-webgl'); + if (!testContext || !testContext.getExtension) return; + testExtensions = { + OES_texture_float: testContext.getExtension('OES_texture_float'), + OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), + OES_element_index_uint: testContext.getExtension('OES_element_index_uint'), + WEBGL_draw_buffers: testContext.getExtension('WEBGL_draw_buffers'), + }; + features = this.getFeatures(); + } + + static isContextMatch(context) { + if (typeof WebGLRenderingContext !== 'undefined') { + return context instanceof WebGLRenderingContext; + } + return false; + } + + static getFeatures() { + const isDrawBuffers = this.getIsDrawBuffers(); + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + isTextureFloat: this.getIsTextureFloat(), + isDrawBuffers, + kernelMap: isDrawBuffers, + channelCount: this.getChannelCount(), + }); + } + + static getIsTextureFloat() { + return Boolean(testExtensions.OES_texture_float); + } + + static getIsDrawBuffers() { + return Boolean(testExtensions.WEBGL_draw_buffers); + } + + static getChannelCount() { + return testExtensions.WEBGL_draw_buffers ? + testContext.getParameter(testExtensions.WEBGL_draw_buffers.MAX_DRAW_BUFFERS_WEBGL) : + 1; + } + + static lookupKernelValueType(type, dynamic, precision, value) { + return lookupKernelValueType(type, dynamic, precision, value); + } + + static get testCanvas() { + return testCanvas; + } + + static get testContext() { + return testContext; + } + + static get features() { + return features; + } + + static get fragmentShader() { + return fragmentShader; + } + + static get vertexShader() { + return vertexShader; + } + + /** + * + * @param {String} source + * @param {IKernelSettings} settings + */ + constructor(source, settings) { + super(source, settings); + this.program = null; + this.pipeline = settings.pipeline; + this.endianness = utils.systemEndianness(); + this.extensions = {}; + this.subKernelOutputTextures = null; + this.kernelArguments = null; + this.argumentTextureCount = 0; + this.constantTextureCount = 0; + this.compiledFragmentShader = null; + this.compiledVertexShader = null; + this.fragShader = null; + this.vertShader = null; + this.drawBuffersMap = null; + this.outputTexture = null; + + /** + * + * @type {Int32Array|null} + */ + this.maxTexSize = null; + this.switchingKernels = false; + this.onRequestSwitchKernel = null; + + this.mergeSettings(source.settings || settings); + + /** + * The thread dimensions, x, y and z + * @type {Array|null} + */ + this.threadDim = null; + this.framebuffer = null; + this.buffer = null; + this.textureCache = {}; + this.programUniformLocationCache = {}; + this.uniform1fCache = {}; + this.uniform1iCache = {}; + this.uniform2fCache = {}; + this.uniform2fvCache = {}; + this.uniform2ivCache = {}; + this.uniform3fvCache = {}; + this.uniform3ivCache = {}; + this.uniform4fvCache = {}; + this.uniform4ivCache = {}; + } + + initCanvas() { + if (typeof document !== 'undefined') { + const canvas = document.createElement('canvas'); + // Default width and height, to fix webgl issue in safari + canvas.width = 2; + canvas.height = 2; + return canvas; + } else if (typeof OffscreenCanvas !== 'undefined') { + return new OffscreenCanvas(0, 0); + } + } + + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + return this.canvas.getContext('webgl', settings) || this.canvas.getContext('experimental-webgl', settings); + } + + initPlugins(settings) { + // default plugins + const pluginsToUse = []; + const { source } = this; + if (typeof source === 'string') { + for (let i = 0; i < plugins.length; i++) { + const plugin = plugins[i]; + if (source.match(plugin.functionMatch)) { + pluginsToUse.push(plugin); + } + } + } else if (typeof source === 'object') { + // `source` is from object, json + if (settings.pluginNames) { //TODO: in context of JSON support, pluginNames may not exist here + for (let i = 0; i < plugins.length; i++) { + const plugin = plugins[i]; + const usePlugin = settings.pluginNames.some(pluginName => pluginName === plugin.name); + if (usePlugin) { + pluginsToUse.push(plugin); + } + } + } + } + return pluginsToUse; + } + + initExtensions() { + this.extensions = { + OES_texture_float: this.context.getExtension('OES_texture_float'), + OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), + OES_element_index_uint: this.context.getExtension('OES_element_index_uint'), + WEBGL_draw_buffers: this.context.getExtension('WEBGL_draw_buffers'), + WEBGL_color_buffer_float: this.context.getExtension('WEBGL_color_buffer_float'), + }; + } + + /** + * @desc Validate settings related to Kernel, such as dimensions size, and auto output support. + * @param {IArguments} args + */ + validateSettings(args) { + if (!this.validate) { + this.texSize = utils.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + return; + } + + const { features } = this.constructor; + if (this.optimizeFloatMemory === true && !features.isTextureFloat) { + throw new Error('Float textures are not supported'); + } else if (this.precision === 'single' && !features.isFloatRead) { + throw new Error('Single precision not supported'); + } else if (!this.graphical && this.precision === null && features.isTextureFloat) { + this.precision = features.isFloatRead ? 'single' : 'unsigned'; + } + + if (this.subKernels && this.subKernels.length > 0 && !this.extensions.WEBGL_draw_buffers) { + throw new Error('could not instantiate draw buffers extension'); + } + + if (this.fixIntegerDivisionAccuracy === null) { + this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; + } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { + this.fixIntegerDivisionAccuracy = false; + } + + this.checkOutput(); + + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + + const argType = utils.getVariableType(args[0], this.strictIntegers); + if (argType === 'Array') { + this.output = utils.getDimensions(argType); + } else if (argType === 'NumberTexture' || argType === 'ArrayTexture(4)') { + this.output = args[0].output; + } else { + throw new Error('Auto output not supported for input type: ' + argType); + } + } + + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); + } + + if (this.precision === 'precision') { + this.precision = 'unsigned'; + console.warn('Cannot use graphical mode and single precision at the same time'); + } + + this.texSize = utils.clone(this.output); + return; + } else if (this.precision === null && features.isTextureFloat) { + this.precision = 'single'; + } + + this.texSize = utils.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + + this.checkTextureSize(); + } + + updateMaxTexSize() { + const { texSize, canvas } = this; + if (this.maxTexSize === null) { + let canvasIndex = canvases.indexOf(canvas); + if (canvasIndex === -1) { + canvasIndex = canvases.length; + canvases.push(canvas); + maxTexSizes[canvasIndex] = [texSize[0], texSize[1]]; + } + this.maxTexSize = maxTexSizes[canvasIndex]; + } + if (this.maxTexSize[0] < texSize[0]) { + this.maxTexSize[0] = texSize[0]; + } + if (this.maxTexSize[1] < texSize[1]) { + this.maxTexSize[1] = texSize[1]; + } + } + + // TODO: move channel checks to new place + _oldtranslateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + + // need this line to automatically get returnType + const translatedSource = functionBuilder.getPrototypeString('kernel'); + + if (!this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + + let requiredChannels = 0; + const returnTypes = functionBuilder.getReturnTypes(); + for (let i = 0; i < returnTypes.length; i++) { + switch (returnTypes[i]) { + case 'Float': + case 'Number': + case 'Integer': + requiredChannels++; + break; + case 'Array(2)': + requiredChannels += 2; + break; + case 'Array(3)': + requiredChannels += 3; + break; + case 'Array(4)': + requiredChannels += 4; + break; + } + } + + if (features && requiredChannels > features.channelCount) { + throw new Error('Too many channels!'); + } + + return this.translatedSource = translatedSource; + } + + setupArguments(args) { + this.kernelArguments = []; + this.argumentTextureCount = 0; + const needsArgumentTypes = this.argumentTypes === null; + // TODO: remove + if (needsArgumentTypes) { + this.argumentTypes = []; + } + this.argumentSizes = []; + this.argumentBitRatios = []; + // TODO: end remove + + if (args.length < this.argumentNames.length) { + throw new Error('not enough arguments for kernel'); + } else if (args.length > this.argumentNames.length) { + throw new Error('too many arguments for kernel'); + } + + const { context: gl } = this; + let textureIndexes = 0; + for (let index = 0; index < args.length; index++) { + const value = args[index]; + const name = this.argumentNames[index]; + let type; + if (needsArgumentTypes) { + type = utils.getVariableType(value, this.strictIntegers); + this.argumentTypes.push(type); + } else { + type = this.argumentTypes[index]; + } + const KernelValue = this.constructor.lookupKernelValueType(type, this.dynamicArguments ? 'dynamic' : 'static', this.precision, args[index]); + if (KernelValue === null) { + return this.requestFallback(args); + } + const kernelArgument = new KernelValue(value, { + name, + type, + tactic: this.tactic, + origin: 'user', + context: gl, + checkContext: this.checkContext, + kernel: this, + strictIntegers: this.strictIntegers, + onRequestTexture: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onUpdateValueMismatch: () => { + this.switchingKernels = true; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount++; + } + }); + this.kernelArguments.push(kernelArgument); + this.argumentSizes.push(kernelArgument.textureSize); + this.argumentBitRatios[index] = kernelArgument.bitRatio; + } + } + + setupConstants(args) { + const { context: gl } = this; + this.kernelConstants = []; + this.forceUploadKernelConstants = []; + let needsConstantTypes = this.constantTypes === null; + if (needsConstantTypes) { + this.constantTypes = {}; + } + this.constantBitRatios = {}; + let textureIndexes = 0; + for (const name in this.constants) { + const value = this.constants[name]; + let type; + if (needsConstantTypes) { + type = utils.getVariableType(value, this.strictIntegers); + this.constantTypes[name] = type; + } else { + type = this.constantTypes[name]; + } + const KernelValue = this.constructor.lookupKernelValueType(type, 'static', this.precision, value); + if (KernelValue === null) { + return this.requestFallback(args); + } + const kernelValue = new KernelValue(value, { + name, + type, + tactic: this.tactic, + origin: 'constants', + context: this.context, + checkContext: this.checkContext, + kernel: this, + strictIntegers: this.strictIntegers, + onRequestTexture: () => { + return this.context.createTexture(); + }, + onRequestIndex: () => { + return textureIndexes++; + }, + onRequestContextHandle: () => { + return gl.TEXTURE0 + this.constantTextureCount++; + } + }); + this.constantBitRatios[name] = kernelValue.bitRatio; + this.kernelConstants.push(kernelValue); + if (kernelValue.forceUploadEachRun) { + this.forceUploadKernelConstants.push(kernelValue); + } + } + } + + build() { + this.initExtensions(); + this.validateSettings(arguments); + this.setupConstants(arguments); + if (this.fallbackRequested) return; + this.setupArguments(arguments); + if (this.fallbackRequested) return; + this.updateMaxTexSize(); + this.translateSource(); + const failureResult = this.pickRenderStrategy(arguments); + if (failureResult) { + return failureResult; + } + const { texSize, context: gl, canvas } = this; + gl.enable(gl.SCISSOR_TEST); + if (this.pipeline && this.precision === 'single') { + gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + canvas.width = this.maxTexSize[0]; + canvas.height = this.maxTexSize[1]; + } else { + gl.viewport(0, 0, this.maxTexSize[0], this.maxTexSize[1]); + canvas.width = this.maxTexSize[0]; + canvas.height = this.maxTexSize[1]; + } + const threadDim = this.threadDim = Array.from(this.output); + while (threadDim.length < 3) { + threadDim.push(1); + } + + const compiledVertexShader = this.getVertexShader(arguments); + const vertShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertShader, compiledVertexShader); + gl.compileShader(vertShader); + this.vertShader = vertShader; + + const compiledFragmentShader = this.getFragmentShader(arguments); + const fragShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragShader, compiledFragmentShader); + gl.compileShader(fragShader); + this.fragShader = fragShader; + + if (this.debug) { + console.log('GLSL Shader Output:'); + console.log(compiledFragmentShader); + } + + if (!gl.getShaderParameter(vertShader, gl.COMPILE_STATUS)) { + throw new Error('Error compiling vertex shader: ' + gl.getShaderInfoLog(vertShader)); + } + if (!gl.getShaderParameter(fragShader, gl.COMPILE_STATUS)) { + throw new Error('Error compiling fragment shader: ' + gl.getShaderInfoLog(fragShader)); + } + + const program = this.program = gl.createProgram(); + gl.attachShader(program, vertShader); + gl.attachShader(program, fragShader); + gl.linkProgram(program); + this.framebuffer = gl.createFramebuffer(); + this.framebuffer.width = texSize[0]; + this.framebuffer.height = texSize[1]; + + const vertices = new Float32Array([-1, -1, + 1, -1, -1, 1, + 1, 1 + ]); + const texCoords = new Float32Array([ + 0, 0, + 1, 0, + 0, 1, + 1, 1 + ]); + + const texCoordOffset = vertices.byteLength; + + let buffer = this.buffer; + if (!buffer) { + buffer = this.buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData(gl.ARRAY_BUFFER, vertices.byteLength + texCoords.byteLength, gl.STATIC_DRAW); + } else { + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + } + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, vertices); + gl.bufferSubData(gl.ARRAY_BUFFER, texCoordOffset, texCoords); + + const aPosLoc = gl.getAttribLocation(this.program, 'aPos'); + gl.enableVertexAttribArray(aPosLoc); + gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, 0, 0); + const aTexCoordLoc = gl.getAttribLocation(this.program, 'aTexCoord'); + gl.enableVertexAttribArray(aTexCoordLoc); + gl.vertexAttribPointer(aTexCoordLoc, 2, gl.FLOAT, false, 0, texCoordOffset); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + + let i = 0; + gl.useProgram(this.program); + for (let p in this.constants) { + this.kernelConstants[i++].updateValue(this.constants[p]); + } + + if (!this.immutable) { + this._setupOutputTexture(); + if ( + this.subKernels !== null && + this.subKernels.length > 0 + ) { + this._setupSubOutputTextures(); + } + } + } + + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGLFunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + + if (this.subKernels && this.subKernels.length > 0) { + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (!subKernel.returnType) { + subKernel.returnType = functionBuilder.getSubKernelResultType(i); + } + } + } + } + + run() { + const { kernelArguments, forceUploadKernelConstants } = this; + const texSize = this.texSize; + const gl = this.context; + + gl.useProgram(this.program); + gl.scissor(0, 0, texSize[0], texSize[1]); + + if (this.dynamicOutput) { + this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); + this.setUniform2iv('uTexSize', texSize); + } + + this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); + + this.switchingKernels = false; + for (let i = 0; i < forceUploadKernelConstants.length; i++) { + const constant = forceUploadKernelConstants[i]; + constant.updateValue(this.constants[constant.name]); + if (this.switchingKernels) return; + } + for (let i = 0; i < kernelArguments.length; i++) { + kernelArguments[i].updateValue(arguments[i]); + if (this.switchingKernels) return; + } + + if (this.plugins) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.onBeforeRun) { + plugin.onBeforeRun(this); + } + } + } + + if (this.graphical) { + if (this.pipeline) { + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (!this.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context, + }); + } + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return; + } + + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (this.immutable) { + this._setupOutputTexture(); + } + + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + this.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(this.drawBuffersMap); + } + + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + + /** + * @desc This return defined outputTexture, which is setup in .build(), or if immutable, is defined in .run() + * @returns {Object} Output Texture Cache + */ + getOutputTexture() { + return this.outputTexture; + } + + /** + * @desc Setup and replace output texture + */ + _setupOutputTexture() { + const gl = this.context; + const texSize = this.texSize; + const texture = this.outputTexture = this.context.createTexture(); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + // if (this.precision === 'single') { + // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + // } else { + // gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + // } + if (this.precision === 'single') { + if (this.pipeline) { + // TODO: investigate if webgl1 can handle gl.RED usage in gl.texImage2D, otherwise, simplify the below + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } + break; + case 'Array(2)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(3)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + case 'Array(4)': + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + break; + default: + if (!this.graphical) { + throw new Error('Unhandled return type'); + } + } + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + } + + /** + * @desc Setup and replace sub-output textures + */ + _setupSubOutputTextures() { + const gl = this.context; + const texSize = this.texSize; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; + for (let i = 0; i < this.subKernels.length; i++) { + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); + } + } + + /** + * @desc Returns the Texture Cache of the supplied parameter (can be kernel, sub-kernel or argument) + * @param {String} name - Name of the subkernel, argument, or kernel. + * @returns {Object} Texture cache + */ + getTextureCache(name) { + if (this.textureCache.hasOwnProperty(name)) { + return this.textureCache[name]; + } + return this.textureCache[name] = this.context.createTexture(); + } + + /** + * @desc removes a texture from the kernel's cache + * @param {String} name - Name of texture + */ + detachTextureCache(name) { + delete this.textureCache[name]; + } + + setUniform1f(name, value) { + if (this.uniform1fCache.hasOwnProperty(name)) { + const cache = this.uniform1fCache[name]; + if (value === cache) { + return; + } + } + this.uniform1fCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform1f(loc, value); + } + + setUniform1i(name, value) { + if (this.uniform1iCache.hasOwnProperty(name)) { + const cache = this.uniform1iCache[name]; + if (value === cache) { + return; + } + } + this.uniform1iCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform1i(loc, value); + } + + setUniform2f(name, value1, value2) { + if (this.uniform2fCache.hasOwnProperty(name)) { + const cache = this.uniform2fCache[name]; + if ( + value1 === cache[0] && + value2 === cache[1] + ) { + return; + } + } + this.uniform2fCache[name] = [value1, value2]; + const loc = this.getUniformLocation(name); + this.context.uniform2f(loc, value1, value2); + } + + setUniform2fv(name, value) { + if (this.uniform2fvCache.hasOwnProperty(name)) { + const cache = this.uniform2fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] + ) { + return; + } + } + this.uniform2fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform2fv(loc, value); + } + + setUniform2iv(name, value) { + if (this.uniform2ivCache.hasOwnProperty(name)) { + const cache = this.uniform2ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] + ) { + return; + } + } + this.uniform2ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform2iv(loc, value); + } + + setUniform3fv(name, value) { + if (this.uniform3fvCache.hasOwnProperty(name)) { + const cache = this.uniform3fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3fv(loc, value); + } + + setUniform3iv(name, value) { + if (this.uniform3ivCache.hasOwnProperty(name)) { + const cache = this.uniform3ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3iv(loc, value); + } + + setUniform3fv(name, value) { + if (this.uniform3fvCache.hasOwnProperty(name)) { + const cache = this.uniform3fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] + ) { + return; + } + } + this.uniform3fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform3fv(loc, value); + } + + setUniform4iv(name, value) { + if (this.uniform4ivCache.hasOwnProperty(name)) { + const cache = this.uniform4ivCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] && + value[3] === cache[3] + ) { + return; + } + } + this.uniform4ivCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform4iv(loc, value); + } + + setUniform4fv(name, value) { + if (this.uniform4fvCache.hasOwnProperty(name)) { + const cache = this.uniform4fvCache[name]; + if ( + value[0] === cache[0] && + value[1] === cache[1] && + value[2] === cache[2] && + value[3] === cache[3] + ) { + return; + } + } + this.uniform4fvCache[name] = value; + const loc = this.getUniformLocation(name); + this.context.uniform4fv(loc, value); + } + + /** + * @desc Return WebGlUniformLocation for various variables + * related to webGl program, such as user-defined variables, + * as well as, dimension sizes, etc. + */ + getUniformLocation(name) { + if (this.programUniformLocationCache.hasOwnProperty(name)) { + return this.programUniformLocationCache[name]; + } + return this.programUniformLocationCache[name] = this.context.getUniformLocation(this.program, name); + } + + /** + * @desc Generate Shader artifacts for the kernel program. + * The final object contains HEADER, KERNEL, MAIN_RESULT, and others. + * + * @param {Array} args - The actual parameters sent to the Kernel + * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.) + */ + _getFragShaderArtifactMap(args) { + return { + HEADER: this._getHeaderString(), + LOOP_MAX: this._getLoopMaxString(), + PLUGINS: this._getPluginsString(), + CONSTANTS: this._getConstantsString(), + DECODE32_ENDIANNESS: this._getDecode32EndiannessString(), + ENCODE32_ENDIANNESS: this._getEncode32EndiannessString(), + DIVIDE_WITH_INTEGER_CHECK: this._getDivideWithIntegerCheckString(), + INJECTED_NATIVE: this._getInjectedNative(), + MAIN_CONSTANTS: this._getMainConstantsString(), + MAIN_ARGUMENTS: this._getMainArgumentsString(args), + KERNEL: this.getKernelString(), + MAIN_RESULT: this.getMainResultString(), + FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), + INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), + SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), + SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), + }; + } + + /** + * @desc Generate Shader artifacts for the kernel program. + * The final object contains HEADER, KERNEL, MAIN_RESULT, and others. + * + * @param {Array} args - The actual parameters sent to the Kernel + * @returns {Object} An object containing the Shader Artifacts(CONSTANTS, HEADER, KERNEL, etc.) + */ + _getVertShaderArtifactMap(args) { + return { + FLOAT_TACTIC_DECLARATION: this.getFloatTacticDeclaration(), + INT_TACTIC_DECLARATION: this.getIntTacticDeclaration(), + SAMPLER_2D_TACTIC_DECLARATION: this.getSampler2DTacticDeclaration(), + SAMPLER_2D_ARRAY_TACTIC_DECLARATION: this.getSampler2DArrayTacticDeclaration(), + }; + } + + /** + * @desc Get the header string for the program. + * This returns an empty string if no sub-kernels are defined. + * + * @returns {String} result + */ + _getHeaderString() { + return ( + this.subKernels !== null ? + '#extension GL_EXT_draw_buffers : require\n' : + '' + ); + } + + /** + * @desc Get the maximum loop size String. + * @returns {String} result + */ + _getLoopMaxString() { + return ( + this.loopMaxIterations ? + ` ${parseInt(this.loopMaxIterations)};\n` : + ' 1000;\n' + ); + } + + _getPluginsString() { + if (!this.plugins) return '\n'; + return this.plugins.map(plugin => plugin.source && this.source.match(plugin.functionMatch) ? plugin.source : '').join('\n'); + } + + /** + * @desc Generate transpiled glsl Strings for constant parameters sent to a kernel + * @returns {String} result + */ + _getConstantsString() { + const result = []; + const { threadDim, texSize } = this; + if (this.dynamicOutput) { + result.push( + 'uniform ivec3 uOutputDim', + 'uniform ivec2 uTexSize' + ); + } else { + result.push( + `ivec3 uOutputDim = ivec3(${threadDim[0]}, ${threadDim[1]}, ${threadDim[2]})`, + `ivec2 uTexSize = ivec2(${texSize[0]}, ${texSize[1]})` + ); + } + return utils.linesToString(result); + } + + /** + * @desc Get texture coordinate string for the program + * @returns {String} result + */ + _getTextureCoordinate() { + const subKernels = this.subKernels; + if (subKernels === null || subKernels.length < 1) { + return 'varying vec2 vTexCoord;\n'; + } else { + return 'out vec2 vTexCoord;\n'; + } + } + + /** + * @desc Get Decode32 endianness string for little-endian and big-endian + * @returns {String} result + */ + _getDecode32EndiannessString() { + return ( + this.endianness === 'LE' ? + '' : + ' texel.rgba = texel.abgr;\n' + ); + } + + /** + * @desc Get Encode32 endianness string for little-endian and big-endian + * @returns {String} result + */ + _getEncode32EndiannessString() { + return ( + this.endianness === 'LE' ? + '' : + ' texel.rgba = texel.abgr;\n' + ); + } + + /** + * @desc if fixIntegerDivisionAccuracy provide method to replace / + * @returns {String} result + */ + _getDivideWithIntegerCheckString() { + return this.fixIntegerDivisionAccuracy ? + `float div_with_int_check(float x, float y) { + if (floor(x) == x && floor(y) == y && integerMod(x, y) == 0.0) { + return float(int(x)/int(y)); + } + return x / y; +}` : + ''; + } + + /** + * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel + * @param {Array} args - The actual parameters sent to the Kernel + * @returns {String} result + */ + _getMainArgumentsString(args) { + const results = []; + const { argumentNames } = this; + for (let i = 0; i < argumentNames.length; i++) { + results.push(this.kernelArguments[i].getSource(args[i])); + } + return results.join(''); + } + + _getInjectedNative() { + return this.injectedNative || ''; + } + + _getMainConstantsString() { + const result = []; + const { constants } = this; + if (constants) { + let i = 0; + for (const name in constants) { + result.push(this.kernelConstants[i++].getSource(this.constants[name])); + } + } + return result.join(''); + } + + /** + * @desc Get Kernel program string (in *glsl*) for a kernel. + * @returns {String} result + */ + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration + ); + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + for (let i = 0; i < subKernels.length; i++) { + const subKernel = subKernels[i]; + result.push( + subKernel.returnType === 'Integer' ? + `int subKernelResult_${ subKernel.name } = 0` : + `float subKernelResult_${ subKernel.name } = 0.0` + ); + } + break; + case 'Array(2)': + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec2 subKernelResult_${ subKernels[i].name }` + ); + } + break; + case 'Array(3)': + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec3 subKernelResult_${ subKernels[i].name }` + ); + } + break; + case 'Array(4)': + for (let i = 0; i < subKernels.length; i++) { + result.push( + `vec4 subKernelResult_${ subKernels[i].name }` + ); + } + break; + } + } else { + result.push( + kernelResultDeclaration + ); + } + + return utils.linesToString(result) + this.translatedSource; + } + + getMainResultGraphical() { + return utils.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragColor = actualColor', + ]); + } + + getMainResultPackedPixels() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return this.getMainResultKernelPackedPixels() + + this.getMainResultSubKernelPackedPixels(); + default: + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); + } + } + + /** + * @return {String} + */ + getMainResultKernelPackedPixels() { + return utils.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); + } + + /** + * @return {String} + */ + getMainResultSubKernelPackedPixels() { + const result = []; + if (!this.subKernels) return ''; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` + ); + } else { + result.push( + ` gl_FragData[${i + 1}] = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` + ); + } + } + return utils.linesToString(result); + } + + getMainResultMemoryOptimizedFloats() { + const result = [ + ' index *= 4', + ]; + + switch (this.returnType) { + case 'Number': + case 'Integer': + case 'Float': + const channels = ['r', 'g', 'b', 'a']; + for (let i = 0; i < channels.length; i++) { + const channel = channels[i]; + this.getMainResultKernelMemoryOptimizedFloats(result, channel); + this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); + if (i + 1 < channels.length) { + result.push(' index += 1'); + } + } + break; + default: + throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); + } + + return utils.linesToString(result); + } + + getMainResultKernelMemoryOptimizedFloats(result, channel) { + result.push( + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` gl_FragData[0].${channel} = kernelResult`, + ); + } + + getMainResultSubKernelMemoryOptimizedFloats(result, channel) { + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}].${channel} = float(subKernelResult_${this.subKernels[i].name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}].${channel} = subKernelResult_${this.subKernels[i].name}`, + ); + } + } + } + + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult', + ]; + } + + getMainResultSubKernelNumberTexture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}][0] = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${subKernel.name}`, + ); + } + } + return result; + } + + getMainResultKernelArray2Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult[0]', + ' gl_FragData[0][1] = kernelResult[1]', + ]; + } + + getMainResultSubKernelArray2Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ); + } + return result; + } + + getMainResultKernelArray3Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0][0] = kernelResult[0]', + ' gl_FragData[0][1] = kernelResult[1]', + ' gl_FragData[0][2] = kernelResult[2]', + ]; + } + + getMainResultSubKernelArray3Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, + ); + } + return result; + } + + getMainResultKernelArray4Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' gl_FragData[0] = kernelResult', + ]; + } + + getMainResultSubKernelArray4Texture() { + const result = []; + if (!this.subKernels) return result; + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` gl_FragData[${i + 1}] = float(subKernelResult_${this.subKernels[i].name})`, + ); + } else { + result.push( + ` gl_FragData[${i + 1}] = subKernelResult_${this.subKernels[i].name}`, + ); + } + } + break; + case 'Array(2)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ); + } + break; + case 'Array(3)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, + ); + } + break; + case 'Array(4)': + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` gl_FragData[${i + 1}][0] = subKernelResult_${this.subKernels[i].name}[0]`, + ` gl_FragData[${i + 1}][1] = subKernelResult_${this.subKernels[i].name}[1]`, + ` gl_FragData[${i + 1}][2] = subKernelResult_${this.subKernels[i].name}[2]`, + ` gl_FragData[${i + 1}][3] = subKernelResult_${this.subKernels[i].name}[3]`, + ); + } + break; + } + + return result; + } + + /** + * @param {String} src - Shader string + * @param {Object} map - Variables/Constants associated with shader + */ + replaceArtifacts(src, map) { + return src.replace(/[ ]*__([A-Z]+[0-9]*([_]?[A-Z]*[0-9]?)*)__;\n/g, (match, artifact) => { + if (map.hasOwnProperty(artifact)) { + return map[artifact]; + } + throw `unhandled artifact ${artifact}`; + }); + } + + /** + * @desc Get the fragment shader String. + * If the String hasn't been compiled yet, + * then this method compiles it as well + * + * @param {Array} args - The actual parameters sent to the Kernel + * @returns {string} Fragment Shader string + */ + getFragmentShader(args) { + if (this.compiledFragmentShader !== null) { + return this.compiledFragmentShader; + } + return this.compiledFragmentShader = this.replaceArtifacts(this.constructor.fragmentShader, this._getFragShaderArtifactMap(args)); + } + + /** + * @desc Get the vertical shader String + * @param {Array|IArguments} args - The actual parameters sent to the Kernel + * @returns {string} Vertical Shader string + */ + getVertexShader(args) { + if (this.compiledVertexShader !== null) { + return this.compiledVertexShader; + } + return this.compiledVertexShader = this.replaceArtifacts(this.constructor.vertexShader, this._getVertShaderArtifactMap(args)); + } + + /** + * @desc Returns the *pre-compiled* Kernel as a JS Object String, that can be reused. + */ + toString() { + const setupContextString = utils.linesToString([ + `const gl = context`, + ]); + return glKernelString(this.constructor, arguments, this, setupContextString); + } + + destroy(removeCanvasReferences) { + if (this.outputTexture) { + this.context.deleteTexture(this.outputTexture); + } + if (this.buffer) { + this.context.deleteBuffer(this.buffer); + } + if (this.framebuffer) { + this.context.deleteFramebuffer(this.framebuffer); + } + if (this.vertShader) { + this.context.deleteShader(this.vertShader); + } + if (this.fragShader) { + this.context.deleteShader(this.fragShader); + } + if (this.program) { + this.context.deleteProgram(this.program); + } + + const keys = Object.keys(this.textureCache); + + for (let i = 0; i < keys.length; i++) { + const name = keys[i]; + this.context.deleteTexture(this.textureCache[name]); + } + + if (this.subKernelOutputTextures) { + for (let i = 0; i < this.subKernelOutputTextures.length; i++) { + this.context.deleteTexture(this.subKernelOutputTextures[i]); + } + } + if (removeCanvasReferences) { + const idx = canvases.indexOf(this.canvas); + if (idx >= 0) { + canvases[idx] = null; + maxTexSizes[idx] = null; + } + } + this.destroyExtensions(); + delete this.context; + delete this.canvas; + } + + destroyExtensions() { + this.extensions.OES_texture_float = null; + this.extensions.OES_texture_float_linear = null; + this.extensions.OES_element_index_uint = null; + this.extensions.WEBGL_draw_buffers = null; + } + + static destroyContext(context) { + const extension = context.getExtension('WEBGL_lose_context'); + if (extension) { + extension.loseContext(); + } + } + + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, WebGLFunctionNode).toJSON(); + return json; + } +} diff --git a/src/backend/web-gl/vertex-shader.js b/src/backend/web-gl/vertex-shader.js index 88647d73..f4e7cf49 100644 --- a/src/backend/web-gl/vertex-shader.js +++ b/src/backend/web-gl/vertex-shader.js @@ -1,19 +1,15 @@ -// language=GLSL -const vertexShader = `__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -attribute vec2 aPos; -attribute vec2 aTexCoord; - -varying vec2 vTexCoord; -uniform vec2 ratio; - -void main(void) { - gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); - vTexCoord = aTexCoord; -}`; - -module.exports = { - vertexShader -}; \ No newline at end of file +// language=GLSL +export const vertexShader = `__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +attribute vec2 aPos; +attribute vec2 aTexCoord; + +varying vec2 vTexCoord; +uniform vec2 ratio; + +void main(void) { + gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); + vTexCoord = aTexCoord; +}`; diff --git a/src/backend/web-gl2/fragment-shader.js b/src/backend/web-gl2/fragment-shader.js index 8a31c1be..d50dcae3 100644 --- a/src/backend/web-gl2/fragment-shader.js +++ b/src/backend/web-gl2/fragment-shader.js @@ -1,395 +1,391 @@ -// language=GLSL -const fragmentShader = `#version 300 es -__HEADER__; -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; -__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; - -const int LOOP_MAX = __LOOP_MAX__; - -__PLUGINS__; -__CONSTANTS__; - -in vec2 vTexCoord; - -const int BIT_COUNT = 32; -int modi(int x, int y) { - return x - y * (x / y); -} - -int bitwiseOr(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; -} -int bitwiseXOR(int a, int b) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 || b > 0)) { - break; - } - } - return result; -} -int bitwiseAnd(int a, int b) { - int result = 0; - int n = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { - result += n; - } - a = a / 2; - b = b / 2; - n = n * 2; - if(!(a > 0 && b > 0)) { - break; - } - } - return result; -} -int bitwiseNot(int a) { - int result = 0; - int n = 1; - - for (int i = 0; i < BIT_COUNT; i++) { - if (modi(a, 2) == 0) { - result += n; - } - a = a / 2; - n = n * 2; - } - return result; -} -int bitwiseZeroFillLeftShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n *= 2; - } - - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -int bitwiseSignedRightShift(int num, int shifts) { - return int(floor(float(num) / pow(2.0, float(shifts)))); -} - -int bitwiseZeroFillRightShift(int n, int shift) { - int maxBytes = BIT_COUNT; - for (int i = 0; i < BIT_COUNT; i++) { - if (maxBytes >= n) { - break; - } - maxBytes *= 2; - } - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= shift) { - break; - } - n /= 2; - } - int result = 0; - int byteVal = 1; - for (int i = 0; i < BIT_COUNT; i++) { - if (i >= maxBytes) break; - if (modi(n, 2) > 0) { result += byteVal; } - n = int(n / 2); - byteVal *= 2; - } - return result; -} - -vec2 integerMod(vec2 x, float y) { - vec2 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec3 integerMod(vec3 x, float y) { - vec3 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -vec4 integerMod(vec4 x, vec4 y) { - vec4 res = floor(mod(x, y)); - return res * step(1.0 - floor(y), -res); -} - -float integerMod(float x, float y) { - float res = floor(mod(x, y)); - return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); -} - -int integerMod(int x, int y) { - return x - (y * int(x/y)); -} - -__DIVIDE_WITH_INTEGER_CHECK__; - -// Here be dragons! -// DO NOT OPTIMIZE THIS CODE -// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE -// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME -const vec2 MAGIC_VEC = vec2(1.0, -256.0); -const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); -const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 -float decode32(vec4 texel) { - __DECODE32_ENDIANNESS__; - texel *= 255.0; - vec2 gte128; - gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; - gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; - float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); - float res = exp2(round(exponent)); - texel.b = texel.b - 128.0 * gte128.x; - res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; - res *= gte128.y * -2.0 + 1.0; - return res; -} - -float decode16(vec4 texel, int index) { - int channel = integerMod(index, 2); - return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; -} - -float decode8(vec4 texel, int index) { - int channel = integerMod(index, 4); - return texel[channel] * 255.0; -} - -vec4 legacyEncode32(float f) { - float F = abs(f); - float sign = f < 0.0 ? 1.0 : 0.0; - float exponent = floor(log2(F)); - float mantissa = (exp2(-exponent) * F); - // exponent += floor(log2(mantissa)); - vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; - texel.rg = integerMod(texel.rg, 256.0); - texel.b = integerMod(texel.b, 128.0); - texel.a = exponent*0.5 + 63.5; - texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; - texel = floor(texel); - texel *= 0.003921569; // 1/255 - __ENCODE32_ENDIANNESS__; - return texel; -} - -// https://github.com/gpujs/gpu.js/wiki/Encoder-details -vec4 encode32(float value) { - if (value == 0.0) return vec4(0, 0, 0, 0); - - float exponent; - float mantissa; - vec4 result; - float sgn; - - sgn = step(0.0, -value); - value = abs(value); - - exponent = floor(log2(value)); - - mantissa = value*pow(2.0, -exponent)-1.0; - exponent = exponent+127.0; - result = vec4(0,0,0,0); - - result.a = floor(exponent/2.0); - exponent = exponent - result.a*2.0; - result.a = result.a + 128.0*sgn; - - result.b = floor(mantissa * 128.0); - mantissa = mantissa - result.b / 128.0; - result.b = result.b + exponent*128.0; - - result.g = floor(mantissa*32768.0); - mantissa = mantissa - result.g/32768.0; - - result.r = floor(mantissa*8388608.0); - return result/255.0; -} -// Dragons end here - -int index; -ivec3 threadId; - -ivec3 indexTo3D(int idx, ivec3 texDim) { - int z = int(idx / (texDim.x * texDim.y)); - idx -= z * int(texDim.x * texDim.y); - int y = int(idx / texDim.x); - int x = int(integerMod(idx, texDim.x)); - return ivec3(x, y, z); -} - -float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return decode32(texel); -} - -float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 2; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); - return decode16(texel, index); -} - -float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int w = texSize.x * 4; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); - return decode8(texel, index); -} - -float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + (texDim.x * (y + (texDim.y * z))); - int channel = integerMod(index, 4); - index = index / 4; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - index = index / 4; - vec4 texel = texture(tex, st / vec2(texSize)); - return texel[channel]; -} - -vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, st / vec2(texSize)); -} - -vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - return texture(tex, vec3(st / vec2(texSize), z)); -} - -float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return result[0]; -} - -vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec2(result[0], result[1]); -} - -vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - index = index / 2; - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - if (channel == 0) return vec2(texel.r, texel.g); - if (channel == 1) return vec2(texel.b, texel.a); - return vec2(0.0, 0.0); -} - -vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - vec4 result = getImage2D(tex, texSize, texDim, z, y, x); - return vec3(result[0], result[1], result[2]); -} - -vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); - int vectorIndex = fieldIndex / 4; - int vectorOffset = fieldIndex - vectorIndex * 4; - int readY = vectorIndex / texSize.x; - int readX = vectorIndex - readY * texSize.x; - vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); - - if (vectorOffset == 0) { - return tex1.xyz; - } else if (vectorOffset == 1) { - return tex1.yzw; - } else { - readX++; - if (readX >= texSize.x) { - readX = 0; - readY++; - } - vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); - if (vectorOffset == 2) { - return vec3(tex1.z, tex1.w, tex2.x); - } else { - return vec3(tex1.w, tex2.x, tex2.y); - } - } -} - -vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - return getImage2D(tex, texSize, texDim, z, y, x); -} - -vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { - int index = x + texDim.x * (y + texDim.y * z); - int channel = integerMod(index, 2); - int w = texSize.x; - vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; - vec4 texel = texture(tex, st / vec2(texSize)); - return vec4(texel.r, texel.g, texel.b, texel.a); -} - -vec4 actualColor; -void color(float r, float g, float b, float a) { - actualColor = vec4(r,g,b,a); -} - -void color(float r, float g, float b) { - color(r,g,b,1.0); -} - -__INJECTED_NATIVE__; -__MAIN_CONSTANTS__; -__MAIN_ARGUMENTS__; -__KERNEL__; - -void main(void) { - index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; - __MAIN_RESULT__; -}`; - -module.exports = { - fragmentShader -}; \ No newline at end of file +// language=GLSL +export const fragmentShader = `#version 300 es +__HEADER__; +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; +__SAMPLER_2D_ARRAY_TACTIC_DECLARATION__; + +const int LOOP_MAX = __LOOP_MAX__; + +__PLUGINS__; +__CONSTANTS__; + +in vec2 vTexCoord; + +const int BIT_COUNT = 32; +int modi(int x, int y) { + return x - y * (x / y); +} + +int bitwiseOr(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) || (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseXOR(int a, int b) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) != (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 || b > 0)) { + break; + } + } + return result; +} +int bitwiseAnd(int a, int b) { + int result = 0; + int n = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if ((modi(a, 2) == 1) && (modi(b, 2) == 1)) { + result += n; + } + a = a / 2; + b = b / 2; + n = n * 2; + if(!(a > 0 && b > 0)) { + break; + } + } + return result; +} +int bitwiseNot(int a) { + int result = 0; + int n = 1; + + for (int i = 0; i < BIT_COUNT; i++) { + if (modi(a, 2) == 0) { + result += n; + } + a = a / 2; + n = n * 2; + } + return result; +} +int bitwiseZeroFillLeftShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n *= 2; + } + + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +int bitwiseSignedRightShift(int num, int shifts) { + return int(floor(float(num) / pow(2.0, float(shifts)))); +} + +int bitwiseZeroFillRightShift(int n, int shift) { + int maxBytes = BIT_COUNT; + for (int i = 0; i < BIT_COUNT; i++) { + if (maxBytes >= n) { + break; + } + maxBytes *= 2; + } + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= shift) { + break; + } + n /= 2; + } + int result = 0; + int byteVal = 1; + for (int i = 0; i < BIT_COUNT; i++) { + if (i >= maxBytes) break; + if (modi(n, 2) > 0) { result += byteVal; } + n = int(n / 2); + byteVal *= 2; + } + return result; +} + +vec2 integerMod(vec2 x, float y) { + vec2 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec3 integerMod(vec3 x, float y) { + vec3 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +vec4 integerMod(vec4 x, vec4 y) { + vec4 res = floor(mod(x, y)); + return res * step(1.0 - floor(y), -res); +} + +float integerMod(float x, float y) { + float res = floor(mod(x, y)); + return res * (res > floor(y) - 1.0 ? 0.0 : 1.0); +} + +int integerMod(int x, int y) { + return x - (y * int(x/y)); +} + +__DIVIDE_WITH_INTEGER_CHECK__; + +// Here be dragons! +// DO NOT OPTIMIZE THIS CODE +// YOU WILL BREAK SOMETHING ON SOMEBODY\'S MACHINE +// LEAVE IT AS IT IS, LEST YOU WASTE YOUR OWN TIME +const vec2 MAGIC_VEC = vec2(1.0, -256.0); +const vec4 SCALE_FACTOR = vec4(1.0, 256.0, 65536.0, 0.0); +const vec4 SCALE_FACTOR_INV = vec4(1.0, 0.00390625, 0.0000152587890625, 0.0); // 1, 1/256, 1/65536 +float decode32(vec4 texel) { + __DECODE32_ENDIANNESS__; + texel *= 255.0; + vec2 gte128; + gte128.x = texel.b >= 128.0 ? 1.0 : 0.0; + gte128.y = texel.a >= 128.0 ? 1.0 : 0.0; + float exponent = 2.0 * texel.a - 127.0 + dot(gte128, MAGIC_VEC); + float res = exp2(round(exponent)); + texel.b = texel.b - 128.0 * gte128.x; + res = dot(texel, SCALE_FACTOR) * exp2(round(exponent-23.0)) + res; + res *= gte128.y * -2.0 + 1.0; + return res; +} + +float decode16(vec4 texel, int index) { + int channel = integerMod(index, 2); + return texel[channel*2] * 255.0 + texel[channel*2 + 1] * 65280.0; +} + +float decode8(vec4 texel, int index) { + int channel = integerMod(index, 4); + return texel[channel] * 255.0; +} + +vec4 legacyEncode32(float f) { + float F = abs(f); + float sign = f < 0.0 ? 1.0 : 0.0; + float exponent = floor(log2(F)); + float mantissa = (exp2(-exponent) * F); + // exponent += floor(log2(mantissa)); + vec4 texel = vec4(F * exp2(23.0-exponent)) * SCALE_FACTOR_INV; + texel.rg = integerMod(texel.rg, 256.0); + texel.b = integerMod(texel.b, 128.0); + texel.a = exponent*0.5 + 63.5; + texel.ba += vec2(integerMod(exponent+127.0, 2.0), sign) * 128.0; + texel = floor(texel); + texel *= 0.003921569; // 1/255 + __ENCODE32_ENDIANNESS__; + return texel; +} + +// https://github.com/gpujs/gpu.js/wiki/Encoder-details +vec4 encode32(float value) { + if (value == 0.0) return vec4(0, 0, 0, 0); + + float exponent; + float mantissa; + vec4 result; + float sgn; + + sgn = step(0.0, -value); + value = abs(value); + + exponent = floor(log2(value)); + + mantissa = value*pow(2.0, -exponent)-1.0; + exponent = exponent+127.0; + result = vec4(0,0,0,0); + + result.a = floor(exponent/2.0); + exponent = exponent - result.a*2.0; + result.a = result.a + 128.0*sgn; + + result.b = floor(mantissa * 128.0); + mantissa = mantissa - result.b / 128.0; + result.b = result.b + exponent*128.0; + + result.g = floor(mantissa*32768.0); + mantissa = mantissa - result.g/32768.0; + + result.r = floor(mantissa*8388608.0); + return result/255.0; +} +// Dragons end here + +int index; +ivec3 threadId; + +ivec3 indexTo3D(int idx, ivec3 texDim) { + int z = int(idx / (texDim.x * texDim.y)); + idx -= z * int(texDim.x * texDim.y); + int y = int(idx / texDim.x); + int x = int(integerMod(idx, texDim.x)); + return ivec3(x, y, z); +} + +float get32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + return decode32(texel); +} + +float get16(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int w = texSize.x * 2; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize.x * 2, texSize.y)); + return decode16(texel, index); +} + +float get8(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int w = texSize.x * 4; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize.x * 4, texSize.y)); + return decode8(texel, index); +} + +float getMemoryOptimized32(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + (texDim.x * (y + (texDim.y * z))); + int channel = integerMod(index, 4); + index = index / 4; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + index = index / 4; + vec4 texel = texture(tex, st / vec2(texSize)); + return texel[channel]; +} + +vec4 getImage2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture(tex, st / vec2(texSize)); +} + +vec4 getImage3D(sampler2DArray tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + return texture(tex, vec3(st / vec2(texSize), z)); +} + +float getFloatFromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return result[0]; +} + +vec2 getVec2FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec2(result[0], result[1]); +} + +vec2 getMemoryOptimizedVec2(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + index = index / 2; + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + if (channel == 0) return vec2(texel.r, texel.g); + if (channel == 1) return vec2(texel.b, texel.a); + return vec2(0.0, 0.0); +} + +vec3 getVec3FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + vec4 result = getImage2D(tex, texSize, texDim, z, y, x); + return vec3(result[0], result[1], result[2]); +} + +vec3 getMemoryOptimizedVec3(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int fieldIndex = 3 * (x + texDim.x * (y + texDim.y * z)); + int vectorIndex = fieldIndex / 4; + int vectorOffset = fieldIndex - vectorIndex * 4; + int readY = vectorIndex / texSize.x; + int readX = vectorIndex - readY * texSize.x; + vec4 tex1 = texture(tex, (vec2(readX, readY) + 0.5) / vec2(texSize)); + + if (vectorOffset == 0) { + return tex1.xyz; + } else if (vectorOffset == 1) { + return tex1.yzw; + } else { + readX++; + if (readX >= texSize.x) { + readX = 0; + readY++; + } + vec4 tex2 = texture(tex, vec2(readX, readY) / vec2(texSize)); + if (vectorOffset == 2) { + return vec3(tex1.z, tex1.w, tex2.x); + } else { + return vec3(tex1.w, tex2.x, tex2.y); + } + } +} + +vec4 getVec4FromSampler2D(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + return getImage2D(tex, texSize, texDim, z, y, x); +} + +vec4 getMemoryOptimizedVec4(sampler2D tex, ivec2 texSize, ivec3 texDim, int z, int y, int x) { + int index = x + texDim.x * (y + texDim.y * z); + int channel = integerMod(index, 2); + int w = texSize.x; + vec2 st = vec2(float(integerMod(index, w)), float(index / w)) + 0.5; + vec4 texel = texture(tex, st / vec2(texSize)); + return vec4(texel.r, texel.g, texel.b, texel.a); +} + +vec4 actualColor; +void color(float r, float g, float b, float a) { + actualColor = vec4(r,g,b,a); +} + +void color(float r, float g, float b) { + color(r,g,b,1.0); +} + +__INJECTED_NATIVE__; +__MAIN_CONSTANTS__; +__MAIN_ARGUMENTS__; +__KERNEL__; + +void main(void) { + index = int(vTexCoord.s * float(uTexSize.x)) + int(vTexCoord.t * float(uTexSize.y)) * uTexSize.x; + __MAIN_RESULT__; +}`; diff --git a/src/backend/web-gl2/function-node.js b/src/backend/web-gl2/function-node.js index ccf35af4..7db91258 100644 --- a/src/backend/web-gl2/function-node.js +++ b/src/backend/web-gl2/function-node.js @@ -1,45 +1,41 @@ -const { WebGLFunctionNode } = require('../web-gl/function-node'); - -/** - * @class WebGL2FunctionNode - * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective webGL code. - * @extends WebGLFunctionNode - * @returns the converted webGL function string - */ -class WebGL2FunctionNode extends WebGLFunctionNode { - - /** - * @desc Parses the abstract syntax tree for *identifier* expression - * @param {Object} idtNode - An ast Node - * @param {Array} retArr - return array string - * @returns {Array} the append retArr - */ - astIdentifierExpression(idtNode, retArr) { - if (idtNode.type !== 'Identifier') { - throw this.astErrorOutput( - 'IdentifierExpression - not an Identifier', - idtNode - ); - } - - const type = this.getType(idtNode); - - if (idtNode.name === 'Infinity') { - retArr.push('intBitsToFloat(2139095039)'); - } else if (type === 'Boolean') { - if (this.argumentNames.indexOf(idtNode.name) > -1) { - retArr.push(`bool(user_${idtNode.name})`); - } else { - retArr.push(`user_${idtNode.name}`); - } - } else { - retArr.push(`user_${idtNode.name}`); - } - - return retArr; - } -} - -module.exports = { - WebGL2FunctionNode -}; \ No newline at end of file +import { WebGLFunctionNode } from '../web-gl/function-node'; + +/** + * @class WebGL2FunctionNode + * @desc [INTERNAL] Takes in a function node, and does all the AST voodoo required to toString its respective webGL code. + * @extends WebGLFunctionNode + * @returns the converted webGL function string + */ +export class WebGL2FunctionNode extends WebGLFunctionNode { + + /** + * @desc Parses the abstract syntax tree for *identifier* expression + * @param {Object} idtNode - An ast Node + * @param {Array} retArr - return array string + * @returns {Array} the append retArr + */ + astIdentifierExpression(idtNode, retArr) { + if (idtNode.type !== 'Identifier') { + throw this.astErrorOutput( + 'IdentifierExpression - not an Identifier', + idtNode + ); + } + + const type = this.getType(idtNode); + + if (idtNode.name === 'Infinity') { + retArr.push('intBitsToFloat(2139095039)'); + } else if (type === 'Boolean') { + if (this.argumentNames.indexOf(idtNode.name) > -1) { + retArr.push(`bool(user_${idtNode.name})`); + } else { + retArr.push(`user_${idtNode.name}`); + } + } else { + retArr.push(`user_${idtNode.name}`); + } + + return retArr; + } +} diff --git a/src/backend/web-gl2/kernel-value-maps.js b/src/backend/web-gl2/kernel-value-maps.js index 357fa824..67e8a856 100644 --- a/src/backend/web-gl2/kernel-value-maps.js +++ b/src/backend/web-gl2/kernel-value-maps.js @@ -1,189 +1,184 @@ -const { WebGL2KernelValueBoolean } = require('./kernel-value/boolean'); -const { WebGL2KernelValueFloat } = require('./kernel-value/float'); -const { WebGL2KernelValueInteger } = require('./kernel-value/integer'); - -const { WebGL2KernelValueHTMLImage } = require('./kernel-value/html-image'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./kernel-value/dynamic-html-image'); - -const { WebGL2KernelValueHTMLImageArray } = require('./kernel-value/html-image-array'); -const { WebGL2KernelValueDynamicHTMLImageArray } = require('./kernel-value/dynamic-html-image-array'); - -const { WebGL2KernelValueHTMLVideo } = require('./kernel-value/html-video'); -const { WebGL2KernelValueDynamicHTMLVideo } = require('./kernel-value/dynamic-html-video'); - -const { WebGL2KernelValueSingleInput } = require('./kernel-value/single-input'); -const { WebGL2KernelValueDynamicSingleInput } = require('./kernel-value/dynamic-single-input'); - -const { WebGL2KernelValueUnsignedInput } = require('./kernel-value/unsigned-input'); -const { WebGL2KernelValueDynamicUnsignedInput } = require('./kernel-value/dynamic-unsigned-input'); - -const { WebGL2KernelValueMemoryOptimizedNumberTexture } = require('./kernel-value/memory-optimized-number-texture'); -const { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } = require('./kernel-value/dynamic-memory-optimized-number-texture'); - -const { WebGL2KernelValueNumberTexture } = require('./kernel-value/number-texture'); -const { WebGL2KernelValueDynamicNumberTexture } = require('./kernel-value/dynamic-number-texture'); - -const { WebGL2KernelValueSingleArray } = require('./kernel-value/single-array'); -const { WebGL2KernelValueDynamicSingleArray } = require('./kernel-value/dynamic-single-array'); - -const { WebGL2KernelValueSingleArray1DI } = require('./kernel-value/single-array1d-i'); -const { WebGL2KernelValueDynamicSingleArray1DI } = require('./kernel-value/dynamic-single-array1d-i'); - -const { WebGL2KernelValueSingleArray2DI } = require('./kernel-value/single-array2d-i'); -const { WebGL2KernelValueDynamicSingleArray2DI } = require('./kernel-value/dynamic-single-array2d-i'); - -const { WebGL2KernelValueSingleArray3DI } = require('./kernel-value/single-array3d-i'); -const { WebGL2KernelValueDynamicSingleArray3DI } = require('./kernel-value/dynamic-single-array3d-i'); - -const { WebGL2KernelValueSingleArray2 } = require('./kernel-value/single-array2'); -const { WebGL2KernelValueSingleArray3 } = require('./kernel-value/single-array3'); -const { WebGL2KernelValueSingleArray4 } = require('./kernel-value/single-array4'); - -const { WebGL2KernelValueUnsignedArray } = require('./kernel-value/unsigned-array'); -const { WebGL2KernelValueDynamicUnsignedArray } = require('./kernel-value/dynamic-unsigned-array'); - -const kernelValueMaps = { - unsigned: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGL2KernelValueDynamicUnsignedInput, - 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueUnsignedArray, - 'Array(2)': false, - 'Array(3)': false, - 'Array(4)': false, - 'Array1D(2)': false, - 'Array1D(3)': false, - 'Array1D(4)': false, - 'Array2D(2)': false, - 'Array2D(3)': false, - 'Array2D(4)': false, - 'Array3D(2)': false, - 'Array3D(3)': false, - 'Array3D(4)': false, - 'Input': WebGL2KernelValueUnsignedInput, - 'NumberTexture': WebGL2KernelValueNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, - single: { - dynamic: { - 'Boolean': WebGL2KernelValueBoolean, - 'Integer': WebGL2KernelValueInteger, - 'Float': WebGL2KernelValueFloat, - 'Array': WebGL2KernelValueDynamicSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI, - 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI, - 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI, - 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI, - 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI, - 'Input': WebGL2KernelValueDynamicSingleInput, - 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, - 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, - }, - static: { - 'Boolean': WebGL2KernelValueBoolean, - 'Float': WebGL2KernelValueFloat, - 'Integer': WebGL2KernelValueInteger, - 'Array': WebGL2KernelValueSingleArray, - 'Array(2)': WebGL2KernelValueSingleArray2, - 'Array(3)': WebGL2KernelValueSingleArray3, - 'Array(4)': WebGL2KernelValueSingleArray4, - 'Array1D(2)': WebGL2KernelValueSingleArray1DI, - 'Array1D(3)': WebGL2KernelValueSingleArray1DI, - 'Array1D(4)': WebGL2KernelValueSingleArray1DI, - 'Array2D(2)': WebGL2KernelValueSingleArray2DI, - 'Array2D(3)': WebGL2KernelValueSingleArray2DI, - 'Array2D(4)': WebGL2KernelValueSingleArray2DI, - 'Array3D(2)': WebGL2KernelValueSingleArray3DI, - 'Array3D(3)': WebGL2KernelValueSingleArray3DI, - 'Array3D(4)': WebGL2KernelValueSingleArray3DI, - 'Input': WebGL2KernelValueSingleInput, - 'NumberTexture': WebGL2KernelValueNumberTexture, - 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, - 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, - 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture, - 'HTMLImage': WebGL2KernelValueHTMLImage, - 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, - 'HTMLVideo': WebGL2KernelValueHTMLVideo, - } - }, -}; - -function lookupKernelValueType(type, dynamic, precision, value) { - if (!type) { - throw new Error('type missing'); - } - if (!dynamic) { - throw new Error('dynamic missing'); - } - if (!precision) { - throw new Error('precision missing'); - } - if (value.type) { - type = value.type; - } - const types = kernelValueMaps[precision][dynamic]; - if (types[type] === false) { - return null; - } else if (types[type] === undefined) { - throw new Error(`Could not find a KernelValue for ${ type }`); - } - return types[type]; -} - -module.exports = { - kernelValueMaps, - lookupKernelValueType -}; \ No newline at end of file +import { WebGL2KernelValueBoolean } from './kernel-value/boolean'; +import { WebGL2KernelValueFloat } from './kernel-value/float'; +import { WebGL2KernelValueInteger } from './kernel-value/integer'; + +import { WebGL2KernelValueHTMLImage } from './kernel-value/html-image'; +import { WebGL2KernelValueDynamicHTMLImage } from './kernel-value/dynamic-html-image'; + +import { WebGL2KernelValueHTMLImageArray } from './kernel-value/html-image-array'; +import { WebGL2KernelValueDynamicHTMLImageArray } from './kernel-value/dynamic-html-image-array'; + +import { WebGL2KernelValueHTMLVideo } from './kernel-value/html-video'; +import { WebGL2KernelValueDynamicHTMLVideo } from './kernel-value/dynamic-html-video'; + +import { WebGL2KernelValueSingleInput } from './kernel-value/single-input'; +import { WebGL2KernelValueDynamicSingleInput } from './kernel-value/dynamic-single-input'; + +import { WebGL2KernelValueUnsignedInput } from './kernel-value/unsigned-input'; +import { WebGL2KernelValueDynamicUnsignedInput } from './kernel-value/dynamic-unsigned-input'; + +import { WebGL2KernelValueMemoryOptimizedNumberTexture } from './kernel-value/memory-optimized-number-texture'; +import { WebGL2KernelValueDynamicMemoryOptimizedNumberTexture } from './kernel-value/dynamic-memory-optimized-number-texture'; + +import { WebGL2KernelValueNumberTexture } from './kernel-value/number-texture'; +import { WebGL2KernelValueDynamicNumberTexture } from './kernel-value/dynamic-number-texture'; + +import { WebGL2KernelValueSingleArray } from './kernel-value/single-array'; +import { WebGL2KernelValueDynamicSingleArray } from './kernel-value/dynamic-single-array'; + +import { WebGL2KernelValueSingleArray1DI } from './kernel-value/single-array1d-i'; +import { WebGL2KernelValueDynamicSingleArray1DI } from './kernel-value/dynamic-single-array1d-i'; + +import { WebGL2KernelValueSingleArray2DI } from './kernel-value/single-array2d-i'; +import { WebGL2KernelValueDynamicSingleArray2DI } from './kernel-value/dynamic-single-array2d-i'; + +import { WebGL2KernelValueSingleArray3DI } from './kernel-value/single-array3d-i'; +import { WebGL2KernelValueDynamicSingleArray3DI } from './kernel-value/dynamic-single-array3d-i'; + +import { WebGL2KernelValueSingleArray2 } from './kernel-value/single-array2'; +import { WebGL2KernelValueSingleArray3 } from './kernel-value/single-array3'; +import { WebGL2KernelValueSingleArray4 } from './kernel-value/single-array4'; + +import { WebGL2KernelValueUnsignedArray } from './kernel-value/unsigned-array'; +import { WebGL2KernelValueDynamicUnsignedArray } from './kernel-value/dynamic-unsigned-array'; + +export const kernelValueMaps = { + unsigned: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGL2KernelValueDynamicUnsignedInput, + 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueUnsignedArray, + 'Array(2)': false, + 'Array(3)': false, + 'Array(4)': false, + 'Array1D(2)': false, + 'Array1D(3)': false, + 'Array1D(4)': false, + 'Array2D(2)': false, + 'Array2D(3)': false, + 'Array2D(4)': false, + 'Array3D(2)': false, + 'Array3D(3)': false, + 'Array3D(4)': false, + 'Input': WebGL2KernelValueUnsignedInput, + 'NumberTexture': WebGL2KernelValueNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, + single: { + dynamic: { + 'Boolean': WebGL2KernelValueBoolean, + 'Integer': WebGL2KernelValueInteger, + 'Float': WebGL2KernelValueFloat, + 'Array': WebGL2KernelValueDynamicSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + 'Array1D(2)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array1D(3)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array1D(4)': WebGL2KernelValueDynamicSingleArray1DI, + 'Array2D(2)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array2D(3)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array2D(4)': WebGL2KernelValueDynamicSingleArray2DI, + 'Array3D(2)': WebGL2KernelValueDynamicSingleArray3DI, + 'Array3D(3)': WebGL2KernelValueDynamicSingleArray3DI, + 'Array3D(4)': WebGL2KernelValueDynamicSingleArray3DI, + 'Input': WebGL2KernelValueDynamicSingleInput, + 'NumberTexture': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueDynamicNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueDynamicNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueDynamicMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueDynamicHTMLImage, + 'HTMLImageArray': WebGL2KernelValueDynamicHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueDynamicHTMLVideo, + }, + static: { + 'Boolean': WebGL2KernelValueBoolean, + 'Float': WebGL2KernelValueFloat, + 'Integer': WebGL2KernelValueInteger, + 'Array': WebGL2KernelValueSingleArray, + 'Array(2)': WebGL2KernelValueSingleArray2, + 'Array(3)': WebGL2KernelValueSingleArray3, + 'Array(4)': WebGL2KernelValueSingleArray4, + 'Array1D(2)': WebGL2KernelValueSingleArray1DI, + 'Array1D(3)': WebGL2KernelValueSingleArray1DI, + 'Array1D(4)': WebGL2KernelValueSingleArray1DI, + 'Array2D(2)': WebGL2KernelValueSingleArray2DI, + 'Array2D(3)': WebGL2KernelValueSingleArray2DI, + 'Array2D(4)': WebGL2KernelValueSingleArray2DI, + 'Array3D(2)': WebGL2KernelValueSingleArray3DI, + 'Array3D(3)': WebGL2KernelValueSingleArray3DI, + 'Array3D(4)': WebGL2KernelValueSingleArray3DI, + 'Input': WebGL2KernelValueSingleInput, + 'NumberTexture': WebGL2KernelValueNumberTexture, + 'ArrayTexture(1)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(2)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(3)': WebGL2KernelValueNumberTexture, + 'ArrayTexture(4)': WebGL2KernelValueNumberTexture, + 'MemoryOptimizedNumberTexture': WebGL2KernelValueMemoryOptimizedNumberTexture, + 'HTMLImage': WebGL2KernelValueHTMLImage, + 'HTMLImageArray': WebGL2KernelValueHTMLImageArray, + 'HTMLVideo': WebGL2KernelValueHTMLVideo, + } + }, +}; + +export function lookupKernelValueType(type, dynamic, precision, value) { + if (!type) { + throw new Error('type missing'); + } + if (!dynamic) { + throw new Error('dynamic missing'); + } + if (!precision) { + throw new Error('precision missing'); + } + if (value.type) { + type = value.type; + } + const types = kernelValueMaps[precision][dynamic]; + if (types[type] === false) { + return null; + } else if (types[type] === undefined) { + throw new Error(`Could not find a KernelValue for ${ type }`); + } + return types[type]; +} diff --git a/src/backend/web-gl2/kernel-value/boolean.js b/src/backend/web-gl2/kernel-value/boolean.js index c91a61a9..3f765060 100644 --- a/src/backend/web-gl2/kernel-value/boolean.js +++ b/src/backend/web-gl2/kernel-value/boolean.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueBoolean } = require('../../web-gl/kernel-value/boolean'); - -class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} - -module.exports = { - WebGL2KernelValueBoolean -}; \ No newline at end of file +import { WebGLKernelValueBoolean } from '../../web-gl/kernel-value/boolean'; + +export class WebGL2KernelValueBoolean extends WebGLKernelValueBoolean {} diff --git a/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js b/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js index dab14341..c96ef1ce 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js +++ b/src/backend/web-gl2/kernel-value/dynamic-html-image-array.js @@ -1,26 +1,22 @@ -const { WebGL2KernelValueHTMLImageArray } = require('./html-image-array'); - -class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2DArray ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(images) { - const { width, height } = images[0]; - this.checkSize(width, height); - this.dimensions = [width, height, images.length]; - this.textureSize = [width, height]; - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(images); - } -} - -module.exports = { - WebGL2KernelValueDynamicHTMLImageArray -}; \ No newline at end of file +import { WebGL2KernelValueHTMLImageArray } from './html-image-array'; + +export class WebGL2KernelValueDynamicHTMLImageArray extends WebGL2KernelValueHTMLImageArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2DArray ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(images) { + const { width, height } = images[0]; + this.checkSize(width, height); + this.dimensions = [width, height, images.length]; + this.textureSize = [width, height]; + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(images); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-html-image.js b/src/backend/web-gl2/kernel-value/dynamic-html-image.js index f1ba34eb..352bfe56 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-html-image.js +++ b/src/backend/web-gl2/kernel-value/dynamic-html-image.js @@ -1,17 +1,13 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicHTMLImage } = require('../../web-gl/kernel-value/dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicHTMLImage -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicHTMLImage } from '../../web-gl/kernel-value/dynamic-html-image'; + +export class WebGL2KernelValueDynamicHTMLImage extends WebGLKernelValueDynamicHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-html-video.js b/src/backend/web-gl2/kernel-value/dynamic-html-video.js index 00f723d1..81b617f6 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-html-video.js +++ b/src/backend/web-gl2/kernel-value/dynamic-html-video.js @@ -1,8 +1,3 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueDynamicHTMLImage } = require('./dynamic-html-image'); - -class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} - -module.exports = { - WebGL2KernelValueDynamicHTMLVideo -}; \ No newline at end of file +import { WebGL2KernelValueDynamicHTMLImage } from './dynamic-html-image'; + +export class WebGL2KernelValueDynamicHTMLVideo extends WebGL2KernelValueDynamicHTMLImage {} diff --git a/src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js b/src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js index 5e3cff4b..e0f5d50e 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js +++ b/src/backend/web-gl2/kernel-value/dynamic-memory-optimized-number-texture.js @@ -1,16 +1,12 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/dynamic-memory-optimized-number-texture'); - -class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { - getSource() { - return utils.linesToString([ - `uniform sampler2D ${this.id}`, - `uniform ivec2 ${this.sizeId}`, - `uniform ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicMemoryOptimizedNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/dynamic-memory-optimized-number-texture'; + +export class WebGL2KernelValueDynamicMemoryOptimizedNumberTexture extends WebGLKernelValueDynamicMemoryOptimizedNumberTexture { + getSource() { + return utils.linesToString([ + `uniform sampler2D ${this.id}`, + `uniform ivec2 ${this.sizeId}`, + `uniform ivec3 ${this.dimensionsId}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-number-texture.js b/src/backend/web-gl2/kernel-value/dynamic-number-texture.js index e3820a56..443b7425 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-number-texture.js +++ b/src/backend/web-gl2/kernel-value/dynamic-number-texture.js @@ -1,17 +1,13 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicNumberTexture } = require('../../web-gl/kernel-value/dynamic-number-texture'); - -class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicNumberTexture } from '../../web-gl/kernel-value/dynamic-number-texture'; + +export class WebGL2KernelValueDynamicNumberTexture extends WebGLKernelValueDynamicNumberTexture { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array.js b/src/backend/web-gl2/kernel-value/dynamic-single-array.js index 3356cdbf..9374fc2a 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-array.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-array.js @@ -1,28 +1,24 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray } = require('../../web-gl2/kernel-value/single-array'); - -class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.dimensions = utils.getDimensions(value, true); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleArray } from '../../web-gl2/kernel-value/single-array'; + +export class WebGL2KernelValueDynamicSingleArray extends WebGL2KernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.dimensions = utils.getDimensions(value, true); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js b/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js index 45203f92..344b79d1 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-array1d-i.js @@ -1,24 +1,20 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray1DI } = require('../../web-gl2/kernel-value/single-array1d-i'); - -class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray1DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleArray1DI } from '../../web-gl2/kernel-value/single-array1d-i'; + +export class WebGL2KernelValueDynamicSingleArray1DI extends WebGL2KernelValueSingleArray1DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js b/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js index d80f712d..127bb64f 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-array2d-i.js @@ -1,24 +1,20 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray2DI } = require('../../web-gl2/kernel-value/single-array2d-i'); - -class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray2DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleArray2DI } from '../../web-gl2/kernel-value/single-array2d-i'; + +export class WebGL2KernelValueDynamicSingleArray2DI extends WebGL2KernelValueSingleArray2DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js b/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js index 15f79ba4..1dd343f5 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-array3d-i.js @@ -1,24 +1,20 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleArray3DI } = require('../../web-gl2/kernel-value/single-array3d-i'); - -class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - this.setShape(value); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleArray3DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleArray3DI } from '../../web-gl2/kernel-value/single-array3d-i'; + +export class WebGL2KernelValueDynamicSingleArray3DI extends WebGL2KernelValueSingleArray3DI { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + this.setShape(value); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-single-input.js b/src/backend/web-gl2/kernel-value/dynamic-single-input.js index 02058a11..95ee750a 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-single-input.js +++ b/src/backend/web-gl2/kernel-value/dynamic-single-input.js @@ -1,29 +1,25 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueSingleInput } = require('../../web-gl2/kernel-value/single-input'); - -class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } - - updateValue(value) { - let [w, h, d] = value.size; - this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); - this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); - this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; - this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); - this.uploadValue = new Float32Array(this.uploadArrayLength); - this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); - this.kernel.setUniform2iv(this.sizeId, this.textureSize); - super.updateValue(value); - } -} - -module.exports = { - WebGL2KernelValueDynamicSingleInput -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGL2KernelValueSingleInput } from '../../web-gl2/kernel-value/single-input'; + +export class WebGL2KernelValueDynamicSingleInput extends WebGL2KernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } + + updateValue(value) { + let [w, h, d] = value.size; + this.dimensions = new Int32Array([w || 1, h || 1, d || 1]); + this.textureSize = utils.getMemoryOptimizedFloatTextureSize(this.dimensions, this.bitRatio); + this.uploadArrayLength = this.textureSize[0] * this.textureSize[1] * this.bitRatio; + this.checkSize(this.textureSize[0] * this.bitRatio, this.textureSize[1] * this.bitRatio); + this.uploadValue = new Float32Array(this.uploadArrayLength); + this.kernel.setUniform3iv(this.dimensionsId, this.dimensions); + this.kernel.setUniform2iv(this.sizeId, this.textureSize); + super.updateValue(value); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js b/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js index 514682c5..1190d00d 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js +++ b/src/backend/web-gl2/kernel-value/dynamic-unsigned-array.js @@ -1,17 +1,13 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicUnsignedArray } = require('../../web-gl/kernel-value/dynamic-unsigned-array'); - -class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicUnsignedArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicUnsignedArray } from '../../web-gl/kernel-value/dynamic-unsigned-array'; + +export class WebGL2KernelValueDynamicUnsignedArray extends WebGLKernelValueDynamicUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js b/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js index 9c79330a..c9311fa8 100644 --- a/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js +++ b/src/backend/web-gl2/kernel-value/dynamic-unsigned-input.js @@ -1,17 +1,13 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueDynamicUnsignedInput } = require('../../web-gl/kernel-value/dynamic-unsigned-input'); - -class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, - `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, - ]); - } -} - -module.exports = { - WebGL2KernelValueDynamicUnsignedInput -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueDynamicUnsignedInput } from '../../web-gl/kernel-value/dynamic-unsigned-input'; + +export class WebGL2KernelValueDynamicUnsignedInput extends WebGLKernelValueDynamicUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `uniform ${ variablePrecision } ivec2 ${this.sizeId}`, + `uniform ${ variablePrecision } ivec3 ${this.dimensionsId}`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/float.js b/src/backend/web-gl2/kernel-value/float.js index b3fc5a78..0ebc9a6c 100644 --- a/src/backend/web-gl2/kernel-value/float.js +++ b/src/backend/web-gl2/kernel-value/float.js @@ -1,8 +1,3 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueFloat } = require('../../web-gl/kernel-value/float'); - -class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} - -module.exports = { - WebGL2KernelValueFloat -}; \ No newline at end of file +import { WebGLKernelValueFloat } from '../../web-gl/kernel-value/float'; + +export class WebGL2KernelValueFloat extends WebGLKernelValueFloat {} diff --git a/src/backend/web-gl2/kernel-value/html-image-array.js b/src/backend/web-gl2/kernel-value/html-image-array.js index 07303b4b..634965e4 100644 --- a/src/backend/web-gl2/kernel-value/html-image-array.js +++ b/src/backend/web-gl2/kernel-value/html-image-array.js @@ -1,68 +1,64 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValue } = require('../../web-gl/kernel-value/index'); - -class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { - constructor(value, settings) { - super(value, settings); - this.checkSize(value[0].width, value[0].height); - this.requestTexture(); - this.dimensions = [value[0].width, value[0].height, value.length]; - this.textureSize = [value[0].width, value[0].height]; - } - getStringValueHandler() { - return `const uploadValue_${this.name} = ${this.varName};\n`; - } - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2DArray ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(images) { - const { context: gl } = this; - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); - // Upload the images into the texture. - gl.texImage3D( - gl.TEXTURE_2D_ARRAY, - 0, - gl.RGBA, - images[0].width, - images[0].height, - images.length, - 0, - gl.RGBA, - gl.UNSIGNED_BYTE, - null - ); - for (let i = 0; i < images.length; i++) { - const xOffset = 0; - const yOffset = 0; - const imageDepth = 1; - gl.texSubImage3D( - gl.TEXTURE_2D_ARRAY, - 0, - xOffset, - yOffset, - i, - images[i].width, - images[i].height, - imageDepth, - gl.RGBA, - gl.UNSIGNED_BYTE, - this.uploadValue = images[i] - ); - } - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueHTMLImageArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValue } from '../../web-gl/kernel-value/index'; + +export class WebGL2KernelValueHTMLImageArray extends WebGLKernelValue { + constructor(value, settings) { + super(value, settings); + this.checkSize(value[0].width, value[0].height); + this.requestTexture(); + this.dimensions = [value[0].width, value[0].height, value.length]; + this.textureSize = [value[0].width, value[0].height]; + } + getStringValueHandler() { + return `const uploadValue_${this.name} = ${this.varName};\n`; + } + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2DArray ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(images) { + const { context: gl } = this; + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); + // Upload the images into the texture. + gl.texImage3D( + gl.TEXTURE_2D_ARRAY, + 0, + gl.RGBA, + images[0].width, + images[0].height, + images.length, + 0, + gl.RGBA, + gl.UNSIGNED_BYTE, + null + ); + for (let i = 0; i < images.length; i++) { + const xOffset = 0; + const yOffset = 0; + const imageDepth = 1; + gl.texSubImage3D( + gl.TEXTURE_2D_ARRAY, + 0, + xOffset, + yOffset, + i, + images[i].width, + images[i].height, + imageDepth, + gl.RGBA, + gl.UNSIGNED_BYTE, + this.uploadValue = images[i] + ); + } + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl2/kernel-value/html-image.js b/src/backend/web-gl2/kernel-value/html-image.js index 637182a0..e749aaf7 100644 --- a/src/backend/web-gl2/kernel-value/html-image.js +++ b/src/backend/web-gl2/kernel-value/html-image.js @@ -1,17 +1,13 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueHTMLImage } = require('../../web-gl/kernel-value/html-image'); - -class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueHTMLImage -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueHTMLImage } from '../../web-gl/kernel-value/html-image'; + +export class WebGL2KernelValueHTMLImage extends WebGLKernelValueHTMLImage { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/html-video.js b/src/backend/web-gl2/kernel-value/html-video.js index 85fb3953..665773ff 100644 --- a/src/backend/web-gl2/kernel-value/html-video.js +++ b/src/backend/web-gl2/kernel-value/html-video.js @@ -1,8 +1,3 @@ -const { utils } = require('../../../utils'); -const { WebGL2KernelValueHTMLImage } = require('./html-image'); - -class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} - -module.exports = { - WebGL2KernelValueHTMLVideo -}; \ No newline at end of file +import { WebGL2KernelValueHTMLImage } from './html-image'; + +export class WebGL2KernelValueHTMLVideo extends WebGL2KernelValueHTMLImage {} diff --git a/src/backend/web-gl2/kernel-value/integer.js b/src/backend/web-gl2/kernel-value/integer.js index a41a2533..530df2fb 100644 --- a/src/backend/web-gl2/kernel-value/integer.js +++ b/src/backend/web-gl2/kernel-value/integer.js @@ -1,21 +1,16 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueInteger } = require('../../web-gl/kernel-value/integer'); - -class WebGL2KernelValueInteger extends WebGLKernelValueInteger { - getSource(value) { - const variablePrecision = this.getVariablePrecisionString(); - if (this.origin === 'constants') { - return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`; - } - return `uniform ${ variablePrecision } int ${this.id};\n`; - } - - updateValue(value) { - if (this.origin === 'constants') return; - this.kernel.setUniform1i(this.id, this.uploadValue = value); - } -} - -module.exports = { - WebGL2KernelValueInteger -}; \ No newline at end of file +import { WebGLKernelValueInteger } from '../../web-gl/kernel-value/integer'; + +export class WebGL2KernelValueInteger extends WebGLKernelValueInteger { + getSource(value) { + const variablePrecision = this.getVariablePrecisionString(); + if (this.origin === 'constants') { + return `const ${ variablePrecision } int ${this.id} = ${ parseInt(value) };\n`; + } + return `uniform ${ variablePrecision } int ${this.id};\n`; + } + + updateValue(value) { + if (this.origin === 'constants') return; + this.kernel.setUniform1i(this.id, this.uploadValue = value); + } +} diff --git a/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js b/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js index 7fd85798..d4830b97 100644 --- a/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js +++ b/src/backend/web-gl2/kernel-value/memory-optimized-number-texture.js @@ -1,18 +1,14 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueMemoryOptimizedNumberTexture } = require('../../web-gl/kernel-value/memory-optimized-number-texture'); - -class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { - getSource() { - const { id, sizeId, textureSize, dimensionsId, dimensions } = this; - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform sampler2D ${id}`, - `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, - `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueMemoryOptimizedNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueMemoryOptimizedNumberTexture } from '../../web-gl/kernel-value/memory-optimized-number-texture'; + +export class WebGL2KernelValueMemoryOptimizedNumberTexture extends WebGLKernelValueMemoryOptimizedNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/number-texture.js b/src/backend/web-gl2/kernel-value/number-texture.js index 440f1e4e..d638c528 100644 --- a/src/backend/web-gl2/kernel-value/number-texture.js +++ b/src/backend/web-gl2/kernel-value/number-texture.js @@ -1,18 +1,14 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueNumberTexture } = require('../../web-gl/kernel-value/number-texture'); - -class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture { - getSource() { - const { id, sizeId, textureSize, dimensionsId, dimensions } = this; - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${id}`, - `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, - `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueNumberTexture -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueNumberTexture } from '../../web-gl/kernel-value/number-texture'; + +export class WebGL2KernelValueNumberTexture extends WebGLKernelValueNumberTexture { + getSource() { + const { id, sizeId, textureSize, dimensionsId, dimensions } = this; + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${id}`, + `${ variablePrecision } ivec2 ${sizeId} = ivec2(${textureSize[0]}, ${textureSize[1]})`, + `${ variablePrecision } ivec3 ${dimensionsId} = ivec3(${dimensions[0]}, ${dimensions[1]}, ${dimensions[2]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array.js b/src/backend/web-gl2/kernel-value/single-array.js index c6ff3d9b..6bce4a4a 100644 --- a/src/backend/web-gl2/kernel-value/single-array.js +++ b/src/backend/web-gl2/kernel-value/single-array.js @@ -1,34 +1,30 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray } = require('../../web-gl/kernel-value/single-array'); - -class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray } from '../../web-gl/kernel-value/single-array'; + +export class WebGL2KernelValueSingleArray extends WebGLKernelValueSingleArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array1d-i.js b/src/backend/web-gl2/kernel-value/single-array1d-i.js index 6a64101d..a380c9c9 100644 --- a/src/backend/web-gl2/kernel-value/single-array1d-i.js +++ b/src/backend/web-gl2/kernel-value/single-array1d-i.js @@ -1,25 +1,21 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray1DI } = require('../../web-gl/kernel-value/single-array1d-i'); - -class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleArray1DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray1DI } from '../../web-gl/kernel-value/single-array1d-i'; + +export class WebGL2KernelValueSingleArray1DI extends WebGLKernelValueSingleArray1DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array2.js b/src/backend/web-gl2/kernel-value/single-array2.js index 638125fb..ff41ed60 100644 --- a/src/backend/web-gl2/kernel-value/single-array2.js +++ b/src/backend/web-gl2/kernel-value/single-array2.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueSingleArray2 } = require('../../web-gl/kernel-value/single-array2'); - -class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} - -module.exports = { - WebGL2KernelValueSingleArray2 -}; \ No newline at end of file +import { WebGLKernelValueSingleArray2 } from '../../web-gl/kernel-value/single-array2'; + +export class WebGL2KernelValueSingleArray2 extends WebGLKernelValueSingleArray2 {} diff --git a/src/backend/web-gl2/kernel-value/single-array2d-i.js b/src/backend/web-gl2/kernel-value/single-array2d-i.js index 8374e67c..4c62c47f 100644 --- a/src/backend/web-gl2/kernel-value/single-array2d-i.js +++ b/src/backend/web-gl2/kernel-value/single-array2d-i.js @@ -1,25 +1,21 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray2DI } = require('../../web-gl/kernel-value/single-array2d-i'); - -class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleArray2DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray2DI } from '../../web-gl/kernel-value/single-array2d-i'; + +export class WebGL2KernelValueSingleArray2DI extends WebGLKernelValueSingleArray2DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array3.js b/src/backend/web-gl2/kernel-value/single-array3.js index 9af01c8f..3dc5df84 100644 --- a/src/backend/web-gl2/kernel-value/single-array3.js +++ b/src/backend/web-gl2/kernel-value/single-array3.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueSingleArray3 } = require('../../web-gl/kernel-value/single-array3'); - -class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} - -module.exports = { - WebGL2KernelValueSingleArray3 -}; \ No newline at end of file +import { WebGLKernelValueSingleArray3 } from '../../web-gl/kernel-value/single-array3'; + +export class WebGL2KernelValueSingleArray3 extends WebGLKernelValueSingleArray3 {} diff --git a/src/backend/web-gl2/kernel-value/single-array3d-i.js b/src/backend/web-gl2/kernel-value/single-array3d-i.js index ea850885..382a3600 100644 --- a/src/backend/web-gl2/kernel-value/single-array3d-i.js +++ b/src/backend/web-gl2/kernel-value/single-array3d-i.js @@ -1,25 +1,21 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleArray3DI } = require('../../web-gl/kernel-value/single-array3d-i'); - -class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { - updateValue(value) { - if (value.constructor !== this.initialValueConstructor) { - this.onUpdateValueMismatch(); - return; - } - const { context: gl } = this; - utils.flattenTo(value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleArray3DI -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleArray3DI } from '../../web-gl/kernel-value/single-array3d-i'; + +export class WebGL2KernelValueSingleArray3DI extends WebGLKernelValueSingleArray3DI { + updateValue(value) { + if (value.constructor !== this.initialValueConstructor) { + this.onUpdateValueMismatch(); + return; + } + const { context: gl } = this; + utils.flattenTo(value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl2/kernel-value/single-array4.js b/src/backend/web-gl2/kernel-value/single-array4.js index d5ec9d2a..d84ac6bc 100644 --- a/src/backend/web-gl2/kernel-value/single-array4.js +++ b/src/backend/web-gl2/kernel-value/single-array4.js @@ -1,7 +1,3 @@ -const { WebGLKernelValueSingleArray4 } = require('../../web-gl/kernel-value/single-array4'); - -class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} - -module.exports = { - WebGL2KernelValueSingleArray4 -}; \ No newline at end of file +import { WebGLKernelValueSingleArray4 } from '../../web-gl/kernel-value/single-array4'; + +export class WebGL2KernelValueSingleArray4 extends WebGLKernelValueSingleArray4 {} diff --git a/src/backend/web-gl2/kernel-value/single-input.js b/src/backend/web-gl2/kernel-value/single-input.js index 2bf23acb..6dac696b 100644 --- a/src/backend/web-gl2/kernel-value/single-input.js +++ b/src/backend/web-gl2/kernel-value/single-input.js @@ -1,30 +1,26 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueSingleInput } = require('../../web-gl/kernel-value/single-input'); - -class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } - - updateValue(input) { - const { context: gl } = this; - utils.flattenTo(input.value, this.uploadValue); - gl.activeTexture(this.contextHandle); - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); - this.kernel.setUniform1i(this.id, this.index); - } -} - -module.exports = { - WebGL2KernelValueSingleInput -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueSingleInput } from '../../web-gl/kernel-value/single-input'; + +export class WebGL2KernelValueSingleInput extends WebGLKernelValueSingleInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } + + updateValue(input) { + const { context: gl } = this; + utils.flattenTo(input.value, this.uploadValue); + gl.activeTexture(this.contextHandle); + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, this.textureSize[0], this.textureSize[1], 0, gl.RGBA, gl.FLOAT, this.uploadValue); + this.kernel.setUniform1i(this.id, this.index); + } +} diff --git a/src/backend/web-gl2/kernel-value/unsigned-array.js b/src/backend/web-gl2/kernel-value/unsigned-array.js index bac1e6f1..ca8cff6c 100644 --- a/src/backend/web-gl2/kernel-value/unsigned-array.js +++ b/src/backend/web-gl2/kernel-value/unsigned-array.js @@ -1,17 +1,13 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedArray } = require('../../web-gl/kernel-value/unsigned-array'); - -class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueUnsignedArray -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueUnsignedArray } from '../../web-gl/kernel-value/unsigned-array'; + +export class WebGL2KernelValueUnsignedArray extends WebGLKernelValueUnsignedArray { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel-value/unsigned-input.js b/src/backend/web-gl2/kernel-value/unsigned-input.js index ed933347..7dddcb5f 100644 --- a/src/backend/web-gl2/kernel-value/unsigned-input.js +++ b/src/backend/web-gl2/kernel-value/unsigned-input.js @@ -1,17 +1,13 @@ -const { utils } = require('../../../utils'); -const { WebGLKernelValueUnsignedInput } = require('../../web-gl/kernel-value/unsigned-input'); - -class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput { - getSource() { - const variablePrecision = this.getVariablePrecisionString(); - return utils.linesToString([ - `uniform ${ variablePrecision } sampler2D ${this.id}`, - `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, - `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, - ]); - } -} - -module.exports = { - WebGL2KernelValueUnsignedInput -}; \ No newline at end of file +import { utils } from '../../../utils'; +import { WebGLKernelValueUnsignedInput } from '../../web-gl/kernel-value/unsigned-input'; + +export class WebGL2KernelValueUnsignedInput extends WebGLKernelValueUnsignedInput { + getSource() { + const variablePrecision = this.getVariablePrecisionString(); + return utils.linesToString([ + `uniform ${ variablePrecision } sampler2D ${this.id}`, + `${ variablePrecision } ivec2 ${this.sizeId} = ivec2(${this.textureSize[0]}, ${this.textureSize[1]})`, + `${ variablePrecision } ivec3 ${this.dimensionsId} = ivec3(${this.dimensions[0]}, ${this.dimensions[1]}, ${this.dimensions[2]})`, + ]); + } +} diff --git a/src/backend/web-gl2/kernel.js b/src/backend/web-gl2/kernel.js index d27fdec8..d95a8660 100644 --- a/src/backend/web-gl2/kernel.js +++ b/src/backend/web-gl2/kernel.js @@ -1,685 +1,681 @@ -const { WebGLKernel } = require('../web-gl/kernel'); -const { WebGL2FunctionNode } = require('./function-node'); -const { FunctionBuilder } = require('../function-builder'); -const { utils } = require('../../utils'); -const { fragmentShader } = require('./fragment-shader'); -const { vertexShader } = require('./vertex-shader'); -const { lookupKernelValueType } = require('./kernel-value-maps'); - -let isSupported = null; -let testCanvas = null; -let testContext = null; -let testExtensions = null; - -/** - * - * @type {IKernelFeatures} - */ -let features = null; - -/** - * @extends WebGLKernel - */ -class WebGL2Kernel extends WebGLKernel { - static get isSupported() { - if (isSupported !== null) { - return isSupported; - } - this.setupFeatureChecks(); - isSupported = this.isContextMatch(testContext); - return isSupported; - } - - static setupFeatureChecks() { - if (typeof document !== 'undefined') { - testCanvas = document.createElement('canvas'); - } else if (typeof OffscreenCanvas !== 'undefined') { - testCanvas = new OffscreenCanvas(0, 0); - } - if (!testCanvas) return; - testContext = testCanvas.getContext('webgl2'); - if (!testContext || !testContext.getExtension) return; - testExtensions = { - EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'), - OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), - }; - features = this.getFeatures(); - } - - static isContextMatch(context) { - // from global - if (typeof WebGL2RenderingContext !== 'undefined') { - return context instanceof WebGL2RenderingContext; - } - return false; - } - - static getFeatures() { - return Object.freeze({ - isFloatRead: this.getIsFloatRead(), - isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), - kernelMap: true, - isTextureFloat: true, - channelCount: this.getChannelCount(), - maxTextureSize: this.getMaxTextureSize(), - }); - } - - static getIsTextureFloat() { - return true; - } - - static getIsIntegerDivisionAccurate() { - return super.getIsIntegerDivisionAccurate(); - } - - static getChannelCount() { - return testContext.getParameter(testContext.MAX_DRAW_BUFFERS); - } - - static getMaxTextureSize() { - return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); - } - - static lookupKernelValueType(type, dynamic, precision, value) { - return lookupKernelValueType(type, dynamic, precision, value); - } - - static get testCanvas() { - return testCanvas; - } - - static get testContext() { - return testContext; - } - - /** - * - * @returns {{isFloatRead: Boolean, isIntegerDivisionAccurate: Boolean, kernelMap: Boolean, isTextureFloat: Boolean}} - */ - static get features() { - return features; - } - - static get fragmentShader() { - return fragmentShader; - } - static get vertexShader() { - return vertexShader; - } - - initContext() { - const settings = { - alpha: false, - depth: false, - antialias: false - }; - const context = this.canvas.getContext('webgl2', settings); - return context; - } - - initExtensions() { - this.extensions = { - EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'), - OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), - }; - } - - /** - * @desc Validate settings related to Kernel, such as dimensions size, and auto output support. - * @param {IArguments} args - */ - validateSettings(args) { - if (!this.validate) { - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - return; - } - - const features = this.constructor.features; - if (this.precision === 'single' && !features.isFloatRead) { - throw new Error('Float texture outputs are not supported'); - } else if (!this.graphical && this.precision === null) { - this.precision = features.isFloatRead ? 'single' : 'unsigned'; - } - - if (this.fixIntegerDivisionAccuracy === null) { - this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; - } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { - this.fixIntegerDivisionAccuracy = false; - } - - this.checkOutput(); - - if (!this.output || this.output.length === 0) { - if (args.length !== 1) { - throw new Error('Auto output only supported for kernels with only one input'); - } - - const argType = utils.getVariableType(args[0], this.strictIntegers); - switch (argType) { - case 'Array': - this.output = utils.getDimensions(argType); - break; - case 'NumberTexture': - case 'MemoryOptimizedNumberTexture': - case 'ArrayTexture(1)': - case 'ArrayTexture(2)': - case 'ArrayTexture(3)': - case 'ArrayTexture(4)': - this.output = args[0].output; - break; - default: - throw new Error('Auto output not supported for input type: ' + argType); - } - } - - if (this.graphical) { - if (this.output.length !== 2) { - throw new Error('Output must have 2 dimensions on graphical mode'); - } - - if (this.precision === 'single') { - console.warn('Cannot use graphical mode and single precision at the same time'); - this.precision = 'unsigned'; - } - - this.texSize = utils.clone(this.output); - return; - } else if (!this.graphical && this.precision === null && features.isTextureFloat) { - this.precision = 'single'; - } - - this.texSize = utils.getKernelTextureSize({ - optimizeFloatMemory: this.optimizeFloatMemory, - precision: this.precision, - }, this.output); - - this.checkTextureSize(); - } - - translateSource() { - const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, { - fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy - }); - this.translatedSource = functionBuilder.getPrototypeString('kernel'); - if (!this.graphical && !this.returnType) { - this.returnType = functionBuilder.getKernelResultType(); - } - - if (this.subKernels && this.subKernels.length > 0) { - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (!subKernel.returnType) { - subKernel.returnType = functionBuilder.getSubKernelResultType(i); - } - } - } - } - - run() { - const { kernelArguments, texSize, forceUploadKernelConstants } = this; - const gl = this.context; - - gl.useProgram(this.program); - gl.scissor(0, 0, texSize[0], texSize[1]); - - if (this.dynamicOutput) { - this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); - this.setUniform2iv('uTexSize', texSize); - } - - this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); - - this.switchingKernels = false; - for (let i = 0; i < forceUploadKernelConstants.length; i++) { - const constant = forceUploadKernelConstants[i]; - constant.updateValue(this.constants[constant.name]); - if (this.switchingKernels) return; - } - for (let i = 0; i < kernelArguments.length; i++) { - kernelArguments[i].updateValue(arguments[i]); - if (this.switchingKernels) return; - } - - if (this.plugins) { - for (let i = 0; i < this.plugins.length; i++) { - const plugin = this.plugins[i]; - if (plugin.onBeforeRun) { - plugin.onBeforeRun(this); - } - } - } - - if (this.graphical) { - if (this.pipeline) { - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (!this.outputTexture || this.immutable) { - this._setupOutputTexture(); - } - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return new this.TextureConstructor({ - texture: this.outputTexture, - size: texSize, - dimensions: this.threadDim, - output: this.output, - context: this.context - }); - } - gl.bindRenderbuffer(gl.RENDERBUFFER, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - return; - } - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); - if (this.immutable) { - this._setupOutputTexture(); - } - - if (this.subKernels !== null) { - if (this.immutable) { - this._setupSubOutputTextures(); - } - gl.drawBuffers(this.drawBuffersMap); - } - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - } - - drawBuffers() { - this.context.drawBuffers(this.drawBuffersMap); - } - - getOutputTexture() { - return this.outputTexture; - } - - _setupOutputTexture() { - const { texSize } = this; - const gl = this.context; - const texture = this.outputTexture = gl.createTexture(); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - if (this.precision === 'single') { - if (this.pipeline) { - switch (this.returnType) { - case 'Number': - case 'Float': - case 'Integer': - if (this.optimizeFloatMemory) { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); - } - break; - case 'Array(2)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); - break; - case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable - case 'Array(4)': - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - break; - default: - throw new Error('Unhandled return type'); - } - } else { - gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); - } - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); - } - - _setupSubOutputTextures() { - const { texSize } = this; - const gl = this.context; - this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; - this.subKernelOutputTextures = []; - for (let i = 0; i < this.subKernels.length; i++) { - const texture = this.context.createTexture(); - this.subKernelOutputTextures.push(texture); - this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); - gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - // TODO: upgrade this - if (this.precision === 'single') { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); - } else { - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); - } - } - - /** - * - * @desc Get the header string for the program. - * This returns an empty string if no sub-kernels are defined. - * - * @returns {String} result - */ - _getHeaderString() { - return ''; - } - - /** - * @desc Get texture coordinate string for the program - * @returns {String} result - */ - _getTextureCoordinate() { - const subKernels = this.subKernels; - if (subKernels === null || subKernels.length < 1) { - switch (this.tactic) { - case 'speed': - return 'in lowp vec2 vTexCoord;\n'; - case 'performance': - return 'in highp vec2 vTexCoord;\n'; - case 'balanced': - default: - return 'in mediump vec2 vTexCoord;\n'; - } - } else { - switch (this.tactic) { - case 'speed': - return 'out lowp vec2 vTexCoord;\n'; - case 'performance': - return 'out highp vec2 vTexCoord;\n'; - case 'balanced': - default: - return 'out mediump vec2 vTexCoord;\n'; - } - } - } - - /** - * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel - * @param {Array} args - The actual parameters sent to the Kernel - * @returns {String} result - */ - _getMainArgumentsString(args) { - const result = []; - const argumentNames = this.argumentNames; - for (let i = 0; i < argumentNames.length; i++) { - result.push(this.kernelArguments[i].getSource(args[i])); - } - return result.join(''); - } - - /** - * @desc Get Kernel program string (in *glsl*) for a kernel. - * @returns {String} result - */ - getKernelString() { - let kernelResultDeclaration; - switch (this.returnType) { - case 'Array(2)': - kernelResultDeclaration = 'vec2 kernelResult'; - break; - case 'Array(3)': - kernelResultDeclaration = 'vec3 kernelResult'; - break; - case 'Array(4)': - kernelResultDeclaration = 'vec4 kernelResult'; - break; - case 'LiteralInteger': - case 'Float': - case 'Number': - case 'Integer': - kernelResultDeclaration = 'float kernelResult'; - break; - default: - if (this.graphical) { - kernelResultDeclaration = 'float kernelResult'; - } else { - throw new Error(`unrecognized output type "${ this.returnType }"`); - } - } - - const result = []; - const subKernels = this.subKernels; - if (subKernels !== null) { - result.push( - kernelResultDeclaration, - 'layout(location = 0) out vec4 data0' - ); - for (let i = 0; i < subKernels.length; i++) { - const subKernel = subKernels[i]; - result.push( - subKernel.returnType === 'Integer' ? - `int subKernelResult_${ subKernel.name } = 0` : - `float subKernelResult_${ subKernel.name } = 0.0`, - `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }` - ); - } - } else { - result.push( - 'out vec4 data0', - kernelResultDeclaration - ); - } - - return utils.linesToString(result) + this.translatedSource; - } - - getMainResultGraphical() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0 = actualColor', - ]); - } - - getMainResultPackedPixels() { - switch (this.returnType) { - case 'LiteralInteger': - case 'Number': - case 'Integer': - case 'Float': - return this.getMainResultKernelPackedPixels() + - this.getMainResultSubKernelPackedPixels(); - default: - throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); - } - } - - /** - * @return {String} - */ - getMainResultKernelPackedPixels() { - return utils.linesToString([ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` - ]); - } - - /** - * @return {String} - */ - getMainResultSubKernelPackedPixels() { - const result = []; - if (!this.subKernels) return ''; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` - ); - } else { - result.push( - ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` - ); - } - } - return utils.linesToString(result); - } - - getMainResultMemoryOptimizedFloats() { - const result = [ - ' index *= 4', - ]; - - switch (this.returnType) { - case 'Number': - case 'Integer': - case 'Float': - const channels = ['r', 'g', 'b', 'a']; - for (let i = 0; i < channels.length; i++) { - const channel = channels[i]; - this.getMainResultKernelMemoryOptimizedFloats(result, channel); - this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); - if (i + 1 < channels.length) { - result.push(' index += 1'); - } - } - break; - default: - throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); - } - - return utils.linesToString(result); - } - - getMainResultKernelMemoryOptimizedFloats(result, channel) { - result.push( - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ` data0.${channel} = kernelResult`, - ); - } - - getMainResultSubKernelMemoryOptimizedFloats(result, channel) { - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; i++) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`, - ); - } else { - result.push( - ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`, - ); - } - } - } - - getMainResultKernelNumberTexture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult', - ]; - } - - getMainResultSubKernelNumberTexture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - if (subKernel.returnType === 'Integer') { - result.push( - ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`, - ); - } else { - result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}`, - ); - } - } - return result; - } - - getMainResultKernelArray2Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult[0]', - ' data0[1] = kernelResult[1]', - ]; - } - - getMainResultSubKernelArray2Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, - ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, - ); - } - return result; - } - - getMainResultKernelArray3Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0[0] = kernelResult[0]', - ' data0[1] = kernelResult[1]', - ' data0[2] = kernelResult[2]', - ]; - } - - getMainResultSubKernelArray3Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - const subKernel = this.subKernels[i]; - result.push( - ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, - ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, - ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`, - ); - } - return result; - } - - getMainResultKernelArray4Texture() { - return [ - ' threadId = indexTo3D(index, uOutputDim)', - ' kernel()', - ' data0 = kernelResult', - ]; - } - - getMainResultSubKernelArray4Texture() { - const result = []; - if (!this.subKernels) return result; - for (let i = 0; i < this.subKernels.length; ++i) { - result.push( - ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`, - ); - } - return result; - } - - destroyExtensions() { - this.extensions.EXT_color_buffer_float = null; - this.extensions.OES_texture_float_linear = null; - } - - toJSON() { - const json = super.toJSON(); - json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON(); - return json; - } -} - -module.exports = { - WebGL2Kernel -}; \ No newline at end of file +import { WebGLKernel } from '../web-gl/kernel'; +import { WebGL2FunctionNode } from './function-node'; +import { FunctionBuilder } from '../function-builder'; +import { utils } from '../../utils'; +import { fragmentShader } from './fragment-shader'; +import { vertexShader } from './vertex-shader'; +import { lookupKernelValueType } from './kernel-value-maps'; + +let isSupported = null; +let testCanvas = null; +let testContext = null; +let testExtensions = null; + +/** + * + * @type {IKernelFeatures} + */ +let features = null; + +/** + * @extends WebGLKernel + */ +export class WebGL2Kernel extends WebGLKernel { + static get isSupported() { + if (isSupported !== null) { + return isSupported; + } + this.setupFeatureChecks(); + isSupported = this.isContextMatch(testContext); + return isSupported; + } + + static setupFeatureChecks() { + if (typeof document !== 'undefined') { + testCanvas = document.createElement('canvas'); + } else if (typeof OffscreenCanvas !== 'undefined') { + testCanvas = new OffscreenCanvas(0, 0); + } + if (!testCanvas) return; + testContext = testCanvas.getContext('webgl2'); + if (!testContext || !testContext.getExtension) return; + testExtensions = { + EXT_color_buffer_float: testContext.getExtension('EXT_color_buffer_float'), + OES_texture_float_linear: testContext.getExtension('OES_texture_float_linear'), + }; + features = this.getFeatures(); + } + + static isContextMatch(context) { + // from global + if (typeof WebGL2RenderingContext !== 'undefined') { + return context instanceof WebGL2RenderingContext; + } + return false; + } + + static getFeatures() { + return Object.freeze({ + isFloatRead: this.getIsFloatRead(), + isIntegerDivisionAccurate: this.getIsIntegerDivisionAccurate(), + kernelMap: true, + isTextureFloat: true, + channelCount: this.getChannelCount(), + maxTextureSize: this.getMaxTextureSize(), + }); + } + + static getIsTextureFloat() { + return true; + } + + static getIsIntegerDivisionAccurate() { + return super.getIsIntegerDivisionAccurate(); + } + + static getChannelCount() { + return testContext.getParameter(testContext.MAX_DRAW_BUFFERS); + } + + static getMaxTextureSize() { + return testContext.getParameter(testContext.MAX_TEXTURE_SIZE); + } + + static lookupKernelValueType(type, dynamic, precision, value) { + return lookupKernelValueType(type, dynamic, precision, value); + } + + static get testCanvas() { + return testCanvas; + } + + static get testContext() { + return testContext; + } + + /** + * + * @returns {{isFloatRead: Boolean, isIntegerDivisionAccurate: Boolean, kernelMap: Boolean, isTextureFloat: Boolean}} + */ + static get features() { + return features; + } + + static get fragmentShader() { + return fragmentShader; + } + static get vertexShader() { + return vertexShader; + } + + initContext() { + const settings = { + alpha: false, + depth: false, + antialias: false + }; + const context = this.canvas.getContext('webgl2', settings); + return context; + } + + initExtensions() { + this.extensions = { + EXT_color_buffer_float: this.context.getExtension('EXT_color_buffer_float'), + OES_texture_float_linear: this.context.getExtension('OES_texture_float_linear'), + }; + } + + /** + * @desc Validate settings related to Kernel, such as dimensions size, and auto output support. + * @param {IArguments} args + */ + validateSettings(args) { + if (!this.validate) { + this.texSize = utils.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + return; + } + + const features = this.constructor.features; + if (this.precision === 'single' && !features.isFloatRead) { + throw new Error('Float texture outputs are not supported'); + } else if (!this.graphical && this.precision === null) { + this.precision = features.isFloatRead ? 'single' : 'unsigned'; + } + + if (this.fixIntegerDivisionAccuracy === null) { + this.fixIntegerDivisionAccuracy = !features.isIntegerDivisionAccurate; + } else if (this.fixIntegerDivisionAccuracy && features.isIntegerDivisionAccurate) { + this.fixIntegerDivisionAccuracy = false; + } + + this.checkOutput(); + + if (!this.output || this.output.length === 0) { + if (args.length !== 1) { + throw new Error('Auto output only supported for kernels with only one input'); + } + + const argType = utils.getVariableType(args[0], this.strictIntegers); + switch (argType) { + case 'Array': + this.output = utils.getDimensions(argType); + break; + case 'NumberTexture': + case 'MemoryOptimizedNumberTexture': + case 'ArrayTexture(1)': + case 'ArrayTexture(2)': + case 'ArrayTexture(3)': + case 'ArrayTexture(4)': + this.output = args[0].output; + break; + default: + throw new Error('Auto output not supported for input type: ' + argType); + } + } + + if (this.graphical) { + if (this.output.length !== 2) { + throw new Error('Output must have 2 dimensions on graphical mode'); + } + + if (this.precision === 'single') { + console.warn('Cannot use graphical mode and single precision at the same time'); + this.precision = 'unsigned'; + } + + this.texSize = utils.clone(this.output); + return; + } else if (!this.graphical && this.precision === null && features.isTextureFloat) { + this.precision = 'single'; + } + + this.texSize = utils.getKernelTextureSize({ + optimizeFloatMemory: this.optimizeFloatMemory, + precision: this.precision, + }, this.output); + + this.checkTextureSize(); + } + + translateSource() { + const functionBuilder = FunctionBuilder.fromKernel(this, WebGL2FunctionNode, { + fixIntegerDivisionAccuracy: this.fixIntegerDivisionAccuracy + }); + this.translatedSource = functionBuilder.getPrototypeString('kernel'); + if (!this.graphical && !this.returnType) { + this.returnType = functionBuilder.getKernelResultType(); + } + + if (this.subKernels && this.subKernels.length > 0) { + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (!subKernel.returnType) { + subKernel.returnType = functionBuilder.getSubKernelResultType(i); + } + } + } + } + + run() { + const { kernelArguments, texSize, forceUploadKernelConstants } = this; + const gl = this.context; + + gl.useProgram(this.program); + gl.scissor(0, 0, texSize[0], texSize[1]); + + if (this.dynamicOutput) { + this.setUniform3iv('uOutputDim', new Int32Array(this.threadDim)); + this.setUniform2iv('uTexSize', texSize); + } + + this.setUniform2f('ratio', texSize[0] / this.maxTexSize[0], texSize[1] / this.maxTexSize[1]); + + this.switchingKernels = false; + for (let i = 0; i < forceUploadKernelConstants.length; i++) { + const constant = forceUploadKernelConstants[i]; + constant.updateValue(this.constants[constant.name]); + if (this.switchingKernels) return; + } + for (let i = 0; i < kernelArguments.length; i++) { + kernelArguments[i].updateValue(arguments[i]); + if (this.switchingKernels) return; + } + + if (this.plugins) { + for (let i = 0; i < this.plugins.length; i++) { + const plugin = this.plugins[i]; + if (plugin.onBeforeRun) { + plugin.onBeforeRun(this); + } + } + } + + if (this.graphical) { + if (this.pipeline) { + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (!this.outputTexture || this.immutable) { + this._setupOutputTexture(); + } + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return new this.TextureConstructor({ + texture: this.outputTexture, + size: texSize, + dimensions: this.threadDim, + output: this.output, + context: this.context + }); + } + gl.bindRenderbuffer(gl.RENDERBUFFER, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + return; + } + + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); + if (this.immutable) { + this._setupOutputTexture(); + } + + if (this.subKernels !== null) { + if (this.immutable) { + this._setupSubOutputTextures(); + } + gl.drawBuffers(this.drawBuffersMap); + } + + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + } + + drawBuffers() { + this.context.drawBuffers(this.drawBuffersMap); + } + + getOutputTexture() { + return this.outputTexture; + } + + _setupOutputTexture() { + const { texSize } = this; + const gl = this.context; + const texture = this.outputTexture = gl.createTexture(); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + if (this.precision === 'single') { + if (this.pipeline) { + switch (this.returnType) { + case 'Number': + case 'Float': + case 'Integer': + if (this.optimizeFloatMemory) { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + } else { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.R32F, texSize[0], texSize[1]); + } + break; + case 'Array(2)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RG32F, texSize[0], texSize[1]); + break; + case 'Array(3)': // there is _no_ 3 channel format which is guaranteed to be color-renderable + case 'Array(4)': + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + break; + default: + throw new Error('Unhandled return type'); + } + } else { + gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, texSize[0], texSize[1]); + } + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); + } + + _setupSubOutputTextures() { + const { texSize } = this; + const gl = this.context; + this.drawBuffersMap = [gl.COLOR_ATTACHMENT0]; + this.subKernelOutputTextures = []; + for (let i = 0; i < this.subKernels.length; i++) { + const texture = this.context.createTexture(); + this.subKernelOutputTextures.push(texture); + this.drawBuffersMap.push(gl.COLOR_ATTACHMENT0 + i + 1); + gl.activeTexture(gl.TEXTURE0 + this.constantTextureCount + this.argumentTextureCount + i); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + // TODO: upgrade this + if (this.precision === 'single') { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, texSize[0], texSize[1], 0, gl.RGBA, gl.FLOAT, null); + } else { + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize[0], texSize[1], 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i + 1, gl.TEXTURE_2D, texture, 0); + } + } + + /** + * + * @desc Get the header string for the program. + * This returns an empty string if no sub-kernels are defined. + * + * @returns {String} result + */ + _getHeaderString() { + return ''; + } + + /** + * @desc Get texture coordinate string for the program + * @returns {String} result + */ + _getTextureCoordinate() { + const subKernels = this.subKernels; + if (subKernels === null || subKernels.length < 1) { + switch (this.tactic) { + case 'speed': + return 'in lowp vec2 vTexCoord;\n'; + case 'performance': + return 'in highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'in mediump vec2 vTexCoord;\n'; + } + } else { + switch (this.tactic) { + case 'speed': + return 'out lowp vec2 vTexCoord;\n'; + case 'performance': + return 'out highp vec2 vTexCoord;\n'; + case 'balanced': + default: + return 'out mediump vec2 vTexCoord;\n'; + } + } + } + + /** + * @desc Generate transpiled glsl Strings for user-defined parameters sent to a kernel + * @param {Array} args - The actual parameters sent to the Kernel + * @returns {String} result + */ + _getMainArgumentsString(args) { + const result = []; + const argumentNames = this.argumentNames; + for (let i = 0; i < argumentNames.length; i++) { + result.push(this.kernelArguments[i].getSource(args[i])); + } + return result.join(''); + } + + /** + * @desc Get Kernel program string (in *glsl*) for a kernel. + * @returns {String} result + */ + getKernelString() { + let kernelResultDeclaration; + switch (this.returnType) { + case 'Array(2)': + kernelResultDeclaration = 'vec2 kernelResult'; + break; + case 'Array(3)': + kernelResultDeclaration = 'vec3 kernelResult'; + break; + case 'Array(4)': + kernelResultDeclaration = 'vec4 kernelResult'; + break; + case 'LiteralInteger': + case 'Float': + case 'Number': + case 'Integer': + kernelResultDeclaration = 'float kernelResult'; + break; + default: + if (this.graphical) { + kernelResultDeclaration = 'float kernelResult'; + } else { + throw new Error(`unrecognized output type "${ this.returnType }"`); + } + } + + const result = []; + const subKernels = this.subKernels; + if (subKernels !== null) { + result.push( + kernelResultDeclaration, + 'layout(location = 0) out vec4 data0' + ); + for (let i = 0; i < subKernels.length; i++) { + const subKernel = subKernels[i]; + result.push( + subKernel.returnType === 'Integer' ? + `int subKernelResult_${ subKernel.name } = 0` : + `float subKernelResult_${ subKernel.name } = 0.0`, + `layout(location = ${ i + 1 }) out vec4 data${ i + 1 }` + ); + } + } else { + result.push( + 'out vec4 data0', + kernelResultDeclaration + ); + } + + return utils.linesToString(result) + this.translatedSource; + } + + getMainResultGraphical() { + return utils.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0 = actualColor', + ]); + } + + getMainResultPackedPixels() { + switch (this.returnType) { + case 'LiteralInteger': + case 'Number': + case 'Integer': + case 'Float': + return this.getMainResultKernelPackedPixels() + + this.getMainResultSubKernelPackedPixels(); + default: + throw new Error(`packed output only usable with Numbers, "${this.returnType}" specified`); + } + } + + /** + * @return {String} + */ + getMainResultKernelPackedPixels() { + return utils.linesToString([ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0 = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(kernelResult)` + ]); + } + + /** + * @return {String} + */ + getMainResultSubKernelPackedPixels() { + const result = []; + if (!this.subKernels) return ''; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(float(subKernelResult_${this.subKernels[i].name}))` + ); + } else { + result.push( + ` data${i + 1} = ${this.useLegacyEncoder ? 'legacyEncode32' : 'encode32'}(subKernelResult_${this.subKernels[i].name})` + ); + } + } + return utils.linesToString(result); + } + + getMainResultMemoryOptimizedFloats() { + const result = [ + ' index *= 4', + ]; + + switch (this.returnType) { + case 'Number': + case 'Integer': + case 'Float': + const channels = ['r', 'g', 'b', 'a']; + for (let i = 0; i < channels.length; i++) { + const channel = channels[i]; + this.getMainResultKernelMemoryOptimizedFloats(result, channel); + this.getMainResultSubKernelMemoryOptimizedFloats(result, channel); + if (i + 1 < channels.length) { + result.push(' index += 1'); + } + } + break; + default: + throw new Error(`optimized output only usable with Numbers, ${this.returnType} specified`); + } + + return utils.linesToString(result); + } + + getMainResultKernelMemoryOptimizedFloats(result, channel) { + result.push( + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ` data0.${channel} = kernelResult`, + ); + } + + getMainResultSubKernelMemoryOptimizedFloats(result, channel) { + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; i++) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1}.${channel} = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` data${i + 1}.${channel} = subKernelResult_${subKernel.name}`, + ); + } + } + } + + getMainResultKernelNumberTexture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult', + ]; + } + + getMainResultSubKernelNumberTexture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + if (subKernel.returnType === 'Integer') { + result.push( + ` data${i + 1}[0] = float(subKernelResult_${subKernel.name})`, + ); + } else { + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}`, + ); + } + } + return result; + } + + getMainResultKernelArray2Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult[0]', + ' data0[1] = kernelResult[1]', + ]; + } + + getMainResultSubKernelArray2Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, + ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, + ); + } + return result; + } + + getMainResultKernelArray3Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0[0] = kernelResult[0]', + ' data0[1] = kernelResult[1]', + ' data0[2] = kernelResult[2]', + ]; + } + + getMainResultSubKernelArray3Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + const subKernel = this.subKernels[i]; + result.push( + ` data${i + 1}[0] = subKernelResult_${subKernel.name}[0]`, + ` data${i + 1}[1] = subKernelResult_${subKernel.name}[1]`, + ` data${i + 1}[2] = subKernelResult_${subKernel.name}[2]`, + ); + } + return result; + } + + getMainResultKernelArray4Texture() { + return [ + ' threadId = indexTo3D(index, uOutputDim)', + ' kernel()', + ' data0 = kernelResult', + ]; + } + + getMainResultSubKernelArray4Texture() { + const result = []; + if (!this.subKernels) return result; + for (let i = 0; i < this.subKernels.length; ++i) { + result.push( + ` data${i + 1} = subKernelResult_${this.subKernels[i].name}`, + ); + } + return result; + } + + destroyExtensions() { + this.extensions.EXT_color_buffer_float = null; + this.extensions.OES_texture_float_linear = null; + } + + toJSON() { + const json = super.toJSON(); + json.functionNodes = FunctionBuilder.fromKernel(this, WebGL2FunctionNode).toJSON(); + return json; + } +} diff --git a/src/backend/web-gl2/vertex-shader.js b/src/backend/web-gl2/vertex-shader.js index e44dc986..5b65a0bb 100644 --- a/src/backend/web-gl2/vertex-shader.js +++ b/src/backend/web-gl2/vertex-shader.js @@ -1,20 +1,16 @@ -// language=GLSL -const vertexShader = `#version 300 es -__FLOAT_TACTIC_DECLARATION__; -__INT_TACTIC_DECLARATION__; -__SAMPLER_2D_TACTIC_DECLARATION__; - -in vec2 aPos; -in vec2 aTexCoord; - -out vec2 vTexCoord; -uniform vec2 ratio; - -void main(void) { - gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); - vTexCoord = aTexCoord; -}`; - -module.exports = { - vertexShader -}; \ No newline at end of file +// language=GLSL +export const vertexShader = `#version 300 es +__FLOAT_TACTIC_DECLARATION__; +__INT_TACTIC_DECLARATION__; +__SAMPLER_2D_TACTIC_DECLARATION__; + +in vec2 aPos; +in vec2 aTexCoord; + +out vec2 vTexCoord; +uniform vec2 ratio; + +void main(void) { + gl_Position = vec4((aPos + vec2(1)) * ratio + vec2(-1), 0, 1); + vTexCoord = aTexCoord; +}`; diff --git a/src/base-gpu.js b/src/base-gpu.js new file mode 100644 index 00000000..be3e0921 --- /dev/null +++ b/src/base-gpu.js @@ -0,0 +1,577 @@ +import { gpuMock } from 'gpu-mock.js'; +import { CPUKernel } from './backend/cpu/kernel'; +import { WebGL2Kernel } from './backend/web-gl2/kernel'; +import { WebGLKernel } from './backend/web-gl/kernel'; +import { kernelRunShortcut } from './kernel-run-shortcut'; +import { + functionToIFunction, + getFunctionNameFromString, + isFunction, + warnDeprecated +} from './common'; +import { getVariableType } from './utils'; + +/** + * @type {Kernel[]} + */ +const kernelOrder = [ WebGL2Kernel, WebGLKernel ]; + +/** + * @type {string[]} + */ +const kernelTypes = [ 'gpu', 'cpu' ]; + +const internalKernels = { + 'webgl2': WebGL2Kernel, + 'webgl': WebGLKernel, +}; + +let validate = true; + +/** + * The GPU.js library class which manages the GPU context for the creating kernels + */ +export class GPU { + static disableValidation() { + validate = false; + } + + static enableValidation() { + validate = true; + } + + static get isGPUSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported); + } + + /** + * + * @returns {boolean} + */ + static get isKernelMapSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); + } + + /** + * @desc TRUE is platform supports OffscreenCanvas + */ + static get isOffscreenCanvasSupported() { + return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined'; + } + + /** + * @desc TRUE if platform supports WebGL + */ + static get isWebGLSupported() { + return WebGLKernel.isSupported; + } + + /** + * @desc TRUE if platform supports WebGL2 + */ + static get isWebGL2Supported() { + return WebGL2Kernel.isSupported; + } + + /** + * @desc TRUE if platform supports HeadlessGL + */ + static get isHeadlessGLSupported() { + return false; + } + + /** + * + * @desc TRUE if platform supports Canvas + */ + static get isCanvasSupported() { + return typeof HTMLCanvasElement !== 'undefined'; + } + + /** + * @desc TRUE if platform supports HTMLImageArray} + */ + static get isGPUHTMLImageArraySupported() { + return WebGL2Kernel.isSupported; + } + + /** + * @desc TRUE if platform supports single precision} + * @returns {boolean} + */ + static get isSinglePrecisionSupported() { + return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); + } + + /** + * Creates an instance of GPU. + * @param {IGPUSettings} [settings] - Settings to set mode, and other properties + */ + constructor(settings) { + settings = settings || {}; + this.canvas = settings.canvas || null; + this.context = settings.context || null; + this.mode = settings.mode; + this.Kernel = null; + this.kernels = []; + this.functions = []; + this.nativeFunctions = []; + this.injectedNative = null; + if (this.mode === 'dev') return; + this.chooseKernel(); + // add functions from settings + if (settings.functions) { + for (let i = 0; i < settings.functions.length; i++) { + this.addFunction(settings.functions[i]); + } + } + + // add native functions from settings + if (settings.nativeFunctions) { + for (const p in settings.nativeFunctions) { + this.addNativeFunction(p, settings.nativeFunctions[p]); + } + } + } + + getValidate() { + return validate; + } + + /** + * Choose kernel type and save on .Kernel property of GPU + */ + chooseKernel() { + if (this.Kernel) return; + + let Kernel = null; + + if (this.context) { + for (let i = 0; i < kernelOrder.length; i++) { + const ExternalKernel = kernelOrder[i]; + if (ExternalKernel.isContextMatch(this.context)) { + if (!ExternalKernel.isSupported) { + throw new Error(`Kernel type ${ExternalKernel.name} not supported`); + } + Kernel = ExternalKernel; + break; + } + } + if (Kernel === null) { + throw new Error('unknown Context'); + } + } else if (this.mode) { + if (this.mode in internalKernels) { + if (!validate || internalKernels[this.mode].isSupported) { + Kernel = internalKernels[this.mode]; + } + } else if (this.mode === 'gpu') { + for (let i = 0; i < kernelOrder.length; i++) { + if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + } + } else if (this.mode === 'cpu') { + Kernel = CPUKernel; + } + if (!Kernel) { + throw new Error(`A requested mode of "${this.mode}" and is not supported`); + } + } else { + for (let i = 0; i < kernelOrder.length; i++) { + if (kernelOrder[i].isSupported) { + Kernel = kernelOrder[i]; + break; + } + } + if (!Kernel) { + Kernel = CPUKernel; + } + } + + if (!this.mode) { + this.mode = Kernel.mode; + } + this.Kernel = Kernel; + } + + /** + * @desc This creates a callable function object to call the kernel function with the argument parameter set + * @param {Function|String|object} source - The calling to perform the conversion + * @param {Object} [settings] - The parameter configuration object + * @return {Kernel} callable function to run + */ + createKernel(source, settings) { + if (typeof source === 'undefined') { + throw new Error('Missing source parameter'); + } + if (typeof source !== 'object' && !isFunction(source) && typeof source !== 'string') { + throw new Error('source parameter not a function'); + } + + if (this.mode === 'dev') { + const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); + this.kernels.push(devKernel); + return devKernel; + } + + source = typeof source === 'function' ? source.toString() : source; + const switchableKernels = {}; + const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {}; + // handle conversion of argumentTypes + if (settings && typeof settings.argumentTypes === 'object') { + settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + } + + function onRequestFallback(args) { + const fallbackKernel = new CPUKernel(source, { + argumentTypes: kernelRun.argumentTypes, + constantTypes: kernelRun.constantTypes, + graphical: kernelRun.graphical, + loopMaxIterations: kernelRun.loopMaxIterations, + constants: kernelRun.constants, + dynamicOutput: kernelRun.dynamicOutput, + dynamicArgument: kernelRun.dynamicArguments, + output: kernelRun.output, + precision: kernelRun.precision, + pipeline: kernelRun.pipeline, + immutable: kernelRun.immutable, + optimizeFloatMemory: kernelRun.optimizeFloatMemory, + fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy, + functions: kernelRun.functions, + nativeFunctions: kernelRun.nativeFunctions, + injectedNative: kernelRun.injectedNative, + subKernels: kernelRun.subKernels, + strictIntegers: kernelRun.strictIntegers, + debug: kernelRun.debug, + warnVarUsage: kernelRun.warnVarUsage, + }); + fallbackKernel.build.apply(fallbackKernel, args); + const result = fallbackKernel.run.apply(fallbackKernel, args); + kernelRun.replaceKernel(fallbackKernel); + return result; + } + + function onRequestSwitchKernel(args, kernel) { + const argumentTypes = new Array(args.length); + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + const type = kernel.argumentTypes[i]; + if (arg.type) { + argumentTypes[i] = arg.type; + } else { + switch (type) { + case 'Number': + case 'Integer': + case 'Float': + case 'ArrayTexture(1)': + argumentTypes[i] = getVariableType(arg); + break; + default: + argumentTypes[i] = type; + } + } + } + const signature = argumentTypes.join(','); + const existingKernel = switchableKernels[signature]; + if (existingKernel) { + existingKernel.run.apply(existingKernel, args); + if (existingKernel.renderKernels) { + return existingKernel.renderKernels(); + } else { + return existingKernel.renderOutput(); + } + } + + const newKernel = switchableKernels[signature] = new kernel.constructor(source, { + argumentTypes, + constantTypes: kernel.constantTypes, + graphical: kernel.graphical, + loopMaxIterations: kernel.loopMaxIterations, + constants: kernel.constants, + dynamicOutput: kernel.dynamicOutput, + dynamicArgument: kernel.dynamicArguments, + context: kernel.context, + canvas: kernel.canvas, + output: kernel.output, + precision: kernel.precision, + pipeline: kernel.pipeline, + immutable: kernel.immutable, + optimizeFloatMemory: kernel.optimizeFloatMemory, + fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy, + functions: kernel.functions, + nativeFunctions: kernel.nativeFunctions, + injectedNative: kernel.injectedNative, + subKernels: kernel.subKernels, + strictIntegers: kernel.strictIntegers, + debug: kernel.debug, + gpu: kernel.gpu, + validate, + warnVarUsage: kernel.warnVarUsage, + returnType: kernel.returnType, + onRequestFallback, + onRequestSwitchKernel, + }); + newKernel.build.apply(newKernel, args); + newKernel.run.apply(newKernel, args); + kernelRun.replaceKernel(newKernel); + if (newKernel.renderKernels) { + return newKernel.renderKernels(); + } else { + return newKernel.renderOutput(); + } + } + const mergedSettings = Object.assign({ + context: this.context, + canvas: this.canvas, + functions: this.functions, + nativeFunctions: this.nativeFunctions, + injectedNative: this.injectedNative, + gpu: this, + validate, + onRequestFallback, + onRequestSwitchKernel + }, settingsCopy); + + const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); + + //if canvas didn't come from this, propagate from kernel + if (!this.canvas) { + this.canvas = kernelRun.canvas; + } + + //if context didn't come from this, propagate from kernel + if (!this.context) { + this.context = kernelRun.context; + } + + this.kernels.push(kernelRun); + + return kernelRun; + } + + /** + * + * Create a super kernel which executes sub kernels + * and saves their output to be used with the next sub kernel. + * This can be useful if we want to save the output on one kernel, + * and then use it as an input to another kernel. *Machine Learning* + * + * @param {Object|Array} subKernels - Sub kernels for this kernel + * @param {Function} rootKernel - Root kernel + * + * @returns {Function} callable kernel function + * + * @example + * const megaKernel = gpu.createKernelMap({ + * addResult: function add(a, b) { + * return a[this.thread.x] + b[this.thread.x]; + * }, + * multiplyResult: function multiply(a, b) { + * return a[this.thread.x] * b[this.thread.x]; + * }, + * }, function(a, b, c) { + * return multiply(add(a, b), c); + * }); + * + * megaKernel(a, b, c); + * + * Note: You can also define subKernels as an array of functions. + * > [add, multiply] + * + */ + createKernelMap() { + let fn; + let settings; + if (typeof arguments[arguments.length - 2] === 'function') { + fn = arguments[arguments.length - 2]; + settings = arguments[arguments.length - 1]; + } else { + fn = arguments[arguments.length - 1]; + } + + if (this.mode !== 'dev') { + if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { + if (this.mode && kernelTypes.indexOf(this.mode) < 0) { + throw new Error(`kernelMap not supported on ${this.Kernel.name}`); + } + } + } + + const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings); + // handle conversion of argumentTypes + if (settings && typeof settings.argumentTypes === 'object') { + settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); + } + + if (Array.isArray(arguments[0])) { + settingsCopy.subKernels = []; + const functions = arguments[0]; + for (let i = 0; i < functions.length; i++) { + const source = functions[i].toString(); + const name = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name, + source, + property: i, + }); + } + } else { + settingsCopy.subKernels = []; + const functions = arguments[0]; + for (let p in functions) { + if (!functions.hasOwnProperty(p)) continue; + const source = functions[p].toString(); + const name = getFunctionNameFromString(source); + settingsCopy.subKernels.push({ + name: name || p, + source, + property: p, + }); + } + } + const kernel = this.createKernel(fn, settingsCopy); + + return kernel; + } + + /** + * + * Combine different kernels into one super Kernel, + * useful to perform multiple operations inside one + * kernel without the penalty of data transfer between + * cpu and gpu. + * + * The number of kernel functions sent to this method can be variable. + * You can send in one, two, etc. + * + * @param {Function} subKernels - Kernel function(s) to combine. + * @param {Function} rootKernel - Root kernel to combine kernels into + * + * @example + * combineKernels(add, multiply, function(a,b,c){ + * return add(multiply(a,b), c) + * }) + * + * @returns {Function} Callable kernel function + * + */ + combineKernels() { + const firstKernel = arguments[0]; + const combinedKernel = arguments[arguments.length - 1]; + if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel; + const canvas = arguments[0].canvas; + const context = arguments[0].context; + const max = arguments.length - 1; + for (let i = 0; i < max; i++) { + arguments[i] + .setCanvas(canvas) + .setContext(context) + .setPipeline(true); + } + + return function() { + const texture = combinedKernel.apply(this, arguments); + if (texture.toArray) { + return texture.toArray(); + } + return texture; + }; + } + + /** + * @desc Adds additional functions, that the kernel may call. + * @param {Function|String} source - Javascript function to convert + * @param {IFunctionSettings} [settings] + * @returns {GPU} returns itself + */ + addFunction(source, settings) { + this.functions.push(functionToIFunction(source, settings)); + return this; + } + + /** + * @desc Adds additional native functions, that the kernel may call. + * @param {String} name - native function name, used for reverse lookup + * @param {String} source - the native function implementation, as it would be defined in it's entirety + * @param {object} [settings] + * @returns {GPU} returns itself + */ + addNativeFunction(name, source, settings) { + if (this.kernels.length > 0) { + throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); + } + settings = settings || {}; + const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; + this.nativeFunctions.push({ + name, + source, + settings, + argumentTypes, + argumentNames, + returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), + }); + return this; + } + + /** + * Inject a string just before translated kernel functions + * @param {String} source + * @return {GPU} + */ + injectNative(source) { + this.injectedNative = source; + return this; + } + + /** + * @desc Destroys all memory associated with gpu.js & the webGl if we created it + */ + destroy() { + if (!this.kernels) return; + // perform on next run loop - for some reason we dont get lose context events + // if webGl is created and destroyed in the same run loop. + setTimeout(() => { + for (let i = 0; i < this.kernels.length; i++) { + this.kernels[i].destroy(true); // remove canvas if exists + } + // all kernels are associated with one context, go ahead and take care of it here + let firstKernel = this.kernels[0]; + if (firstKernel) { + // if it is shortcut + if (firstKernel.kernel) { + firstKernel = firstKernel.kernel; + } + if (firstKernel.constructor.destroyContext) { + firstKernel.constructor.destroyContext(this.context); + } + } + }, 0); + } +} + +function upgradeDeprecatedCreateKernelSettings(settings) { + if (!settings) { + return {}; + } + const upgradedSettings = Object.assign({}, settings); + + if (settings.hasOwnProperty('floatOutput')) { + warnDeprecated('setting', 'floatOutput', 'precision'); + upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; + } + if (settings.hasOwnProperty('outputToTexture')) { + warnDeprecated('setting', 'outputToTexture', 'pipeline'); + upgradedSettings.pipeline = Boolean(settings.outputToTexture); + } + if (settings.hasOwnProperty('outputImmutable')) { + warnDeprecated('setting', 'outputImmutable', 'immutable'); + upgradedSettings.immutable = Boolean(settings.outputImmutable); + } + if (settings.hasOwnProperty('floatTextures')) { + warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); + upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); + } + return upgradedSettings; +} diff --git a/src/browser-header.txt b/src/browser-header.txt deleted file mode 100644 index ef9d7f8a..00000000 --- a/src/browser-header.txt +++ /dev/null @@ -1,14 +0,0 @@ -/** - * <%= pkg.name %> - * <%= pkg.homepage %> - * - * <%= pkg.description %> - * - * @version <%= pkg.version %> - * @date <%= new Date() %> - * - * @license <%= pkg.license %> - * The MIT License - * - * Copyright (c) <%= new Date().getFullYear() %> gpu.js Team - */ \ No newline at end of file diff --git a/src/browser.js b/src/browser.js index ffea4a6f..9178f497 100644 --- a/src/browser.js +++ b/src/browser.js @@ -1,8 +1,70 @@ -const lib = require('./index'); -const GPU = lib.GPU; -for (const p in lib) { - if (!lib.hasOwnProperty(p)) continue; - if (p === 'GPU') continue; //prevent recursive reference - GPU[p] = lib[p]; -} -module.exports = GPU; \ No newline at end of file +import { GPU } from './base-gpu'; +import { alias } from './alias'; +import { utils } from './utils'; +import * as common from './common'; +import { Input, input } from './input'; +import { Texture } from './texture'; +import { FunctionBuilder } from './backend/function-builder'; +import { FunctionNode } from './backend/function-node'; +import { CPUFunctionNode } from './backend/cpu/function-node'; +import { CPUKernel } from './backend/cpu/kernel'; +import { WebGLFunctionNode } from './backend/web-gl/function-node'; +import { WebGLKernel } from './backend/web-gl/kernel'; +import { WebGL2FunctionNode } from './backend/web-gl2/function-node'; +import { WebGL2Kernel } from './backend/web-gl2/kernel'; +import { GLKernel } from './backend/gl/kernel'; +import { Kernel } from './backend/kernel'; + +/** + * Stub for HeadlessGL. + */ +class HeadlessGLKernel extends WebGLKernel { + static get isSupported() { return false } + static isContextMatch() { return false } + static getIsTextureFloat() { return false } + static getIsDrawBuffers() { return false } + static getChannelCount() { return 1 } + static get testCanvas() { return null } + static get testContext() { return null } + static get features() { return null } + static setupFeatureChecks() {} + static destroyContext() {} + initCanvas() { return {} } + initContext() { return null } + toString() { return '' } + initExtensions() {} + build() {} + destroyExtensions() {} + setOutput() {} + + static getFeatures() { + return Object.freeze({ + isFloatRead: false, + isIntegerDivisionAccurate: false, + isTextureFloat: false, + isDrawBuffers: false, + kernelMap: false, + channelCount: 1, + }); + } +}; + +const lib = GPU; +lib.alias = alias; +lib.CPUFunctionNode = CPUFunctionNode; +lib.CPUKernel = CPUKernel; +lib.FunctionBuilder = FunctionBuilder; +lib.FunctionNode = FunctionNode; +lib.HeadlessGLKernel = HeadlessGLKernel; +lib.Input = Input; +lib.input = input; +lib.Texture = Texture; +lib.utils = { ...common, ...utils }; +lib.WebGL2FunctionNode = WebGL2FunctionNode; +lib.WebGL2Kernel = WebGL2Kernel; +lib.WebGLFunctionNode = WebGLFunctionNode; +lib.WebGLKernel = WebGLKernel; +lib.GLKernel = GLKernel; +lib.Kernel = Kernel; + +export default lib; diff --git a/src/common.js b/src/common.js new file mode 100644 index 00000000..a780f77b --- /dev/null +++ b/src/common.js @@ -0,0 +1,139 @@ +/** + * @fileoverview Branch of utils to prevent circular dependencies. + */ + +const ARGUMENT_NAMES = /([^\s,]+)/g; +const FUNCTION_NAME = /function ([^(]*)/; +const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; + +/** + * @descReturn TRUE, on a JS function + * @param {Function} funcObj - Object to validate if its a function + * @returns {Boolean} TRUE if the object is a JS function + */ +export function isFunction(funcObj) { + return typeof(funcObj) === 'function'; +}; + +/** + * @desc Return the function name from a JS function string + * @param {String} funcStr - String of JS function to validate + * @returns {String} Function name string (if found) + */ +export function getFunctionNameFromString(funcStr) { + return FUNCTION_NAME.exec(funcStr)[1].trim(); +}; + +/** + * + * @param {String|Function} source + * @param {IFunctionSettings} [settings] + * @returns {IFunction} + */ +export function functionToIFunction(source, settings) { + settings = settings || {}; + if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function'); + const sourceString = typeof source === 'string' ? source : source.toString(); + + let argumentTypes = []; + + if (Array.isArray(settings.argumentTypes)) { + argumentTypes = settings.argumentTypes; + } else if (typeof settings.argumentTypes === 'object') { + argumentTypes = getArgumentNamesFromString(sourceString) + .map(name => settings.argumentTypes[name]) || []; + } else { + argumentTypes = settings.argumentTypes || []; + } + + return { + source: sourceString, + argumentTypes, + returnType: settings.returnType || null, + }; +}; + +export function warnDeprecated(type, oldName, newName) { + const msg = newName + ? `It has been replaced with "${ newName }"` + : 'It has been removed'; + console.warn(`You are using a deprecated ${ type } "${ oldName }". ${msg}. Fixing, but please upgrade as it will soon be removed.`) +}; + +/** + * @desc Return TRUE, on a valid JS function string + * Note: This does just a VERY simply sanity check. And may give false positives. + * + * @param {String} fn - String of JS function to validate + * @returns {Boolean} TRUE if the string passes basic validation + */ +export function isFunctionString(fn) { + if (typeof fn === 'string') { + return (fn + .slice(0, 'function'.length) + .toLowerCase() === 'function'); + } + return false; +}; + +/** + * @desc Return list of argument names extracted from a javascript function + * @param {String} fn - String of JS function to validate + * @returns {String[]} Array representing all the parameter names + */ +export function getArgumentNamesFromString(fn) { + const fnStr = fn.replace(STRIP_COMMENTS, ''); + let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); + if (result === null) { + result = []; + } + return result; +}; + +/** + * @desc Checks if is an array or Array-like object + * @param {Object} array - The argument object to check if is array + * @returns {Boolean} true if is array or Array-like object + */ +export function isArray(array) { + return !isNaN(array.length); +}; + +export function erectMemoryOptimized2DFloat(array, width, height) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const offset = y * width; + yResults[y] = array.subarray(offset, offset + width); + } + return yResults; +}; + +export function erectMemoryOptimized3DFloat(array, width, height, depth) { + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const offset = (z * height * width) + (y * width); + yResults[y] = array.subarray(offset, offset + width); + } + zResults[z] = yResults; + } + return zResults; +}; + +export function getAstString(source, ast) { + const lines = Array.isArray(source) ? source : source.split(/\r?\n/g); + const start = ast.loc.start; + const end = ast.loc.end; + const result = []; + if (start.line === end.line) { + result.push(lines[start.line - 1].substring(start.column, end.column)); + } else { + result.push(lines[start.line - 1].slice(start.column)); + for (let i = start.line; i < end.line; i++) { + result.push(lines[i]); + } + result.push(lines[end.line - 1].slice(0, end.column)); + } + return result.join('\n'); +}; diff --git a/src/gpu.js b/src/gpu.js index 12e3b768..24ab8e9a 100644 --- a/src/gpu.js +++ b/src/gpu.js @@ -1,579 +1,81 @@ -const { gpuMock } = require('gpu-mock.js'); -const { utils } = require('./utils'); -const { CPUKernel } = require('./backend/cpu/kernel'); -const { HeadlessGLKernel } = require('./backend/headless-gl/kernel'); -const { WebGL2Kernel } = require('./backend/web-gl2/kernel'); -const { WebGLKernel } = require('./backend/web-gl/kernel'); -const { kernelRunShortcut } = require('./kernel-run-shortcut'); - - -/** - * - * @type {Kernel[]} - */ -const kernelOrder = [HeadlessGLKernel, WebGL2Kernel, WebGLKernel]; - -/** - * - * @type {string[]} - */ -const kernelTypes = ['gpu', 'cpu']; - -const internalKernels = { - 'headlessgl': HeadlessGLKernel, - 'webgl2': WebGL2Kernel, - 'webgl': WebGLKernel, -}; - -let validate = true; - -/** - * The GPU.js library class which manages the GPU context for the creating kernels - */ -class GPU { - static disableValidation() { - validate = false; - } - - static enableValidation() { - validate = true; - } - - static get isGPUSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported); - } - - /** - * - * @returns {boolean} - */ - static get isKernelMapSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.kernelMap); - } - - /** - * @desc TRUE is platform supports OffscreenCanvas - */ - static get isOffscreenCanvasSupported() { - return (typeof Worker !== 'undefined' && typeof OffscreenCanvas !== 'undefined') || typeof importScripts !== 'undefined'; - } - - /** - * @desc TRUE if platform supports WebGL - */ - static get isWebGLSupported() { - return WebGLKernel.isSupported; - } - - /** - * @desc TRUE if platform supports WebGL2 - */ - static get isWebGL2Supported() { - return WebGL2Kernel.isSupported; - } - - /** - * @desc TRUE if platform supports HeadlessGL - */ - static get isHeadlessGLSupported() { - return HeadlessGLKernel.isSupported; - } - - /** - * - * @desc TRUE if platform supports Canvas - */ - static get isCanvasSupported() { - return typeof HTMLCanvasElement !== 'undefined'; - } - - /** - * @desc TRUE if platform supports HTMLImageArray} - */ - static get isGPUHTMLImageArraySupported() { - return WebGL2Kernel.isSupported; - } - - /** - * @desc TRUE if platform supports single precision} - * @returns {boolean} - */ - static get isSinglePrecisionSupported() { - return kernelOrder.some(Kernel => Kernel.isSupported && Kernel.features.isFloatRead && Kernel.features.isTextureFloat); - } - - /** - * Creates an instance of GPU. - * @param {IGPUSettings} [settings] - Settings to set mode, and other properties - */ - constructor(settings) { - settings = settings || {}; - this.canvas = settings.canvas || null; - this.context = settings.context || null; - this.mode = settings.mode; - this.Kernel = null; - this.kernels = []; - this.functions = []; - this.nativeFunctions = []; - this.injectedNative = null; - if (this.mode === 'dev') return; - this.chooseKernel(); - // add functions from settings - if (settings.functions) { - for (let i = 0; i < settings.functions.length; i++) { - this.addFunction(settings.functions[i]); - } - } - - // add native functions from settings - if (settings.nativeFunctions) { - for (const p in settings.nativeFunctions) { - this.addNativeFunction(p, settings.nativeFunctions[p]); - } - } - } - - /** - * Choose kernel type and save on .Kernel property of GPU - */ - chooseKernel() { - if (this.Kernel) return; - - let Kernel = null; - - if (this.context) { - for (let i = 0; i < kernelOrder.length; i++) { - const ExternalKernel = kernelOrder[i]; - if (ExternalKernel.isContextMatch(this.context)) { - if (!ExternalKernel.isSupported) { - throw new Error(`Kernel type ${ExternalKernel.name} not supported`); - } - Kernel = ExternalKernel; - break; - } - } - if (Kernel === null) { - throw new Error('unknown Context'); - } - } else if (this.mode) { - if (this.mode in internalKernels) { - if (!validate || internalKernels[this.mode].isSupported) { - Kernel = internalKernels[this.mode]; - } - } else if (this.mode === 'gpu') { - for (let i = 0; i < kernelOrder.length; i++) { - if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; - } - } - } else if (this.mode === 'cpu') { - Kernel = CPUKernel; - } - if (!Kernel) { - throw new Error(`A requested mode of "${this.mode}" and is not supported`); - } - } else { - for (let i = 0; i < kernelOrder.length; i++) { - if (kernelOrder[i].isSupported) { - Kernel = kernelOrder[i]; - break; - } - } - if (!Kernel) { - Kernel = CPUKernel; - } - } - - if (!this.mode) { - this.mode = Kernel.mode; - } - this.Kernel = Kernel; - } - - /** - * @desc This creates a callable function object to call the kernel function with the argument parameter set - * @param {Function|String|object} source - The calling to perform the conversion - * @param {Object} [settings] - The parameter configuration object - * @return {Kernel} callable function to run - */ - createKernel(source, settings) { - if (typeof source === 'undefined') { - throw new Error('Missing source parameter'); - } - if (typeof source !== 'object' && !utils.isFunction(source) && typeof source !== 'string') { - throw new Error('source parameter not a function'); - } - - if (this.mode === 'dev') { - const devKernel = gpuMock(source, upgradeDeprecatedCreateKernelSettings(settings)); - this.kernels.push(devKernel); - return devKernel; - } - - source = typeof source === 'function' ? source.toString() : source; - const switchableKernels = {}; - const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings) || {}; - // handle conversion of argumentTypes - if (settings && typeof settings.argumentTypes === 'object') { - settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); - } - - function onRequestFallback(args) { - const fallbackKernel = new CPUKernel(source, { - argumentTypes: kernelRun.argumentTypes, - constantTypes: kernelRun.constantTypes, - graphical: kernelRun.graphical, - loopMaxIterations: kernelRun.loopMaxIterations, - constants: kernelRun.constants, - dynamicOutput: kernelRun.dynamicOutput, - dynamicArgument: kernelRun.dynamicArguments, - output: kernelRun.output, - precision: kernelRun.precision, - pipeline: kernelRun.pipeline, - immutable: kernelRun.immutable, - optimizeFloatMemory: kernelRun.optimizeFloatMemory, - fixIntegerDivisionAccuracy: kernelRun.fixIntegerDivisionAccuracy, - functions: kernelRun.functions, - nativeFunctions: kernelRun.nativeFunctions, - injectedNative: kernelRun.injectedNative, - subKernels: kernelRun.subKernels, - strictIntegers: kernelRun.strictIntegers, - debug: kernelRun.debug, - warnVarUsage: kernelRun.warnVarUsage, - }); - fallbackKernel.build.apply(fallbackKernel, args); - const result = fallbackKernel.run.apply(fallbackKernel, args); - kernelRun.replaceKernel(fallbackKernel); - return result; - } - - function onRequestSwitchKernel(args, kernel) { - const argumentTypes = new Array(args.length); - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - const type = kernel.argumentTypes[i]; - if (arg.type) { - argumentTypes[i] = arg.type; - } else { - switch (type) { - case 'Number': - case 'Integer': - case 'Float': - case 'ArrayTexture(1)': - argumentTypes[i] = utils.getVariableType(arg); - break; - default: - argumentTypes[i] = type; - } - } - } - const signature = argumentTypes.join(','); - const existingKernel = switchableKernels[signature]; - if (existingKernel) { - existingKernel.run.apply(existingKernel, args); - if (existingKernel.renderKernels) { - return existingKernel.renderKernels(); - } else { - return existingKernel.renderOutput(); - } - } - - const newKernel = switchableKernels[signature] = new kernel.constructor(source, { - argumentTypes, - constantTypes: kernel.constantTypes, - graphical: kernel.graphical, - loopMaxIterations: kernel.loopMaxIterations, - constants: kernel.constants, - dynamicOutput: kernel.dynamicOutput, - dynamicArgument: kernel.dynamicArguments, - context: kernel.context, - canvas: kernel.canvas, - output: kernel.output, - precision: kernel.precision, - pipeline: kernel.pipeline, - immutable: kernel.immutable, - optimizeFloatMemory: kernel.optimizeFloatMemory, - fixIntegerDivisionAccuracy: kernel.fixIntegerDivisionAccuracy, - functions: kernel.functions, - nativeFunctions: kernel.nativeFunctions, - injectedNative: kernel.injectedNative, - subKernels: kernel.subKernels, - strictIntegers: kernel.strictIntegers, - debug: kernel.debug, - gpu: kernel.gpu, - validate, - warnVarUsage: kernel.warnVarUsage, - returnType: kernel.returnType, - onRequestFallback, - onRequestSwitchKernel, - }); - newKernel.build.apply(newKernel, args); - newKernel.run.apply(newKernel, args); - kernelRun.replaceKernel(newKernel); - if (newKernel.renderKernels) { - return newKernel.renderKernels(); - } else { - return newKernel.renderOutput(); - } - } - const mergedSettings = Object.assign({ - context: this.context, - canvas: this.canvas, - functions: this.functions, - nativeFunctions: this.nativeFunctions, - injectedNative: this.injectedNative, - gpu: this, - validate, - onRequestFallback, - onRequestSwitchKernel - }, settingsCopy); - - const kernelRun = kernelRunShortcut(new this.Kernel(source, mergedSettings)); - - //if canvas didn't come from this, propagate from kernel - if (!this.canvas) { - this.canvas = kernelRun.canvas; - } - - //if context didn't come from this, propagate from kernel - if (!this.context) { - this.context = kernelRun.context; - } - - this.kernels.push(kernelRun); - - return kernelRun; - } - - /** - * - * Create a super kernel which executes sub kernels - * and saves their output to be used with the next sub kernel. - * This can be useful if we want to save the output on one kernel, - * and then use it as an input to another kernel. *Machine Learning* - * - * @param {Object|Array} subKernels - Sub kernels for this kernel - * @param {Function} rootKernel - Root kernel - * - * @returns {Function} callable kernel function - * - * @example - * const megaKernel = gpu.createKernelMap({ - * addResult: function add(a, b) { - * return a[this.thread.x] + b[this.thread.x]; - * }, - * multiplyResult: function multiply(a, b) { - * return a[this.thread.x] * b[this.thread.x]; - * }, - * }, function(a, b, c) { - * return multiply(add(a, b), c); - * }); - * - * megaKernel(a, b, c); - * - * Note: You can also define subKernels as an array of functions. - * > [add, multiply] - * - */ - createKernelMap() { - let fn; - let settings; - if (typeof arguments[arguments.length - 2] === 'function') { - fn = arguments[arguments.length - 2]; - settings = arguments[arguments.length - 1]; - } else { - fn = arguments[arguments.length - 1]; - } - - if (this.mode !== 'dev') { - if (!this.Kernel.isSupported || !this.Kernel.features.kernelMap) { - if (this.mode && kernelTypes.indexOf(this.mode) < 0) { - throw new Error(`kernelMap not supported on ${this.Kernel.name}`); - } - } - } - - const settingsCopy = upgradeDeprecatedCreateKernelSettings(settings); - // handle conversion of argumentTypes - if (settings && typeof settings.argumentTypes === 'object') { - settingsCopy.argumentTypes = Object.keys(settings.argumentTypes).map(argumentName => settings.argumentTypes[argumentName]); - } - - if (Array.isArray(arguments[0])) { - settingsCopy.subKernels = []; - const functions = arguments[0]; - for (let i = 0; i < functions.length; i++) { - const source = functions[i].toString(); - const name = utils.getFunctionNameFromString(source); - settingsCopy.subKernels.push({ - name, - source, - property: i, - }); - } - } else { - settingsCopy.subKernels = []; - const functions = arguments[0]; - for (let p in functions) { - if (!functions.hasOwnProperty(p)) continue; - const source = functions[p].toString(); - const name = utils.getFunctionNameFromString(source); - settingsCopy.subKernels.push({ - name: name || p, - source, - property: p, - }); - } - } - const kernel = this.createKernel(fn, settingsCopy); - - return kernel; - } - - /** - * - * Combine different kernels into one super Kernel, - * useful to perform multiple operations inside one - * kernel without the penalty of data transfer between - * cpu and gpu. - * - * The number of kernel functions sent to this method can be variable. - * You can send in one, two, etc. - * - * @param {Function} subKernels - Kernel function(s) to combine. - * @param {Function} rootKernel - Root kernel to combine kernels into - * - * @example - * combineKernels(add, multiply, function(a,b,c){ - * return add(multiply(a,b), c) - * }) - * - * @returns {Function} Callable kernel function - * - */ - combineKernels() { - const firstKernel = arguments[0]; - const combinedKernel = arguments[arguments.length - 1]; - if (firstKernel.kernel.constructor.mode === 'cpu') return combinedKernel; - const canvas = arguments[0].canvas; - const context = arguments[0].context; - const max = arguments.length - 1; - for (let i = 0; i < max; i++) { - arguments[i] - .setCanvas(canvas) - .setContext(context) - .setPipeline(true); - } - - return function() { - const texture = combinedKernel.apply(this, arguments); - if (texture.toArray) { - return texture.toArray(); - } - return texture; - }; - } - - /** - * @desc Adds additional functions, that the kernel may call. - * @param {Function|String} source - Javascript function to convert - * @param {IFunctionSettings} [settings] - * @returns {GPU} returns itself - */ - addFunction(source, settings) { - this.functions.push(utils.functionToIFunction(source, settings)); - return this; - } - - /** - * @desc Adds additional native functions, that the kernel may call. - * @param {String} name - native function name, used for reverse lookup - * @param {String} source - the native function implementation, as it would be defined in it's entirety - * @param {object} [settings] - * @returns {GPU} returns itself - */ - addNativeFunction(name, source, settings) { - if (this.kernels.length > 0) { - throw new Error('Cannot call "addNativeFunction" after "createKernels" has been called.'); - } - settings = settings || {}; - const { argumentTypes, argumentNames } = this.Kernel.nativeFunctionArguments(source) || {}; - this.nativeFunctions.push({ - name, - source, - settings, - argumentTypes, - argumentNames, - returnType: settings.returnType || this.Kernel.nativeFunctionReturnType(source), - }); - return this; - } - - /** - * Inject a string just before translated kernel functions - * @param {String} source - * @return {GPU} - */ - injectNative(source) { - this.injectedNative = source; - return this; - } - - /** - * @desc Destroys all memory associated with gpu.js & the webGl if we created it - */ - destroy() { - if (!this.kernels) return; - // perform on next run loop - for some reason we dont get lose context events - // if webGl is created and destroyed in the same run loop. - setTimeout(() => { - for (let i = 0; i < this.kernels.length; i++) { - this.kernels[i].destroy(true); // remove canvas if exists - } - // all kernels are associated with one context, go ahead and take care of it here - let firstKernel = this.kernels[0]; - if (firstKernel) { - // if it is shortcut - if (firstKernel.kernel) { - firstKernel = firstKernel.kernel; - } - if (firstKernel.constructor.destroyContext) { - firstKernel.constructor.destroyContext(this.context); - } - } - }, 0); - } -} - - -function upgradeDeprecatedCreateKernelSettings(settings) { - if (!settings) { - return {}; - } - const upgradedSettings = Object.assign({}, settings); - - if (settings.hasOwnProperty('floatOutput')) { - utils.warnDeprecated('setting', 'floatOutput', 'precision'); - upgradedSettings.precision = settings.floatOutput ? 'single' : 'unsigned'; - } - if (settings.hasOwnProperty('outputToTexture')) { - utils.warnDeprecated('setting', 'outputToTexture', 'pipeline'); - upgradedSettings.pipeline = Boolean(settings.outputToTexture); - } - if (settings.hasOwnProperty('outputImmutable')) { - utils.warnDeprecated('setting', 'outputImmutable', 'immutable'); - upgradedSettings.immutable = Boolean(settings.outputImmutable); - } - if (settings.hasOwnProperty('floatTextures')) { - utils.warnDeprecated('setting', 'floatTextures', 'optimizeFloatMemory'); - upgradedSettings.optimizeFloatMemory = Boolean(settings.floatTextures); - } - return upgradedSettings; -} - -module.exports = { - GPU, - kernelOrder, - kernelTypes -}; \ No newline at end of file +import { GPU as BaseGPU } from './base-gpu'; +import { HeadlessGLKernel } from './backend/headless-gl/kernel'; +import { CPUKernel } from './backend/cpu/kernel'; + +/** + * Extends the BaseGPU class to cover HeadlessGL instead of WebGL. + */ +export class GPU extends BaseGPU { + static get isGPUSupported() { + return HeadlessGLKernel.isSupported; + } + + static get isKernelMapSupported() { + return HeadlessGLKernel.isSupported && HeadlessGLKernel.features.kernelMap; + } + + static get isSinglePrecisionSupported() { + return HeadlessGLKernel.isSupported + && HeadlessGLKernel.features.isFloatRead + && HeadlessGLKernel.features.isTextureFloat; + } + + static get isWebGLSupported() { + return false; + } + + static get isWebGL2Supported() { + return false; + } + + static get isHeadlessGLSupported() { + return HeadlessGLKernel.isSupported; + } + + static get isGPUHTMLImageArraySupported() { + return false; + } + + chooseKernel() { + if (this.Kernel) return; + + let Kernel = null; + + if (this.context) { + if (HeadlessGLKernel.isContextMatch(this.context)) { + if (!HeadlessGLKernel.isSupported) { + throw new Error(`Kernel type ${HeadlessGLKernel.name} not supported`); + } + Kernel = HeadlessGLKernel; + } + if (Kernel === null) { + throw new Error('unknown Context'); + } + } else if (this.mode) { + if (this.mode === 'headlessgl') { + if (!this.getValidate() || HeadlessGLKernel.isSupported) { + Kernel = HeadlessGLKernel; + } + } else if (this.mode === 'gpu') { + if (HeadlessGLKernel.isSupported) { + Kernel = HeadlessGLKernel; + } + } else if (this.mode === 'cpu') { + Kernel = CPUKernel; + } + + if (!Kernel) { + throw new Error(`A requested mode of "${this.mode}" and is not supported`); + } + } else { + Kernel = HeadlessGLKernel.isSupported ? HeadlessGLKernel : CPUKernel; + } + + if (!this.mode) { + this.mode = Kernel.mode; + } + this.Kernel = Kernel; + } + + +}; diff --git a/src/index.js b/src/index.js index 95302ea9..9a8bd3c3 100644 --- a/src/index.js +++ b/src/index.js @@ -1,51 +1,45 @@ -const { GPU } = require('./gpu'); -const { alias } = require('./alias'); -const { utils } = require('./utils'); -const { Input, input } = require('./input'); -const { Texture } = require('./texture'); -const { FunctionBuilder } = require('./backend/function-builder'); -const { FunctionNode } = require('./backend/function-node'); -const { CPUFunctionNode } = require('./backend/cpu/function-node'); -const { CPUKernel } = require('./backend/cpu/kernel'); - -const { HeadlessGLKernel } = require('./backend/headless-gl/kernel'); - -const { WebGLFunctionNode } = require('./backend/web-gl/function-node'); -const { WebGLKernel } = require('./backend/web-gl/kernel'); -const { kernelValueMaps: webGLKernelValueMaps } = require('./backend/web-gl/kernel-value-maps'); - -const { WebGL2FunctionNode } = require('./backend/web-gl2/function-node'); -const { WebGL2Kernel } = require('./backend/web-gl2/kernel'); -const { kernelValueMaps: webGL2KernelValueMaps } = require('./backend/web-gl2/kernel-value-maps'); - -const { GLKernel } = require('./backend/gl/kernel'); - -const { Kernel } = require('./backend/kernel'); - -const { FunctionTracer } = require('./backend/function-tracer'); - -module.exports = { - alias, - CPUFunctionNode, - CPUKernel, - GPU, - FunctionBuilder, - FunctionNode, - HeadlessGLKernel, - Input, - input, - Texture, - utils, - - WebGL2FunctionNode, - WebGL2Kernel, - webGL2KernelValueMaps, - - WebGLFunctionNode, - WebGLKernel, - webGLKernelValueMaps, - - GLKernel, - Kernel, - FunctionTracer, -}; \ No newline at end of file +import { GPU } from './gpu'; +import { alias } from './alias'; +import * as common from './common'; +import { utils as util } from './utils'; +import { Input, input } from './input'; +import { Texture } from './texture'; +import { FunctionBuilder } from './backend/function-builder'; +import { FunctionNode } from './backend/function-node'; +import { CPUFunctionNode } from './backend/cpu/function-node'; +import { CPUKernel } from './backend/cpu/kernel'; +import { HeadlessGLKernel } from './backend/headless-gl/kernel'; +import { WebGLFunctionNode } from './backend/web-gl/function-node'; +import { WebGLKernel } from './backend/web-gl/kernel'; +import { WebGL2FunctionNode } from './backend/web-gl2/function-node'; +import { WebGL2Kernel } from './backend/web-gl2/kernel'; +import { GLKernel } from './backend/gl/kernel'; +import { Kernel } from './backend/kernel'; +import { kernelValueMaps as webGLKernelValueMaps } from './backend/web-gl/kernel-value-maps'; +import { kernelValueMaps as webGL2KernelValueMaps } from './backend/web-gl2/kernel-value-maps'; +import { FunctionTracer } from './backend/function-tracer'; + +const utils = { ...common, ...util }; + +export { + alias, + CPUFunctionNode, + CPUKernel, + GPU, + FunctionBuilder, + FunctionNode, + HeadlessGLKernel, + Input, + input, + Texture, + utils, + WebGL2FunctionNode, + WebGL2Kernel, + webGL2KernelValueMaps, + WebGLFunctionNode, + WebGLKernel, + webGLKernelValueMaps, + GLKernel, + Kernel, + FunctionTracer, +}; diff --git a/src/input.js b/src/input.js index 12f0c252..1b959487 100644 --- a/src/input.js +++ b/src/input.js @@ -1,54 +1,50 @@ -class Input { - constructor(value, size) { - this.value = value; - if (Array.isArray(size)) { - this.size = size; - } else { - this.size = new Int32Array(3); - if (size.z) { - this.size = new Int32Array([size.x, size.y, size.z]); - } else if (size.y) { - this.size = new Int32Array([size.x, size.y]); - } else { - this.size = new Int32Array([size.x]); - } - } - - const [w, h, d] = this.size; - if (d) { - if (this.value.length !== (w * h * d)) { - throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`); - } - } else if (h) { - if (this.value.length !== (w * h)) { - throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`); - } - } else { - if (this.value.length !== w) { - throw new Error(`Input size ${this.value.length} does not match ${w}`); - } - } - - } - - toArray() { - const { utils } = require('./utils'); - const [w, h, d] = this.size; - if (d) { - return utils.erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); - } else if (h) { - return utils.erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h); - } else { - return this.value; - } - } -} - -function input(value, size) { - return new Input(value, size); -} - -module.exports = { - Input, - input -}; \ No newline at end of file +import { erectMemoryOptimized2DFloat, erectMemoryOptimized3DFloat } from './common'; + +export class Input { + constructor(value, size) { + this.value = value; + if (Array.isArray(size)) { + this.size = size; + } else { + this.size = new Int32Array(3); + if (size.z) { + this.size = new Int32Array([size.x, size.y, size.z]); + } else if (size.y) { + this.size = new Int32Array([size.x, size.y]); + } else { + this.size = new Int32Array([size.x]); + } + } + + const [w, h, d] = this.size; + if (d) { + if (this.value.length !== (w * h * d)) { + throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} * ${d} = ${(h * w * d)}`); + } + } else if (h) { + if (this.value.length !== (w * h)) { + throw new Error(`Input size ${this.value.length} does not match ${w} * ${h} = ${(h * w)}`); + } + } else { + if (this.value.length !== w) { + throw new Error(`Input size ${this.value.length} does not match ${w}`); + } + } + + } + + toArray() { + const [ w, h, d ] = this.size; + if (d) { + return erectMemoryOptimized3DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h, d); + } else if (h) { + return erectMemoryOptimized2DFloat(this.value.subarray ? this.value : new Float32Array(this.value), w, h); + } else { + return this.value; + } + } +}; + +export function input(value, size) { + return new Input(value, size); +}; diff --git a/src/kernel-run-shortcut.js b/src/kernel-run-shortcut.js index 3739d0c7..88b41077 100644 --- a/src/kernel-run-shortcut.js +++ b/src/kernel-run-shortcut.js @@ -1,95 +1,92 @@ -const { utils } = require('./utils'); - -/** - * Makes kernels easier for mortals (including me) - * @param kernel - * @returns {function()} - */ -function kernelRunShortcut(kernel) { - let run = function() { - kernel.build.apply(kernel, arguments); - if (kernel.renderKernels) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderKernels(); - }; - } else if (kernel.renderOutput) { - run = function() { - kernel.run.apply(kernel, arguments); - if (kernel.switchingKernels) { - kernel.switchingKernels = false; - return kernel.onRequestSwitchKernel(arguments, kernel); - } - return kernel.renderOutput(); - }; - } else { - run = function() { - return kernel.run.apply(kernel, arguments); - }; - } - return run.apply(kernel, arguments); - }; - const shortcut = function() { - return run.apply(kernel, arguments); - }; - /** - * Run kernel in async mode - * @returns {Promise} - */ - shortcut.exec = function() { - return new Promise((accept, reject) => { - try { - accept(run.apply(this, arguments)); - } catch (e) { - reject(e); - } - }); - }; - shortcut.replaceKernel = function(replacementKernel) { - kernel = replacementKernel; - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - }; - - bindKernelToShortcut(kernel, shortcut); - shortcut.kernel = kernel; - return shortcut; -} - -function bindKernelToShortcut(kernel, shortcut) { - const properties = utils.allPropertiesOf(kernel); - for (let i = 0; i < properties.length; i++) { - const property = properties[i]; - if (property[0] === '_' && property[1] === '_') continue; - if (typeof kernel[property] === 'function') { - if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') { - shortcut[property] = function() { - kernel[property].apply(kernel, arguments); - return shortcut; - }; - } else { - if (property === 'toString') { - shortcut.toString = function() { - return kernel.toString.apply(kernel, arguments); - }; - } else { - shortcut[property] = kernel[property].bind(kernel); - } - } - } else { - shortcut.__defineGetter__(property, () => { - return kernel[property]; - }); - shortcut.__defineSetter__(property, (value) => { - kernel[property] = value; - }); - } - } -} -module.exports = { - kernelRunShortcut -}; \ No newline at end of file +import { utils } from './utils'; + +/** + * Makes kernels easier for mortals (including me) + * @param kernel + * @returns {function()} + */ +export function kernelRunShortcut(kernel) { + let run = function() { + kernel.build.apply(kernel, arguments); + if (kernel.renderKernels) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderKernels(); + }; + } else if (kernel.renderOutput) { + run = function() { + kernel.run.apply(kernel, arguments); + if (kernel.switchingKernels) { + kernel.switchingKernels = false; + return kernel.onRequestSwitchKernel(arguments, kernel); + } + return kernel.renderOutput(); + }; + } else { + run = function() { + return kernel.run.apply(kernel, arguments); + }; + } + return run.apply(kernel, arguments); + }; + const shortcut = function() { + return run.apply(kernel, arguments); + }; + /** + * Run kernel in async mode + * @returns {Promise} + */ + shortcut.exec = function() { + return new Promise((accept, reject) => { + try { + accept(run.apply(this, arguments)); + } catch (e) { + reject(e); + } + }); + }; + shortcut.replaceKernel = function(replacementKernel) { + kernel = replacementKernel; + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + }; + + bindKernelToShortcut(kernel, shortcut); + shortcut.kernel = kernel; + return shortcut; +} + +function bindKernelToShortcut(kernel, shortcut) { + const properties = utils.allPropertiesOf(kernel); + for (let i = 0; i < properties.length; i++) { + const property = properties[i]; + if (property[0] === '_' && property[1] === '_') continue; + if (typeof kernel[property] === 'function') { + if (property.substring(0, 3) === 'add' || property.substring(0, 3) === 'set') { + shortcut[property] = function() { + kernel[property].apply(kernel, arguments); + return shortcut; + }; + } else { + if (property === 'toString') { + shortcut.toString = function() { + return kernel.toString.apply(kernel, arguments); + }; + } else { + shortcut[property] = kernel[property].bind(kernel); + } + } + } else { + shortcut.__defineGetter__(property, () => { + return kernel[property]; + }); + shortcut.__defineSetter__(property, (value) => { + kernel[property] = value; + }); + } + } +} diff --git a/src/plugins/triangle-noise.js b/src/plugins/triangle-noise.js index cc2972e2..6d23f5f8 100644 --- a/src/plugins/triangle-noise.js +++ b/src/plugins/triangle-noise.js @@ -1,53 +1,52 @@ -const source = ` - -uniform highp float triangle_noise_seed; -highp float triangle_noise_shift = 0.000001; - -//https://www.shadertoy.com/view/4t2SDh -//note: uniformly distributed, normalized rand, [0;1[ -float nrand( vec2 n ) -{ - return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); -} -//note: remaps v to [0;1] in interval [a;b] -float remap( float a, float b, float v ) -{ - return clamp( (v-a) / (b-a), 0.0, 1.0 ); -} - -float n4rand( vec2 n ) -{ - float t = fract( triangle_noise_seed + triangle_noise_shift ); - float nrnd0 = nrand( n + 0.07*t ); - float nrnd1 = nrand( n + 0.11*t ); - float nrnd2 = nrand( n + 0.13*t ); - float nrnd3 = nrand( n + 0.17*t ); - float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; - triangle_noise_shift = result + 0.000001; - return result; -}`; - -const name = 'triangle-noise-noise'; - -const functionMatch = 'Math.random()'; - -const functionReplace = 'n4rand(vTexCoord)'; - -const functionReturnType = 'Number'; - -const onBeforeRun = (kernel) => { - kernel.setUniform1f('triangle_noise_seed', Math.random()); -}; - -/** - * - * @type IPlugin - */ -module.exports = { - name, - onBeforeRun, - functionMatch, - functionReplace, - functionReturnType, - source -}; \ No newline at end of file +const source = ` + +uniform highp float triangle_noise_seed; +highp float triangle_noise_shift = 0.000001; + +//https://www.shadertoy.com/view/4t2SDh +//note: uniformly distributed, normalized rand, [0;1[ +float nrand( vec2 n ) +{ + return fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453); +} +//note: remaps v to [0;1] in interval [a;b] +float remap( float a, float b, float v ) +{ + return clamp( (v-a) / (b-a), 0.0, 1.0 ); +} + +float n4rand( vec2 n ) +{ + float t = fract( triangle_noise_seed + triangle_noise_shift ); + float nrnd0 = nrand( n + 0.07*t ); + float nrnd1 = nrand( n + 0.11*t ); + float nrnd2 = nrand( n + 0.13*t ); + float nrnd3 = nrand( n + 0.17*t ); + float result = (nrnd0+nrnd1+nrnd2+nrnd3) / 4.0; + triangle_noise_shift = result + 0.000001; + return result; +}`; + +const name = 'triangle-noise-noise'; + +const functionMatch = 'Math.random()'; + +const functionReplace = 'n4rand(vTexCoord)'; + +const functionReturnType = 'Number'; + +const onBeforeRun = (kernel) => { + kernel.setUniform1f('triangle_noise_seed', Math.random()); +}; + +/** + * @type IPlugin + */ +export default { + name, + onBeforeRun, + functionMatch, + functionReplace, + functionReturnType, + source +}; diff --git a/src/texture.js b/src/texture.js index f7a192c9..1d4c99fe 100644 --- a/src/texture.js +++ b/src/texture.js @@ -1,44 +1,40 @@ -/** - * @desc WebGl Texture implementation in JS - * @param {ITextureSettings} settings - */ -class Texture { - constructor(settings) { - const { - texture, - size, - dimensions, - output, - context, - type = 'NumberTexture', - } = settings; - if (!output) throw new Error('settings property "output" required.'); - if (!context) throw new Error('settings property "context" required.'); - this.texture = texture; - this.size = size; - this.dimensions = dimensions; - this.output = output; - this.context = context; - this.kernel = null; - this.type = type; - } - - /** - * @desc Converts the Texture into a JavaScript Array - * @returns {Number[]|Number[][]|Number[][][]} - */ - toArray() { - throw new Error(`Not implemented on ${this.constructor.name}`); - } - - /** - * @desc Deletes the Texture - */ - delete() { - return this.context.deleteTexture(this.texture); - } -} - -module.exports = { - Texture -}; \ No newline at end of file +/** + * @desc WebGl Texture implementation in JS + * @param {ITextureSettings} settings + */ +export class Texture { + constructor(settings) { + const { + texture, + size, + dimensions, + output, + context, + type = 'NumberTexture', + } = settings; + if (!output) throw new Error('settings property "output" required.'); + if (!context) throw new Error('settings property "context" required.'); + this.texture = texture; + this.size = size; + this.dimensions = dimensions; + this.output = output; + this.context = context; + this.kernel = null; + this.type = type; + } + + /** + * @desc Converts the Texture into a JavaScript Array + * @returns {Number[]|Number[][]|Number[][][]} + */ + toArray() { + throw new Error(`Not implemented on ${this.constructor.name}`); + } + + /** + * @desc Deletes the Texture + */ + delete() { + return this.context.deleteTexture(this.texture); + } +}; diff --git a/src/utils.js b/src/utils.js index d840c333..b2beaec9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,899 +1,691 @@ -const acorn = require('acorn'); -const { Input } = require('./input'); -const { Texture } = require('./texture'); - -const FUNCTION_NAME = /function ([^(]*)/; -const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; -const ARGUMENT_NAMES = /([^\s,]+)/g; - -/** - * - * @desc Various utility functions / snippets of code that GPU.JS uses internally. - * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere) - */ -const utils = { - /** - * - * @desc Gets the system endianness, and cache it - * @returns {String} 'LE' or 'BE' depending on system architecture - * Credit: https://gist.github.com/TooTallNate/4750953 - */ - systemEndianness() { - return _systemEndianness; - }, - getSystemEndianness() { - const b = new ArrayBuffer(4); - const a = new Uint32Array(b); - const c = new Uint8Array(b); - a[0] = 0xdeadbeef; - if (c[0] === 0xef) return 'LE'; - if (c[0] === 0xde) return 'BE'; - throw new Error('unknown endianness'); - }, - - /** - * @descReturn TRUE, on a JS function - * @param {Function} funcObj - Object to validate if its a function - * @returns {Boolean} TRUE if the object is a JS function - */ - isFunction(funcObj) { - return typeof(funcObj) === 'function'; - }, - - /** - * @desc Return TRUE, on a valid JS function string - * Note: This does just a VERY simply sanity check. And may give false positives. - * - * @param {String} fn - String of JS function to validate - * @returns {Boolean} TRUE if the string passes basic validation - */ - isFunctionString(fn) { - if (typeof fn === 'string') { - return (fn - .slice(0, 'function'.length) - .toLowerCase() === 'function'); - } - return false; - }, - - /** - * @desc Return the function name from a JS function string - * @param {String} funcStr - String of JS function to validate - * @returns {String} Function name string (if found) - */ - getFunctionNameFromString(funcStr) { - return FUNCTION_NAME.exec(funcStr)[1].trim(); - }, - - getFunctionBodyFromString(funcStr) { - return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); - }, - - /** - * @desc Return list of argument names extracted from a javascript function - * @param {String} fn - String of JS function to validate - * @returns {String[]} Array representing all the parameter names - */ - getArgumentNamesFromString(fn) { - const fnStr = fn.replace(STRIP_COMMENTS, ''); - let result = fnStr.slice(fnStr.indexOf('(') + 1, fnStr.indexOf(')')).match(ARGUMENT_NAMES); - if (result === null) { - result = []; - } - return result; - }, - - /** - * @desc Returns a clone - * @param {Object} obj - Object to clone - * @returns {Object|Array} Cloned object - */ - clone(obj) { - if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj; - - const temp = obj.constructor(); // changed - - for (let key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - obj.isActiveClone = null; - temp[key] = utils.clone(obj[key]); - delete obj.isActiveClone; - } - } - - return temp; - }, - - /** - * @desc Checks if is an array or Array-like object - * @param {Object} array - The argument object to check if is array - * @returns {Boolean} true if is array or Array-like object - */ - isArray(array) { - return !isNaN(array.length); - }, - - /** - * @desc Evaluate the argument type, to apply respective logic for it - * @param {Object} value - The argument object to evaluate type - * @returns {String} Argument type Array/Number/Float/Texture/Unknown - */ - getVariableType(value, strictIntegers) { - if (utils.isArray(value)) { - if (value.length > 0 && value[0].nodeName === 'IMG') { - return 'HTMLImageArray'; - } - return 'Array'; - } - - switch (value.constructor) { - case Boolean: - return 'Boolean'; - case Number: - if (strictIntegers && Number.isInteger(value)) { - return 'Integer'; - } - return 'Float'; - case Texture: - return value.type; - case Input: - return 'Input'; - } - switch (value.nodeName) { - case 'IMG': - return 'HTMLImage'; - case 'VIDEO': - return 'HTMLVideo'; - } - if (value.hasOwnProperty('type')) { - return value.type; - } - return 'Unknown'; - }, - - getKernelTextureSize(settings, dimensions) { - let [w, h, d] = dimensions; - let texelCount = (w || 1) * (h || 1) * (d || 1); - - if (settings.optimizeFloatMemory && settings.precision === 'single') { - w = texelCount = Math.ceil(texelCount / 4); - } - // if given dimensions == a 2d image - if (h > 1 && w * h === texelCount) { - return new Int32Array([w, h]); - } - return utils.closestSquareDimensions(texelCount); - }, - - /** - * - * @param {Number} length - * @returns {TextureDimensions} - */ - closestSquareDimensions(length) { - const sqrt = Math.sqrt(length); - let high = Math.ceil(sqrt); - let low = Math.floor(sqrt); - while (high * low < length) { - high--; - low = Math.ceil(length / high); - } - return new Int32Array([low, Math.ceil(length / low)]); - }, - - /** - * A texture takes up four - * @param {OutputDimensions} dimensions - * @param {Number} bitRatio - * @returns {TextureDimensions} - */ - getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) { - const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4); - const texelCount = totalArea / bitRatio; - return utils.closestSquareDimensions(texelCount); - }, - - /** - * - * @param dimensions - * @param bitRatio - * @returns {*|TextureDimensions} - */ - getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) { - const [w, h, d] = dimensions; - const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4); - const texelCount = totalArea / (4 / bitRatio); - return utils.closestSquareDimensions(texelCount); - }, - - roundTo(n, d) { - return Math.floor((n + d - 1) / d) * d; - }, - /** - * @desc Return the dimension of an array. - * @param {Array|String|Texture|Input} x - The array - * @param {Boolean} [pad] - To include padding in the dimension calculation - * @returns {OutputDimensions} - */ - getDimensions(x, pad) { - let ret; - if (utils.isArray(x)) { - const dim = []; - let temp = x; - while (utils.isArray(temp)) { - dim.push(temp.length); - temp = temp[0]; - } - ret = dim.reverse(); - } else if (x instanceof Texture) { - ret = x.output; - } else if (x instanceof Input) { - ret = x.size; - } else { - throw new Error(`Unknown dimensions of ${x}`); - } - - if (pad) { - ret = Array.from(ret); - while (ret.length < 3) { - ret.push(1); - } - } - - return new Int32Array(ret); - }, - - /** - * Puts a nested 2d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - flatten2dArrayTo(array, target) { - let offset = 0; - for (let y = 0; y < array.length; y++) { - target.set(array[y], offset); - offset += array[y].length; - } - }, - - /** - * Puts a nested 3d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - flatten3dArrayTo(array, target) { - let offset = 0; - for (let z = 0; z < array.length; z++) { - for (let y = 0; y < array[z].length; y++) { - target.set(array[z][y], offset); - offset += array[z][y].length; - } - } - }, - - /** - * Puts a nested 4d array into a one-dimensional target array - * @param {Array|*} array - * @param {Float32Array|Float64Array} target - */ - flatten4dArrayTo(array, target) { - let offset = 0; - for (let l = 0; l < array.length; l++) { - for (let z = 0; z < array[l].length; z++) { - for (let y = 0; y < array[l][z].length; y++) { - target.set(array[l][z][y], offset); - offset += array[l][z][y].length; - } - } - } - }, - - /** - * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array - * @param {Float32Array|Uint16Array|Uint8Array} array - * @param {Float32Array} target - */ - flattenTo(array, target) { - if (utils.isArray(array[0])) { - if (utils.isArray(array[0][0])) { - if (utils.isArray(array[0][0][0])) { - utils.flatten4dArrayTo(array, target); - } else { - utils.flatten3dArrayTo(array, target); - } - } else { - utils.flatten2dArrayTo(array, target); - } - } else { - target.set(array); - } - }, - - /** - * - * @desc Splits an array into smaller arrays. - * Number of elements in one small chunk is given by `part` - * - * @param {Number[]} array - The array to split into chunks - * @param {Number} part - elements in one chunk - * - * @returns {Number[]} An array of smaller chunks - */ - splitArray(array, part) { - const result = []; - for (let i = 0; i < array.length; i += part) { - result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part)); - } - return result; - }, - - getAstString(source, ast) { - const lines = Array.isArray(source) ? source : source.split(/\r?\n/g); - const start = ast.loc.start; - const end = ast.loc.end; - const result = []; - if (start.line === end.line) { - result.push(lines[start.line - 1].substring(start.column, end.column)); - } else { - result.push(lines[start.line - 1].slice(start.column)); - for (let i = start.line; i < end.line; i++) { - result.push(lines[i]); - } - result.push(lines[end.line - 1].slice(0, end.column)); - } - return result.join('\n'); - }, - - allPropertiesOf(obj) { - const props = []; - - do { - props.push.apply(props, Object.getOwnPropertyNames(obj)); - } while (obj = Object.getPrototypeOf(obj)); - - return props; - }, - - /** - * @param {Array} lines - An Array of strings - * @returns {String} Single combined String, separated by *\n* - */ - linesToString(lines) { - if (lines.length > 0) { - return lines.join(';\n') + ';\n'; - } else { - return '\n'; - } - }, - warnDeprecated(type, oldName, newName) { - if (newName) { - console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been replaced with "${ newName }". Fixing, but please upgrade as it will soon be removed.`); - } else { - console.warn(`You are using a deprecated ${ type } "${ oldName }". It has been removed. Fixing, but please upgrade as it will soon be removed.`); - } - }, - /** - * - * @param {String|Function} source - * @param {IFunctionSettings} [settings] - * @returns {IFunction} - */ - functionToIFunction(source, settings) { - settings = settings || {}; - if (typeof source !== 'string' && typeof source !== 'function') throw new Error('source not a string or function'); - const sourceString = typeof source === 'string' ? source : source.toString(); - - let argumentTypes = []; - - if (Array.isArray(settings.argumentTypes)) { - argumentTypes = settings.argumentTypes; - } else if (typeof settings.argumentTypes === 'object') { - argumentTypes = utils.getArgumentNamesFromString(sourceString) - .map(name => settings.argumentTypes[name]) || []; - } else { - argumentTypes = settings.argumentTypes || []; - } - - return { - source: sourceString, - argumentTypes, - returnType: settings.returnType || null, - }; - }, - flipPixels: (pixels, width, height) => { - // https://stackoverflow.com/a/41973289/1324039 - const halfHeight = height / 2 | 0; // the | 0 keeps the result an int - const bytesPerRow = width * 4; - // make a temp buffer to hold one row - const temp = new Uint8ClampedArray(width * 4); - const result = pixels.slice(0); - for (let y = 0; y < halfHeight; ++y) { - const topOffset = y * bytesPerRow; - const bottomOffset = (height - y - 1) * bytesPerRow; - - // make copy of a row on the top half - temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); - - // copy a row from the bottom half to the top - result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); - - // copy the copy of the top half row to the bottom half - result.set(temp, bottomOffset); - } - return result; - }, - erectPackedFloat: (array, width) => { - return array.subarray(0, width); - }, - erect2DPackedFloat: (array, width, height) => { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xStart = y * width; - const xEnd = xStart + width; - yResults[y] = array.subarray(xStart, xEnd); - } - return yResults; - }, - erect3DPackedFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xStart = (z * height * width) + y * width; - const xEnd = xStart + width; - yResults[y] = array.subarray(xStart, xEnd); - } - zResults[z] = yResults; - } - return zResults; - }, - erectMemoryOptimizedFloat: (array, width) => { - return array.subarray(0, width); - }, - erectMemoryOptimized2DFloat: (array, width, height) => { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const offset = y * width; - yResults[y] = array.subarray(offset, offset + width); - } - return yResults; - }, - erectMemoryOptimized3DFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const offset = (z * height * width) + (y * width); - yResults[y] = array.subarray(offset, offset + width); - } - zResults[z] = yResults; - } - return zResults; - }, - erectFloat: (array, width) => { - const xResults = new Float32Array(width); - let i = 0; - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; - } - return xResults; - }, - erect2DFloat: (array, width, height) => { - const yResults = new Array(height); - let i = 0; - for (let y = 0; y < height; y++) { - const xResults = new Float32Array(width); - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; - } - yResults[y] = xResults; - } - return yResults; - }, - erect3DFloat: (array, width, height, depth) => { - const zResults = new Array(depth); - let i = 0; - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Float32Array(width); - for (let x = 0; x < width; x++) { - xResults[x] = array[i]; - i += 4; - } - yResults[y] = xResults; - } - zResults[z] = yResults; - } - return zResults; - }, - erectArray2: (array, width) => { - const xResults = new Array(width); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 2); - } - return xResults; - }, - erect2DArray2: (array, width, height) => { - const yResults = new Array(height); - const XResultsMax = width * 4; - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * XResultsMax; - let i = 0; - for (let x = 0; x < XResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 2); - } - yResults[y] = xResults; - } - return yResults; - }, - erect3DArray2: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 2); - } - yResults[y] = xResults; - } - zResults[z] = yResults; - } - return zResults; - }, - erectArray3: (array, width) => { - const xResults = new Array(width); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 3); - } - return xResults; - }, - erect2DArray3: (array, width, height) => { - const xResultsMax = width * 4; - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * xResultsMax; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 3); - } - yResults[y] = xResults; - } - return yResults; - }, - erect3DArray3: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 3); - } - yResults[y] = xResults; - } - zResults[z] = yResults; - } - return zResults; - }, - erectArray4: (array, width) => { - const xResults = new Array(array); - const xResultsMax = width * 4; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x, x + 4); - } - return xResults; - }, - erect2DArray4: (array, width, height) => { - const xResultsMax = width * 4; - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = y * xResultsMax; - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 4); - } - yResults[y] = xResults; - } - return yResults; - }, - erect3DArray4: (array, width, height, depth) => { - const xResultsMax = width * 4; - const zResults = new Array(depth); - for (let z = 0; z < depth; z++) { - const yResults = new Array(height); - for (let y = 0; y < height; y++) { - const xResults = new Array(width); - const offset = (z * xResultsMax * height) + (y * xResultsMax); - let i = 0; - for (let x = 0; x < xResultsMax; x += 4) { - xResults[i++] = array.subarray(x + offset, x + offset + 4); - } - yResults[y] = xResults; - } - zResults[z] = yResults; - } - return zResults; - }, - - /** - * - * @param {String} source - * @param {Object} settings - * @return {String} - */ - flattenFunctionToString: (source, settings) => { - const { findDependency, thisLookup, doNotDefine } = settings; - let flattened = settings.flattened; - if (!flattened) { - flattened = settings.flattened = {}; - } - const ast = acorn.parse(source); - const functionDependencies = []; - - function flatten(ast) { - if (Array.isArray(ast)) { - const results = []; - for (let i = 0; i < ast.length; i++) { - results.push(flatten(ast[i])); - } - return results.join(''); - } - switch (ast.type) { - case 'Program': - return flatten(ast.body); - case 'FunctionDeclaration': - return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; - case 'BlockStatement': { - const result = []; - for (let i = 0; i < ast.body.length; i++) { - result.push(flatten(ast.body[i]), ';\n'); - } - return `{\n${result.join('')}}`; - } - case 'VariableDeclaration': - switch (ast.declarations[0].id.type) { - case 'ObjectPattern': { - const source = flatten(ast.declarations[0].init); - const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; - if (/this/.test(source)) { - const result = []; - const lookups = properties.map(thisLookup); - for (let i = 0; i < lookups.length; i++) { - const lookup = lookups[i]; - if (lookup === null) continue; - const property = properties[i]; - result.push(`${ast.kind} ${ property } = ${ lookup };\n`); - } - - return result.join(''); - } - return `${ast.kind} { ${properties} } = ${source}`; - } - case 'ArrayPattern': - return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; - } - if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { - return ''; - } - return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`; - case 'CallExpression': { - if (ast.callee.property.name === 'subarray') { - return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } - if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') { - return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } - if (ast.callee.object.type === 'ThisExpression') { - functionDependencies.push(findDependency('this', ast.callee.property.name)); - return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } else if (ast.callee.object.name) { - const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name); - if (foundSource === null) { - // we're not flattening it - return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } else { - functionDependencies.push(foundSource); - // we're flattening it - return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } - } else if (ast.callee.object.type === 'MemberExpression') { - return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - } else { - throw new Error('unknown ast.callee'); - } - } - case 'ReturnStatement': - return `return ${flatten(ast.argument)}`; - case 'BinaryExpression': - return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`; - case 'UnaryExpression': - if (ast.prefix) { - return `${ast.operator} ${flatten(ast.argument)}`; - } else { - return `${flatten(ast.argument)} ${ast.operator}`; - } - case 'ExpressionStatement': - return `(${flatten(ast.expression)})`; - case 'ArrowFunctionExpression': - return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`; - case 'Literal': - return ast.raw; - case 'Identifier': - return ast.name; - case 'MemberExpression': - if (ast.object.type === 'ThisExpression') { - return thisLookup(ast.property.name); - } - if (ast.computed) { - return `${flatten(ast.object)}[${flatten(ast.property)}]`; - } - return flatten(ast.object) + '.' + flatten(ast.property); - case 'ThisExpression': - return 'this'; - case 'NewExpression': - return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; - case 'ForStatement': - return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`; - case 'AssignmentExpression': - return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`; - case 'UpdateExpression': - return `${flatten(ast.argument)}${ast.operator}`; - case 'IfStatement': - return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`; - case 'ThrowStatement': - return `throw ${flatten(ast.argument)}`; - case 'ObjectPattern': - return ast.properties.map(flatten).join(', '); - case 'ArrayPattern': - return ast.elements.map(flatten).join(', '); - case 'DebuggerStatement': - return 'debugger;'; - case 'ConditionalExpression': - return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`; - case 'Property': - if (ast.kind === 'init') { - return flatten(ast.key); - } - } - throw new Error(`unhandled ast.type of ${ ast.type }`); - } - const result = flatten(ast); - if (functionDependencies.length > 0) { - const flattenedFunctionDependencies = []; - for (let i = 0; i < functionDependencies.length; i++) { - const functionDependency = functionDependencies[i]; - if (!flattened[functionDependency]) { - flattened[functionDependency] = true; - } - flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\n'); - } - return flattenedFunctionDependencies.join('') + result; - } - return result; - }, - - splitHTMLImageToRGB: (image, mode) => { - const gpu = new GPU({ mode }); - - const rKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.r * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const gKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.g * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const bKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.b * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const aKernel = gpu.createKernel(function(a) { - const pixel = a[this.thread.y][this.thread.x]; - return pixel.a * 255; - }, { - output: [image.width, image.height], - precision: 'unsigned', - argumentTypes: ['HTMLImage'], - }); - const result = [ - rKernel(image), - gKernel(image), - bKernel(image), - aKernel(image), - ]; - result.rKernel = rKernel; - result.gKernel = gKernel; - result.bKernel = bKernel; - result.aKernel = aKernel; - result.gpu = gpu; - return result; - }, - - /** - * A visual debug utility - * @param rgba - * @param width - * @param height - * @param mode - * @return {Object[]} - */ - splitRGBAToCanvases: (rgba, width, height, mode) => { - const { GPU } = require('./gpu.js'); - - const visualGPUR = new GPU({ mode }); - const visualKernelR = visualGPUR.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(pixel.r / 255, 0, 0, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelR(rgba); - - const visualGPUG = new GPU({ mode }); - const visualKernelG = visualGPUG.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(0, pixel.g / 255, 0, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelG(rgba); - - const visualGPUB = new GPU({ mode }); - const visualKernelB = visualGPUB.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(0, 0, pixel.b / 255, 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelB(rgba); - - const visualGPUA = new GPU({ mode }); - const visualKernelA = visualGPUA.createKernel(function(v) { - const pixel = v[this.thread.y][this.thread.x]; - this.color(255, 255, 255, pixel.a / 255); - }, { output: [width, height], graphical: true, argumentTypes: { v: 'Array2D(4)' } }); - visualKernelA(rgba); - - visualGPUR.destroy(); - visualGPUG.destroy(); - visualGPUB.destroy(); - visualGPUA.destroy(); - - return [ - visualKernelR.canvas, - visualKernelG.canvas, - visualKernelB.canvas, - visualKernelA.canvas, - ]; - } -}; - -const _systemEndianness = utils.getSystemEndianness(); - -module.exports = { - utils -}; \ No newline at end of file +import { parse } from 'acorn'; +import { Texture } from './texture'; +import { Input } from './input'; +import { + getAstString, + erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat, + functionToIFunction, + getArgumentNamesFromString, + getFunctionNameFromString, + isArray, + isFunction, + isFunctionString, + warnDeprecated +} from './common'; + +export function getSystemEndianness() { + const b = new ArrayBuffer(4); + const a = new Uint32Array(b); + const c = new Uint8Array(b); + a[0] = 0xdeadbeef; + if (c[0] === 0xef) return 'LE'; + if (c[0] === 0xde) return 'BE'; + throw new Error('unknown endianness'); +}; + +const _systemEndianness = getSystemEndianness(); + +/** + * + * @desc Gets the system endianness, and cache it + * @returns {String} 'LE' or 'BE' depending on system architecture + * Credit: https://gist.github.com/TooTallNate/4750953 + */ +export function systemEndianness() { + return _systemEndianness; +}; + +/** + * @desc Evaluate the argument type, to apply respective logic for it + * @param {Object} value - The argument object to evaluate type + * @returns {String} Argument type Array/Number/Float/Texture/Unknown + */ +export function getVariableType(value, strictIntegers) { + if (isArray(value)) { + if (value[0].nodeName === 'IMG') { + return 'HTMLImageArray'; + } + return 'Array'; + } + + switch (value.constructor) { + case Boolean: + return 'Boolean'; + case Number: + return strictIntegers && Number.isInteger(value) ? 'Integer' : 'Float'; + case Texture: + return value.type; + case Input: + return 'Input'; + } + + switch (value.nodeName) { + case 'IMG': + return 'HTMLImage'; + case 'VIDEO': + return 'HTMLVideo'; + } + + return value.hasOwnProperty('type') ? value.type : 'Unknown'; +}; + +/** + * @desc Various utility functions / snippets of code that GPU.JS uses internally. + * This covers various snippets of code that is not entirely gpu.js specific (ie. may find uses elsewhere) + */ +const utils = { + systemEndianness, + getSystemEndianness, + isFunction, + isFunctionString, + getFunctionNameFromString, + + getFunctionBodyFromString(funcStr) { + return funcStr.substring(funcStr.indexOf('{') + 1, funcStr.lastIndexOf('}')); + }, + + getArgumentNamesFromString, + + /** + * @desc Returns a clone + * @param {Object} obj - Object to clone + * @returns {Object|Array} Cloned object + */ + clone(obj) { + if (obj === null || typeof obj !== 'object' || obj.hasOwnProperty('isActiveClone')) return obj; + + const temp = obj.constructor(); // changed + + for (let key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + obj.isActiveClone = null; + temp[key] = utils.clone(obj[key]); + delete obj.isActiveClone; + } + } + + return temp; + }, + + isArray, + getVariableType, + + getKernelTextureSize(settings, dimensions) { + let [w, h, d] = dimensions; + let texelCount = (w || 1) * (h || 1) * (d || 1); + + if (settings.optimizeFloatMemory && settings.precision === 'single') { + w = texelCount = Math.ceil(texelCount / 4); + } + // if given dimensions == a 2d image + if (h > 1 && w * h === texelCount) { + return new Int32Array([w, h]); + } + return utils.closestSquareDimensions(texelCount); + }, + + /** + * + * @param {Number} length + * @returns {TextureDimensions} + */ + closestSquareDimensions(length) { + const sqrt = Math.sqrt(length); + let high = Math.ceil(sqrt); + let low = Math.floor(sqrt); + while (high * low < length) { + high--; + low = Math.ceil(length / high); + } + return new Int32Array([low, Math.ceil(length / low)]); + }, + + /** + * A texture takes up four + * @param {OutputDimensions} dimensions + * @param {Number} bitRatio + * @returns {TextureDimensions} + */ + getMemoryOptimizedFloatTextureSize(dimensions, bitRatio) { + const totalArea = utils.roundTo((dimensions[0] || 1) * (dimensions[1] || 1) * (dimensions[2] || 1) * (dimensions[3] || 1), 4); + const texelCount = totalArea / bitRatio; + return utils.closestSquareDimensions(texelCount); + }, + + /** + * + * @param dimensions + * @param bitRatio + * @returns {*|TextureDimensions} + */ + getMemoryOptimizedPackedTextureSize(dimensions, bitRatio) { + const [w, h, d] = dimensions; + const totalArea = utils.roundTo((w || 1) * (h || 1) * (d || 1), 4); + const texelCount = totalArea / (4 / bitRatio); + return utils.closestSquareDimensions(texelCount); + }, + + roundTo(n, d) { + return Math.floor((n + d - 1) / d) * d; + }, + /** + * @desc Return the dimension of an array. + * @param {Array|String|Texture|Input} x - The array + * @param {Boolean} [pad] - To include padding in the dimension calculation + * @returns {OutputDimensions} + */ + getDimensions(x, pad) { + let ret; + if (isArray(x)) { + const dim = []; + let temp = x; + while (isArray(temp)) { + dim.push(temp.length); + temp = temp[0]; + } + ret = dim.reverse(); + } else if (x instanceof Texture) { + ret = x.output; + } else if (x instanceof Input) { + ret = x.size; + } else { + throw new Error(`Unknown dimensions of ${x}`); + } + + if (pad) { + ret = Array.from(ret); + while (ret.length < 3) { + ret.push(1); + } + } + + return new Int32Array(ret); + }, + + /** + * Puts a nested 2d array into a one-dimensional target array + * @param {Array|*} array + * @param {Float32Array|Float64Array} target + */ + flatten2dArrayTo(array, target) { + let offset = 0; + for (let y = 0; y < array.length; y++) { + target.set(array[y], offset); + offset += array[y].length; + } + }, + + /** + * Puts a nested 3d array into a one-dimensional target array + * @param {Array|*} array + * @param {Float32Array|Float64Array} target + */ + flatten3dArrayTo(array, target) { + let offset = 0; + for (let z = 0; z < array.length; z++) { + for (let y = 0; y < array[z].length; y++) { + target.set(array[z][y], offset); + offset += array[z][y].length; + } + } + }, + + /** + * Puts a nested 4d array into a one-dimensional target array + * @param {Array|*} array + * @param {Float32Array|Float64Array} target + */ + flatten4dArrayTo(array, target) { + let offset = 0; + for (let l = 0; l < array.length; l++) { + for (let z = 0; z < array[l].length; z++) { + for (let y = 0; y < array[l][z].length; y++) { + target.set(array[l][z][y], offset); + offset += array[l][z][y].length; + } + } + } + }, + + /** + * Puts a nested 1d, 2d, or 3d array into a one-dimensional target array + * @param {Float32Array|Uint16Array|Uint8Array} array + * @param {Float32Array} target + */ + flattenTo(array, target) { + if (isArray(array[0])) { + if (isArray(array[0][0])) { + if (isArray(array[0][0][0])) { + utils.flatten4dArrayTo(array, target); + } else { + utils.flatten3dArrayTo(array, target); + } + } else { + utils.flatten2dArrayTo(array, target); + } + } else { + target.set(array); + } + }, + + /** + * + * @desc Splits an array into smaller arrays. + * Number of elements in one small chunk is given by `part` + * + * @param {Number[]} array - The array to split into chunks + * @param {Number} part - elements in one chunk + * + * @returns {Number[]} An array of smaller chunks + */ + splitArray(array, part) { + const result = []; + for (let i = 0; i < array.length; i += part) { + result.push(new array.constructor(array.buffer, i * 4 + array.byteOffset, part)); + } + return result; + }, + + getAstString, + + allPropertiesOf(obj) { + const props = []; + + do { + props.push.apply(props, Object.getOwnPropertyNames(obj)); + } while (obj = Object.getPrototypeOf(obj)); + + return props; + }, + + /** + * @param {Array} lines - An Array of strings + * @returns {String} Single combined String, separated by *\n* + */ + linesToString(lines) { + if (lines.length > 0) { + return lines.join(';\n') + ';\n'; + } else { + return '\n'; + } + }, + + warnDeprecated, + functionToIFunction, + + flipPixels(pixels, width, height) { + // https://stackoverflow.com/a/41973289/1324039 + const halfHeight = height / 2 | 0; // the | 0 keeps the result an int + const bytesPerRow = width * 4; + // make a temp buffer to hold one row + const temp = new Uint8ClampedArray(width * 4); + const result = pixels.slice(0); + for (let y = 0; y < halfHeight; ++y) { + const topOffset = y * bytesPerRow; + const bottomOffset = (height - y - 1) * bytesPerRow; + + // make copy of a row on the top half + temp.set(result.subarray(topOffset, topOffset + bytesPerRow)); + + // copy a row from the bottom half to the top + result.copyWithin(topOffset, bottomOffset, bottomOffset + bytesPerRow); + + // copy the copy of the top half row to the bottom half + result.set(temp, bottomOffset); + } + return result; + }, + + erectPackedFloat: (array, width) => { + return array.subarray(0, width); + }, + erect2DPackedFloat: (array, width, height) => { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xStart = y * width; + const xEnd = xStart + width; + yResults[y] = array.subarray(xStart, xEnd); + } + return yResults; + }, + erect3DPackedFloat: (array, width, height, depth) => { + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xStart = (z * height * width) + y * width; + const xEnd = xStart + width; + yResults[y] = array.subarray(xStart, xEnd); + } + zResults[z] = yResults; + } + return zResults; + }, + erectMemoryOptimizedFloat: (array, width) => { + return array.subarray(0, width); + }, + erectMemoryOptimized2DFloat, + erectMemoryOptimized3DFloat, + erectFloat: (array, width) => { + const xResults = new Float32Array(width); + let i = 0; + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; + } + return xResults; + }, + erect2DFloat: (array, width, height) => { + const yResults = new Array(height); + let i = 0; + for (let y = 0; y < height; y++) { + const xResults = new Float32Array(width); + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; + } + yResults[y] = xResults; + } + return yResults; + }, + erect3DFloat: (array, width, height, depth) => { + const zResults = new Array(depth); + let i = 0; + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Float32Array(width); + for (let x = 0; x < width; x++) { + xResults[x] = array[i]; + i += 4; + } + yResults[y] = xResults; + } + zResults[z] = yResults; + } + return zResults; + }, + erectArray2: (array, width) => { + const xResults = new Array(width); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 2); + } + return xResults; + }, + erect2DArray2: (array, width, height) => { + const yResults = new Array(height); + const XResultsMax = width * 4; + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * XResultsMax; + let i = 0; + for (let x = 0; x < XResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 2); + } + yResults[y] = xResults; + } + return yResults; + }, + erect3DArray2: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 2); + } + yResults[y] = xResults; + } + zResults[z] = yResults; + } + return zResults; + }, + erectArray3: (array, width) => { + const xResults = new Array(width); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 3); + } + return xResults; + }, + erect2DArray3: (array, width, height) => { + const xResultsMax = width * 4; + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * xResultsMax; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 3); + } + yResults[y] = xResults; + } + return yResults; + }, + erect3DArray3: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 3); + } + yResults[y] = xResults; + } + zResults[z] = yResults; + } + return zResults; + }, + erectArray4: (array, width) => { + const xResults = new Array(array); + const xResultsMax = width * 4; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x, x + 4); + } + return xResults; + }, + erect2DArray4: (array, width, height) => { + const xResultsMax = width * 4; + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = y * xResultsMax; + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 4); + } + yResults[y] = xResults; + } + return yResults; + }, + erect3DArray4: (array, width, height, depth) => { + const xResultsMax = width * 4; + const zResults = new Array(depth); + for (let z = 0; z < depth; z++) { + const yResults = new Array(height); + for (let y = 0; y < height; y++) { + const xResults = new Array(width); + const offset = (z * xResultsMax * height) + (y * xResultsMax); + let i = 0; + for (let x = 0; x < xResultsMax; x += 4) { + xResults[i++] = array.subarray(x + offset, x + offset + 4); + } + yResults[y] = xResults; + } + zResults[z] = yResults; + } + return zResults; + }, + + /** + * @param {String} source + * @param {Object} settings + * @return {String} + */ + flattenFunctionToString: (source, settings) => { + const { findDependency, thisLookup, doNotDefine } = settings; + let flattened = settings.flattened; + if (!flattened) { + flattened = settings.flattened = {}; + } + + const ast = parse(source); + const functionDependencies = []; + + function flatten(ast) { + if (Array.isArray(ast)) { + const results = []; + for (let i = 0; i < ast.length; i++) { + results.push(flatten(ast[i])); + } + return results.join(''); + } + switch (ast.type) { + case 'Program': + return flatten(ast.body); + case 'FunctionDeclaration': + return `function ${ast.id.name}(${ast.params.map(flatten).join(', ')}) ${ flatten(ast.body) }`; + case 'BlockStatement': { + const result = []; + for (let i = 0; i < ast.body.length; i++) { + result.push(flatten(ast.body[i]), ';\n'); + } + return `{\n${result.join('')}}`; + } + case 'VariableDeclaration': + switch (ast.declarations[0].id.type) { + case 'ObjectPattern': { + const source = flatten(ast.declarations[0].init); + const properties = ast.declarations.map(declaration => declaration.id.properties.map(flatten))[0]; + if (/this/.test(source)) { + const result = []; + const lookups = properties.map(thisLookup); + for (let i = 0; i < lookups.length; i++) { + const lookup = lookups[i]; + if (lookup === null) continue; + const property = properties[i]; + result.push(`${ast.kind} ${ property } = ${ lookup };\n`); + } + + return result.join(''); + } + return `${ast.kind} { ${properties} } = ${source}`; + } + case 'ArrayPattern': + return `${ast.kind} [ ${ ast.declarations.map(declaration => flatten(declaration.id)).join(', ') } ] = ${flatten(ast.declarations[0].init)}`; + } + if (doNotDefine && doNotDefine.indexOf(ast.declarations[0].id.name) !== -1) { + return ''; + } + return `${ast.kind} ${ast.declarations[0].id.name} = ${flatten(ast.declarations[0].init)}`; + case 'CallExpression': { + if (ast.callee.property.name === 'subarray') { + return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + if (ast.callee.object.name === 'gl' || ast.callee.object.name === 'context') { + return `${flatten(ast.callee.object)}.${flatten(ast.callee.property)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + if (ast.callee.object.type === 'ThisExpression') { + functionDependencies.push(findDependency('this', ast.callee.property.name)); + return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else if (ast.callee.object.name) { + const foundSource = findDependency(ast.callee.object.name, ast.callee.property.name); + if (foundSource === null) { + // we're not flattening it + return `${ast.callee.object.name}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else { + functionDependencies.push(foundSource); + // we're flattening it + return `${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } + } else if (ast.callee.object.type === 'MemberExpression') { + return `${flatten(ast.callee.object)}.${ast.callee.property.name}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + } else { + throw new Error('unknown ast.callee'); + } + } + case 'ReturnStatement': + return `return ${flatten(ast.argument)}`; + case 'BinaryExpression': + return `(${flatten(ast.left)}${ast.operator}${flatten(ast.right)})`; + case 'UnaryExpression': + if (ast.prefix) { + return `${ast.operator} ${flatten(ast.argument)}`; + } else { + return `${flatten(ast.argument)} ${ast.operator}`; + } + case 'ExpressionStatement': + return `(${flatten(ast.expression)})`; + case 'ArrowFunctionExpression': + return `(${ast.params.map(flatten).join(', ')}) => ${flatten(ast.body)}`; + case 'Literal': + return ast.raw; + case 'Identifier': + return ast.name; + case 'MemberExpression': + if (ast.object.type === 'ThisExpression') { + return thisLookup(ast.property.name); + } + if (ast.computed) { + return `${flatten(ast.object)}[${flatten(ast.property)}]`; + } + return flatten(ast.object) + '.' + flatten(ast.property); + case 'ThisExpression': + return 'this'; + case 'NewExpression': + return `new ${flatten(ast.callee)}(${ast.arguments.map(value => flatten(value)).join(', ')})`; + case 'ForStatement': + return `for (${flatten(ast.init)};${flatten(ast.test)};${flatten(ast.update)}) ${flatten(ast.body)}`; + case 'AssignmentExpression': + return `${flatten(ast.left)}${ast.operator}${flatten(ast.right)}`; + case 'UpdateExpression': + return `${flatten(ast.argument)}${ast.operator}`; + case 'IfStatement': + return `if (${flatten(ast.test)}) ${flatten(ast.consequent)}`; + case 'ThrowStatement': + return `throw ${flatten(ast.argument)}`; + case 'ObjectPattern': + return ast.properties.map(flatten).join(', '); + case 'ArrayPattern': + return ast.elements.map(flatten).join(', '); + case 'DebuggerStatement': + return 'debugger;'; + case 'ConditionalExpression': + return `${flatten(ast.test)}?${flatten(ast.consequent)}:${flatten(ast.alternate)}`; + case 'Property': + if (ast.kind === 'init') { + return flatten(ast.key); + } + } + throw new Error(`unhandled ast.type of ${ ast.type }`); + } + const result = flatten(ast); + if (functionDependencies.length > 0) { + const flattenedFunctionDependencies = []; + for (let i = 0; i < functionDependencies.length; i++) { + const functionDependency = functionDependencies[i]; + if (!flattened[functionDependency]) { + flattened[functionDependency] = true; + } + flattenedFunctionDependencies.push(utils.flattenFunctionToString(functionDependency, settings) + ';\n'); + } + return flattenedFunctionDependencies.join('') + result; + } + return result; + }, +}; + +export { utils }; diff --git a/test/.DS_Store b/test/.DS_Store deleted file mode 100644 index 0183cffe..00000000 Binary files a/test/.DS_Store and /dev/null differ diff --git a/test/all-template.html b/test/all-template.html index 3bf6bca0..6759e87a 100644 --- a/test/all-template.html +++ b/test/all-template.html @@ -1,39 +1,34 @@ - - - - - GPU.JS : Test All - - - - - - - -
-
- - - -{{test-files}} - - + + + + + GPU.JS : Test All + + + + + + + +
+
+ + + +{{test-files}} + + diff --git a/test/all.html b/test/all.html index 1ecf5da3..c93b16e2 100644 --- a/test/all.html +++ b/test/all.html @@ -1,39 +1,34 @@ - - - - - GPU.JS : Test All - - - - - - - -
-
- - - + + + + + GPU.JS : Test All + + + + + + + +
+
+ + + @@ -293,6 +288,6 @@ - - - + + + diff --git a/test/benchmark-faster.js b/test/benchmark-faster.js index a41e505c..d05001fb 100644 --- a/test/benchmark-faster.js +++ b/test/benchmark-faster.js @@ -1,4 +1,4 @@ -const { GPU } = require('../src/index.js'); +const { GPU } = require('../dist/gpu.js'); const Benchmark = require('benchmark'); const suite = new Benchmark.Suite; diff --git a/test/benchmark.js b/test/benchmark.js index 86e72d14..31827969 100644 --- a/test/benchmark.js +++ b/test/benchmark.js @@ -1,4 +1,4 @@ -const { GPU } = require('../src/index.js'); +const { GPU } = require('../dist/gpu.js'); const Benchmark = require('benchmark'); const suite = new Benchmark.Suite(); diff --git a/test/features/add-custom-function.js b/test/features/add-custom-function.js index 2cc16840..946dba26 100644 --- a/test/features/add-custom-function.js +++ b/test/features/add-custom-function.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: add custom function'); diff --git a/test/features/add-custom-native-function.js b/test/features/add-custom-native-function.js index 13e0ae23..79d65d00 100644 --- a/test/features/add-custom-native-function.js +++ b/test/features/add-custom-native-function.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: add native'); diff --git a/test/features/add-typed-functions.js b/test/features/add-typed-functions.js index 72ec14ec..139b33d8 100644 --- a/test/features/add-typed-functions.js +++ b/test/features/add-typed-functions.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: add typed functions vec2Test'); function vec2Test(mode) { diff --git a/test/features/argument-array-types.js b/test/features/argument-array-types.js index 93a1102d..7f48158a 100644 --- a/test/features/argument-array-types.js +++ b/test/features/argument-array-types.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('argument array types'); diff --git a/test/features/argument-array1d-types.js b/test/features/argument-array1d-types.js index ce409417..2b15a809 100644 --- a/test/features/argument-array1d-types.js +++ b/test/features/argument-array1d-types.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('argument array 1 types'); diff --git a/test/features/argument-array2d-types.js b/test/features/argument-array2d-types.js index 44e7e79b..8181c786 100644 --- a/test/features/argument-array2d-types.js +++ b/test/features/argument-array2d-types.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('argument array 2 types'); diff --git a/test/features/argument-array3d-types.js b/test/features/argument-array3d-types.js index 68e1fe3a..6ba3c4b3 100644 --- a/test/features/argument-array3d-types.js +++ b/test/features/argument-array3d-types.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('argument array 3 types'); diff --git a/test/features/arithmetic-operators.js b/test/features/arithmetic-operators.js index 83e2d726..5ed59d4c 100644 --- a/test/features/arithmetic-operators.js +++ b/test/features/arithmetic-operators.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: arithmetic operators'); diff --git a/test/features/assignment-operators.js b/test/features/assignment-operators.js index e18bada0..bbce6b95 100644 --- a/test/features/assignment-operators.js +++ b/test/features/assignment-operators.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: assignment operators'); diff --git a/test/features/basic-math.js b/test/features/basic-math.js index 828aec5d..e5444fc1 100644 --- a/test/features/basic-math.js +++ b/test/features/basic-math.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: basic math'); diff --git a/test/features/bitwise-operators.js b/test/features/bitwise-operators.js index 3d0ac614..170424b8 100644 --- a/test/features/bitwise-operators.js +++ b/test/features/bitwise-operators.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('feature: bitwise operators'); diff --git a/test/features/combine-kernels.js b/test/features/combine-kernels.js index 3db77f89..2f8116d1 100644 --- a/test/features/combine-kernels.js +++ b/test/features/combine-kernels.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: combine kernels'); function combineKernels(mode) { diff --git a/test/features/constants-array.js b/test/features/constants-array.js index 910d8086..10090903 100644 --- a/test/features/constants-array.js +++ b/test/features/constants-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants array'); diff --git a/test/features/constants-bool.js b/test/features/constants-bool.js index 4d9c0bed..dba9f1a0 100644 --- a/test/features/constants-bool.js +++ b/test/features/constants-bool.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants bool'); diff --git a/test/features/constants-float.js b/test/features/constants-float.js index 16bf7c1c..1d53f681 100644 --- a/test/features/constants-float.js +++ b/test/features/constants-float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants float'); function floatConstantTest(mode) { diff --git a/test/features/constants-image-array.js b/test/features/constants-image-array.js index f286916b..4bab3040 100644 --- a/test/features/constants-image-array.js +++ b/test/features/constants-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, WebGLKernel } = require('../../src'); +const { GPU, WebGLKernel } = require('../../dist/gpu.js'); describe('features: constants image array'); function feature(mode, done) { diff --git a/test/features/constants-image.js b/test/features/constants-image.js index ae70389c..f191eef0 100644 --- a/test/features/constants-image.js +++ b/test/features/constants-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants image'); function imageConstantTest(mode, done) { diff --git a/test/features/constants-integer.js b/test/features/constants-integer.js index b3f20005..e3a2b7ab 100644 --- a/test/features/constants-integer.js +++ b/test/features/constants-integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants integer'); diff --git a/test/features/constants-texture.js b/test/features/constants-texture.js index 83881603..e351dfc8 100644 --- a/test/features/constants-texture.js +++ b/test/features/constants-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: constants texture 1d'); function test1D(mode) { diff --git a/test/features/cpu-with-textures.js b/test/features/cpu-with-textures.js index b5d80233..70b832c2 100644 --- a/test/features/cpu-with-textures.js +++ b/test/features/cpu-with-textures.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: CPU with Textures'); diff --git a/test/features/create-kernel-map.js b/test/features/create-kernel-map.js index 47c3d5af..26a97050 100644 --- a/test/features/create-kernel-map.js +++ b/test/features/create-kernel-map.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, alias } = require('../../src'); +const { GPU, alias } = require('../../dist/gpu.js'); describe('features: create kernel map'); function createPropertyKernels(gpu, output) { diff --git a/test/features/demo.js b/test/features/demo.js index c31af05c..75b6d0b2 100644 --- a/test/features/demo.js +++ b/test/features/demo.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: demo'); diff --git a/test/features/destroy.js b/test/features/destroy.js index b88b7507..e6f24d30 100644 --- a/test/features/destroy.js +++ b/test/features/destroy.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); const sinon = require('sinon'); describe('features: destroy'); diff --git a/test/features/dev-mode.js b/test/features/dev-mode.js index 4e2a9ae0..3976c510 100644 --- a/test/features/dev-mode.js +++ b/test/features/dev-mode.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../src'); +const { GPU, input } = require('../../dist/gpu.js'); describe('features: dev mode'); diff --git a/test/features/dynamic-arguments.js b/test/features/dynamic-arguments.js index efbe031c..5194c58e 100644 --- a/test/features/dynamic-arguments.js +++ b/test/features/dynamic-arguments.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../src'); +const { GPU, input } = require('../../dist/gpu.js'); describe('features: dynamic arguments'); diff --git a/test/features/dynamic-output.js b/test/features/dynamic-output.js index 955c46c6..c74d4525 100644 --- a/test/features/dynamic-output.js +++ b/test/features/dynamic-output.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: dynamic output'); diff --git a/test/features/function-return.js b/test/features/function-return.js index c82bb415..8a654254 100644 --- a/test/features/function-return.js +++ b/test/features/function-return.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: function return'); diff --git a/test/features/get-canvas.js b/test/features/get-canvas.js index ef247ad1..98f07729 100644 --- a/test/features/get-canvas.js +++ b/test/features/get-canvas.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('get canvas'); diff --git a/test/features/get-pixels.js b/test/features/get-pixels.js index 4e15491a..f463635b 100644 --- a/test/features/get-pixels.js +++ b/test/features/get-pixels.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: getPixels'); diff --git a/test/features/if-else.js b/test/features/if-else.js index 53426729..7dd0f9d9 100644 --- a/test/features/if-else.js +++ b/test/features/if-else.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('if else boolean'); function ifElseBooleanTest(mode) { diff --git a/test/features/image-array.js b/test/features/image-array.js index 023d0ac6..7d90649d 100644 --- a/test/features/image-array.js +++ b/test/features/image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../src'); +const { GPU, CPUKernel } = require('../../dist/gpu.js'); describe('features: image array'); function getImages(callback) { diff --git a/test/features/image.js b/test/features/image.js index 1e7101d9..315c4136 100644 --- a/test/features/image.js +++ b/test/features/image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('image'); function imageArgumentTest(mode, done) { diff --git a/test/features/infinity.js b/test/features/infinity.js index 6f9ba3e4..4a31ba09 100644 --- a/test/features/infinity.js +++ b/test/features/infinity.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('infinity'); function inputWithoutFloat(checks, mode) { diff --git a/test/features/inject-native.js b/test/features/inject-native.js index ed16d9df..3632f3cf 100644 --- a/test/features/inject-native.js +++ b/test/features/inject-native.js @@ -1,82 +1,82 @@ -const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); - -describe('features: inject native'); - -function gpuAddAB(mode) { - const gpu = new GPU({mode}); - gpu - .injectNative(` -int customAdder(int a, int b) { - return a + b; -} -`) - .addNativeFunction('customAdderLink', `int customAdderLink(int a, int b) { - return customAdder(a, b); -}`); - const kernel = gpu.createKernel(function (a, b) { - return customAdderLink(a[this.thread.x], b[this.thread.x]); - }, { - output: [6], - returnType: 'Integer' - }); - - const a = [1, 2, 3, 5, 6, 7]; - const b = [4, 5, 6, 1, 2, 3]; - - const result = kernel(a, b); - - const expected = [5, 7, 9, 6, 8, 10]; - - assert.deepEqual(Array.from(result), expected); - gpu.destroy(); -} - -test('addAB auto', () => { - gpuAddAB(null); -}); - -test('addAB gpu', () => { - gpuAddAB('gpu'); -}); - -(GPU.isWebGLSupported ? test : skip)('addAB webgl', () => { - gpuAddAB('webgl'); -}); - -(GPU.isWebGL2Supported ? test : skip)('addAB webgl2', () => { - gpuAddAB('webgl2'); -}); - -(GPU.isHeadlessGLSupported ? test : skip)('addAB headlessgl', () => { - gpuAddAB('headlessgl'); -}); - -function cpuAddAB(mode) { - function customAdder(a, b) { - return a + b; - } - const gpu = new GPU({mode}); - gpu - .injectNative(customAdder.toString()); - const kernel = gpu.createKernel(function (a, b) { - return customAdder(a[this.thread.x], b[this.thread.x]); - }, { - output: [6], - returnType: 'Integer' - }); - - const a = [1, 2, 3, 5, 6, 7]; - const b = [4, 5, 6, 1, 2, 3]; - - const result = kernel(a, b); - - const expected = [5, 7, 9, 6, 8, 10]; - - assert.deepEqual(Array.from(result), expected); - gpu.destroy(); -} - -test('addAB cpu', () => { - cpuAddAB('cpu'); -}); +const { assert, skip, test, module: describe, only } = require('qunit'); +const { GPU } = require('../../dist/gpu.js'); + +describe('features: inject native'); + +function gpuAddAB(mode) { + const gpu = new GPU({mode}); + gpu + .injectNative(` +int customAdder(int a, int b) { + return a + b; +} +`) + .addNativeFunction('customAdderLink', `int customAdderLink(int a, int b) { + return customAdder(a, b); +}`); + const kernel = gpu.createKernel(function (a, b) { + return customAdderLink(a[this.thread.x], b[this.thread.x]); + }, { + output: [6], + returnType: 'Integer' + }); + + const a = [1, 2, 3, 5, 6, 7]; + const b = [4, 5, 6, 1, 2, 3]; + + const result = kernel(a, b); + + const expected = [5, 7, 9, 6, 8, 10]; + + assert.deepEqual(Array.from(result), expected); + gpu.destroy(); +} + +test('addAB auto', () => { + gpuAddAB(null); +}); + +test('addAB gpu', () => { + gpuAddAB('gpu'); +}); + +(GPU.isWebGLSupported ? test : skip)('addAB webgl', () => { + gpuAddAB('webgl'); +}); + +(GPU.isWebGL2Supported ? test : skip)('addAB webgl2', () => { + gpuAddAB('webgl2'); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('addAB headlessgl', () => { + gpuAddAB('headlessgl'); +}); + +function cpuAddAB(mode) { + function customAdder(a, b) { + return a + b; + } + const gpu = new GPU({mode}); + gpu + .injectNative(customAdder.toString()); + const kernel = gpu.createKernel(function (a, b) { + return customAdder(a[this.thread.x], b[this.thread.x]); + }, { + output: [6], + returnType: 'Integer' + }); + + const a = [1, 2, 3, 5, 6, 7]; + const b = [4, 5, 6, 1, 2, 3]; + + const result = kernel(a, b); + + const expected = [5, 7, 9, 6, 8, 10]; + + assert.deepEqual(Array.from(result), expected); + gpu.destroy(); +} + +test('addAB cpu', () => { + cpuAddAB('cpu'); +}); diff --git a/test/features/input.js b/test/features/input.js index 150557b6..54df97ac 100644 --- a/test/features/input.js +++ b/test/features/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../src'); +const { GPU, input } = require('../../dist/gpu.js'); describe('input'); diff --git a/test/features/json.js b/test/features/json.js index 48bb5d7f..678bd203 100644 --- a/test/features/json.js +++ b/test/features/json.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('json serialize'); diff --git a/test/features/legacy-encoder.js b/test/features/legacy-encoder.js index 8c361264..ebf683e1 100644 --- a/test/features/legacy-encoder.js +++ b/test/features/legacy-encoder.js @@ -1,268 +1,268 @@ -const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, HeadlessGLKernel, WebGLKernel, WebGL2Kernel } = require('../../src'); - -describe('features: legacy encoder'); - -function testLegacyEncoderOff(mode) { - const gpu = new GPU({ mode }); - const kernel = gpu.createKernel(function() { - return 1; - }, { output: [1], precision: 'unsigned' }); - assert.equal(kernel()[0], 1); - gpu.destroy(); -} - -test('off auto', () => { - testLegacyEncoderOff(); -}); - -(GPU.isWebGLSupported ? test : skip)('off webgl', () => { - testLegacyEncoderOff('webgl'); -}); - -(GPU.isWebGL2Supported ? test : skip)('off webgl2', () => { - testLegacyEncoderOff('webgl2'); -}); - -(GPU.isHeadlessGLSupported ? test : skip)('off headlessgl', () => { - testLegacyEncoderOff('headlessgl'); -}); - -test('off cpu', () => { - testLegacyEncoderOff('cpu'); -}); - -function testLegacyEncoderOn(mode) { - const gpu = new GPU({ mode }); - const kernel = gpu.createKernel(function() { - return 1; - }, { - output: [1], - precision: 'unsigned', - useLegacyEncoder: true, - }); - assert.equal(kernel()[0], 1); - gpu.destroy(); -} - -test('on auto', () => { - testLegacyEncoderOn(); -}); - -(GPU.isWebGLSupported ? test : skip)('on webgl', () => { - testLegacyEncoderOn('webgl'); -}); - -(GPU.isWebGL2Supported ? test : skip)('on webgl2', () => { - testLegacyEncoderOn('webgl2'); -}); - -(GPU.isHeadlessGLSupported ? test : skip)('on headlessgl', () => { - testLegacyEncoderOn('headlessgl'); -}); - -test('on cpu', () => { - testLegacyEncoderOn('cpu'); -}); - -function testSubKernelsLegacyEncoderOff(mode) { - const gpu = new GPU({ mode }); - function addOne(value) { - return value + 1; - } - const kernel = gpu.createKernelMap([ - addOne, - ], function() { - const result = addOne(1); - return result + 1; - }, { output: [1], precision: 'unsigned' }); - assert.equal(kernel()[0][0], 2); - assert.equal(kernel().result[0], 3); - gpu.destroy(); -} - -(GPU.isKernelMapSupported ? test : skip)('subKernels off auto', () => { - testSubKernelsLegacyEncoderOff(); -}); - -(GPU.isWebGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels off webgl', () => { - testSubKernelsLegacyEncoderOff('webgl'); -}); - -(GPU.isWebGL2Supported && GPU.isKernelMapSupported ? test : skip)('subKernels off webgl2', () => { - testSubKernelsLegacyEncoderOff('webgl2'); -}); - -(GPU.isHeadlessGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels off headlessgl', () => { - testSubKernelsLegacyEncoderOff('headlessgl'); -}); - -test('subKernels off cpu', () => { - testSubKernelsLegacyEncoderOff('cpu'); -}); - -function testSubKernelsLegacyEncoderOn(mode) { - const gpu = new GPU({ mode }); - function addOne(value) { - return value + 1; - } - const kernel = gpu.createKernelMap([ - addOne, - ], function() { - const value = addOne(1); - return value + 1; - }, { - output: [1], - precision: 'unsigned', - useLegacyEncoder: true, - }); - assert.equal(kernel()[0][0], 2); - assert.equal(kernel().result[0], 3); - gpu.destroy(); -} - -(GPU.isKernelMapSupported ? test : skip)('subKernels on auto', () => { - testSubKernelsLegacyEncoderOn(); -}); - -(GPU.isWebGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels on webgl', () => { - testSubKernelsLegacyEncoderOn('webgl'); -}); - -(GPU.isWebGL2Supported && GPU.isKernelMapSupported ? test : skip)('subKernels on webgl2', () => { - testSubKernelsLegacyEncoderOn('webgl2'); -}); - -(GPU.isHeadlessGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels on headlessgl', () => { - testSubKernelsLegacyEncoderOn('headlessgl'); -}); - -test('subKernels on cpu', () => { - testSubKernelsLegacyEncoderOn('cpu'); -}); - -test('HeadlessGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { - const result = HeadlessGLKernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: false - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - gl_FragData[0] = encode32(kernelResult); -`); -}); - -test('WebGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { - const result = WebGLKernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: false - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - gl_FragData[0] = encode32(kernelResult); -`); -}); - -test('WebGL2Kernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { - const result = WebGL2Kernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: false - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - data0 = encode32(kernelResult); -`); -}); - -test('HeadlessGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { - const result = HeadlessGLKernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: true - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - gl_FragData[0] = legacyEncode32(kernelResult); -`); -}); - -test('WebGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { - const result = WebGLKernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: true - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - gl_FragData[0] = legacyEncode32(kernelResult); -`); -}); - -test('WebGL2Kernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { - const result = WebGL2Kernel.prototype.getMainResultKernelPackedPixels.apply({ - useLegacyEncoder: true - }); - assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); - kernel(); - data0 = legacyEncode32(kernelResult); -`); -}); - -test('HeadlessGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { - const result = HeadlessGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: false, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` gl_FragData[1] = encode32(subKernelResult_subKernel1); -`); -}); - -test('WebGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { - const result = WebGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: false, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` gl_FragData[1] = encode32(subKernelResult_subKernel1); -`); -}); - -test('WebGL2Kernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { - const result = WebGL2Kernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: false, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` data1 = encode32(subKernelResult_subKernel1); -`); -}); - -test('HeadlessGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { - const result = HeadlessGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: true, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` gl_FragData[1] = legacyEncode32(subKernelResult_subKernel1); -`); -}); - -test('WebGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { - const result = WebGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: true, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` gl_FragData[1] = legacyEncode32(subKernelResult_subKernel1); -`); -}); - -test('WebGL2Kernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { - const result = WebGL2Kernel.prototype.getMainResultSubKernelPackedPixels.apply({ - useLegacyEncoder: true, - subKernels: [{ - name: 'subKernel1' - }] - }); - assert.equal(result, ` data1 = legacyEncode32(subKernelResult_subKernel1); -`); -}); +const { assert, skip, test, module: describe, only } = require('qunit'); +const { GPU, HeadlessGLKernel, WebGLKernel, WebGL2Kernel } = require('../../dist/gpu.js'); + +describe('features: legacy encoder'); + +function testLegacyEncoderOff(mode) { + const gpu = new GPU({ mode }); + const kernel = gpu.createKernel(function() { + return 1; + }, { output: [1], precision: 'unsigned' }); + assert.equal(kernel()[0], 1); + gpu.destroy(); +} + +test('off auto', () => { + testLegacyEncoderOff(); +}); + +(GPU.isWebGLSupported ? test : skip)('off webgl', () => { + testLegacyEncoderOff('webgl'); +}); + +(GPU.isWebGL2Supported ? test : skip)('off webgl2', () => { + testLegacyEncoderOff('webgl2'); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('off headlessgl', () => { + testLegacyEncoderOff('headlessgl'); +}); + +test('off cpu', () => { + testLegacyEncoderOff('cpu'); +}); + +function testLegacyEncoderOn(mode) { + const gpu = new GPU({ mode }); + const kernel = gpu.createKernel(function() { + return 1; + }, { + output: [1], + precision: 'unsigned', + useLegacyEncoder: true, + }); + assert.equal(kernel()[0], 1); + gpu.destroy(); +} + +test('on auto', () => { + testLegacyEncoderOn(); +}); + +(GPU.isWebGLSupported ? test : skip)('on webgl', () => { + testLegacyEncoderOn('webgl'); +}); + +(GPU.isWebGL2Supported ? test : skip)('on webgl2', () => { + testLegacyEncoderOn('webgl2'); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('on headlessgl', () => { + testLegacyEncoderOn('headlessgl'); +}); + +test('on cpu', () => { + testLegacyEncoderOn('cpu'); +}); + +function testSubKernelsLegacyEncoderOff(mode) { + const gpu = new GPU({ mode }); + function addOne(value) { + return value + 1; + } + const kernel = gpu.createKernelMap([ + addOne, + ], function() { + const result = addOne(1); + return result + 1; + }, { output: [1], precision: 'unsigned' }); + assert.equal(kernel()[0][0], 2); + assert.equal(kernel().result[0], 3); + gpu.destroy(); +} + +(GPU.isKernelMapSupported ? test : skip)('subKernels off auto', () => { + testSubKernelsLegacyEncoderOff(); +}); + +(GPU.isWebGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels off webgl', () => { + testSubKernelsLegacyEncoderOff('webgl'); +}); + +(GPU.isWebGL2Supported && GPU.isKernelMapSupported ? test : skip)('subKernels off webgl2', () => { + testSubKernelsLegacyEncoderOff('webgl2'); +}); + +(GPU.isHeadlessGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels off headlessgl', () => { + testSubKernelsLegacyEncoderOff('headlessgl'); +}); + +test('subKernels off cpu', () => { + testSubKernelsLegacyEncoderOff('cpu'); +}); + +function testSubKernelsLegacyEncoderOn(mode) { + const gpu = new GPU({ mode }); + function addOne(value) { + return value + 1; + } + const kernel = gpu.createKernelMap([ + addOne, + ], function() { + const value = addOne(1); + return value + 1; + }, { + output: [1], + precision: 'unsigned', + useLegacyEncoder: true, + }); + assert.equal(kernel()[0][0], 2); + assert.equal(kernel().result[0], 3); + gpu.destroy(); +} + +(GPU.isKernelMapSupported ? test : skip)('subKernels on auto', () => { + testSubKernelsLegacyEncoderOn(); +}); + +(GPU.isWebGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels on webgl', () => { + testSubKernelsLegacyEncoderOn('webgl'); +}); + +(GPU.isWebGL2Supported && GPU.isKernelMapSupported ? test : skip)('subKernels on webgl2', () => { + testSubKernelsLegacyEncoderOn('webgl2'); +}); + +(GPU.isHeadlessGLSupported && GPU.isKernelMapSupported ? test : skip)('subKernels on headlessgl', () => { + testSubKernelsLegacyEncoderOn('headlessgl'); +}); + +test('subKernels on cpu', () => { + testSubKernelsLegacyEncoderOn('cpu'); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('HeadlessGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { + const result = HeadlessGLKernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: false + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + gl_FragData[0] = encode32(kernelResult); +`); +}); + +(GPU.isWebGLSupported ? test : skip)('WebGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { + const result = WebGLKernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: false + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + gl_FragData[0] = encode32(kernelResult); +`); +}); + +(GPU.isWebGL2Supported ? test : skip)('WebGL2Kernel.getMainResultKernelPackedPixels useLegacyEncoder = false', () => { + const result = WebGL2Kernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: false + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + data0 = encode32(kernelResult); +`); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('HeadlessGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { + const result = HeadlessGLKernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: true + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + gl_FragData[0] = legacyEncode32(kernelResult); +`); +}); + +(GPU.isWebGLSupported ? test : skip)('WebGLKernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { + const result = WebGLKernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: true + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + gl_FragData[0] = legacyEncode32(kernelResult); +`); +}); + +(GPU.isWebGL2Supported ? test : skip)('WebGL2Kernel.getMainResultKernelPackedPixels useLegacyEncoder = true', () => { + const result = WebGL2Kernel.prototype.getMainResultKernelPackedPixels.apply({ + useLegacyEncoder: true + }); + assert.equal(result, ` threadId = indexTo3D(index, uOutputDim); + kernel(); + data0 = legacyEncode32(kernelResult); +`); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('HeadlessGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { + const result = HeadlessGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: false, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` gl_FragData[1] = encode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isWebGLSupported ? test : skip)('WebGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { + const result = WebGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: false, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` gl_FragData[1] = encode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isWebGL2Supported ? test : skip)('WebGL2Kernel.getMainResultSubKernelPackedPixels useLegacyEncoder = false', () => { + const result = WebGL2Kernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: false, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` data1 = encode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isHeadlessGLSupported ? test : skip)('HeadlessGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { + const result = HeadlessGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: true, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` gl_FragData[1] = legacyEncode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isWebGLSupported ? test : skip)('WebGLKernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { + const result = WebGLKernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: true, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` gl_FragData[1] = legacyEncode32(subKernelResult_subKernel1); +`); +}); + +(GPU.isWebGL2Supported ? test : skip)('WebGL2Kernel.getMainResultSubKernelPackedPixels useLegacyEncoder = true', () => { + const result = WebGL2Kernel.prototype.getMainResultSubKernelPackedPixels.apply({ + useLegacyEncoder: true, + subKernels: [{ + name: 'subKernel1' + }] + }); + assert.equal(result, ` data1 = legacyEncode32(subKernelResult_subKernel1); +`); +}); diff --git a/test/features/loops.js b/test/features/loops.js index 597471a2..866ec145 100644 --- a/test/features/loops.js +++ b/test/features/loops.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('loops - for'); function forLoopTest(mode) { diff --git a/test/features/math-object.js b/test/features/math-object.js index bd80ae46..fe2c37cf 100644 --- a/test/features/math-object.js +++ b/test/features/math-object.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('math object'); diff --git a/test/features/nested-function.js b/test/features/nested-function.js index 52b830c5..b469c617 100644 --- a/test/features/nested-function.js +++ b/test/features/nested-function.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('nested function'); diff --git a/test/features/optimize-float-memory.js b/test/features/optimize-float-memory.js index 7f79a1a9..5b291a1b 100644 --- a/test/features/optimize-float-memory.js +++ b/test/features/optimize-float-memory.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, utils } = require('../../src'); +const { GPU, utils } = require('../../dist/gpu.js'); describe('feature: optimizeFloatMemory'); diff --git a/test/features/output.js b/test/features/output.js index 17d348e0..e58e8e78 100644 --- a/test/features/output.js +++ b/test/features/output.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: output'); diff --git a/test/features/promise-api.js b/test/features/promise-api.js index f77c6e87..9e62f99b 100644 --- a/test/features/promise-api.js +++ b/test/features/promise-api.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: promise api'); diff --git a/test/features/raw-output.js b/test/features/raw-output.js index 0f73e5f9..27d33e95 100644 --- a/test/features/raw-output.js +++ b/test/features/raw-output.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: raw output'); diff --git a/test/features/read-color-texture.js b/test/features/read-color-texture.js index 40453319..607a26a7 100644 --- a/test/features/read-color-texture.js +++ b/test/features/read-color-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: read color texture'); diff --git a/test/features/read-from-texture.js b/test/features/read-from-texture.js index e5e007ae..168d3463 100644 --- a/test/features/read-from-texture.js +++ b/test/features/read-from-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, HeadlessGLKernel } = require('../../src'); +const { GPU, HeadlessGLKernel } = require('../../dist/gpu.js'); describe('features: read from texture'); diff --git a/test/features/return-arrays.js b/test/features/return-arrays.js index a6faa7bc..83e236c1 100644 --- a/test/features/return-arrays.js +++ b/test/features/return-arrays.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: return arrays'); diff --git a/test/features/single-precision-textures.js b/test/features/single-precision-textures.js index 557679d1..564e378a 100644 --- a/test/features/single-precision-textures.js +++ b/test/features/single-precision-textures.js @@ -1,5 +1,5 @@ const { assert, skip, test, only, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: single precision textures'); diff --git a/test/features/single-precision.js b/test/features/single-precision.js index 74c11c1b..4d0b409e 100644 --- a/test/features/single-precision.js +++ b/test/features/single-precision.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: single precision'); function singlePrecisionKernel(mode) { diff --git a/test/features/switches.js b/test/features/switches.js index ec1918f1..62386118 100644 --- a/test/features/switches.js +++ b/test/features/switches.js @@ -1,5 +1,5 @@ const { assert, skip, test, only, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: switches'); diff --git a/test/features/tactic.js b/test/features/tactic.js index 01abb8ce..f1f6378f 100644 --- a/test/features/tactic.js +++ b/test/features/tactic.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: tactic'); diff --git a/test/features/ternary.js b/test/features/ternary.js index b0caeaba..87c3b843 100644 --- a/test/features/ternary.js +++ b/test/features/ternary.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('feature: Ternary'); diff --git a/test/features/to-string/precision/single/arguments/array.js b/test/features/to-string/precision/single/arguments/array.js index d115cfe5..133ce0c5 100644 --- a/test/features/to-string/precision/single/arguments/array.js +++ b/test/features/to-string/precision/single/arguments/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array'); diff --git a/test/features/to-string/precision/single/arguments/array2.js b/test/features/to-string/precision/single/arguments/array2.js index b68236a8..c3c16680 100644 --- a/test/features/to-string/precision/single/arguments/array2.js +++ b/test/features/to-string/precision/single/arguments/array2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array(2)'); diff --git a/test/features/to-string/precision/single/arguments/array2d.js b/test/features/to-string/precision/single/arguments/array2d.js index 7a503e33..362f8fce 100644 --- a/test/features/to-string/precision/single/arguments/array2d.js +++ b/test/features/to-string/precision/single/arguments/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array2D'); diff --git a/test/features/to-string/precision/single/arguments/array2d2.js b/test/features/to-string/precision/single/arguments/array2d2.js index ae1dcc72..0d18ee60 100644 --- a/test/features/to-string/precision/single/arguments/array2d2.js +++ b/test/features/to-string/precision/single/arguments/array2d2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array2D(2)'); diff --git a/test/features/to-string/precision/single/arguments/array2d3.js b/test/features/to-string/precision/single/arguments/array2d3.js index 3d2fb874..249e0ef1 100644 --- a/test/features/to-string/precision/single/arguments/array2d3.js +++ b/test/features/to-string/precision/single/arguments/array2d3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array2D(3)'); diff --git a/test/features/to-string/precision/single/arguments/array3.js b/test/features/to-string/precision/single/arguments/array3.js index cc982e1d..149a3bd3 100644 --- a/test/features/to-string/precision/single/arguments/array3.js +++ b/test/features/to-string/precision/single/arguments/array3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array(3)'); diff --git a/test/features/to-string/precision/single/arguments/array3d.js b/test/features/to-string/precision/single/arguments/array3d.js index 66d2a27b..f63e4a80 100644 --- a/test/features/to-string/precision/single/arguments/array3d.js +++ b/test/features/to-string/precision/single/arguments/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array3D'); diff --git a/test/features/to-string/precision/single/arguments/array4.js b/test/features/to-string/precision/single/arguments/array4.js index 8a3a70df..59561c8f 100644 --- a/test/features/to-string/precision/single/arguments/array4.js +++ b/test/features/to-string/precision/single/arguments/array4.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Array(4)'); diff --git a/test/features/to-string/precision/single/arguments/boolean.js b/test/features/to-string/precision/single/arguments/boolean.js index 3ae322a0..b882da16 100644 --- a/test/features/to-string/precision/single/arguments/boolean.js +++ b/test/features/to-string/precision/single/arguments/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Boolean'); diff --git a/test/features/to-string/precision/single/arguments/float.js b/test/features/to-string/precision/single/arguments/float.js index 3fd99e9f..2ba02ec2 100644 --- a/test/features/to-string/precision/single/arguments/float.js +++ b/test/features/to-string/precision/single/arguments/float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Float'); diff --git a/test/features/to-string/precision/single/arguments/html-image-array.js b/test/features/to-string/precision/single/arguments/html-image-array.js index 2d2a2fe3..881f986a 100644 --- a/test/features/to-string/precision/single/arguments/html-image-array.js +++ b/test/features/to-string/precision/single/arguments/html-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../../../../../src'); +const { GPU, CPUKernel } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments HTMLImageArray'); diff --git a/test/features/to-string/precision/single/arguments/html-image.js b/test/features/to-string/precision/single/arguments/html-image.js index d28f811b..45f9bb04 100644 --- a/test/features/to-string/precision/single/arguments/html-image.js +++ b/test/features/to-string/precision/single/arguments/html-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments HTMLImage'); diff --git a/test/features/to-string/precision/single/arguments/input.js b/test/features/to-string/precision/single/arguments/input.js index 0b87a66a..75b66d55 100644 --- a/test/features/to-string/precision/single/arguments/input.js +++ b/test/features/to-string/precision/single/arguments/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../../../../../src'); +const { GPU, input } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Input'); diff --git a/test/features/to-string/precision/single/arguments/integer.js b/test/features/to-string/precision/single/arguments/integer.js index f787e503..5f775bb4 100644 --- a/test/features/to-string/precision/single/arguments/integer.js +++ b/test/features/to-string/precision/single/arguments/integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments Integer'); diff --git a/test/features/to-string/precision/single/arguments/memory-optimized-number-texture.js b/test/features/to-string/precision/single/arguments/memory-optimized-number-texture.js index b8e59340..9041271e 100644 --- a/test/features/to-string/precision/single/arguments/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/single/arguments/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/single/arguments/number-texture.js b/test/features/to-string/precision/single/arguments/number-texture.js index 36b80b5c..959bf26b 100644 --- a/test/features/to-string/precision/single/arguments/number-texture.js +++ b/test/features/to-string/precision/single/arguments/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision arguments NumberTexture'); diff --git a/test/features/to-string/precision/single/constants/array.js b/test/features/to-string/precision/single/constants/array.js index 876d39ad..cb575568 100644 --- a/test/features/to-string/precision/single/constants/array.js +++ b/test/features/to-string/precision/single/constants/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Array'); diff --git a/test/features/to-string/precision/single/constants/array2.js b/test/features/to-string/precision/single/constants/array2.js index 3e548306..1a7aadd1 100644 --- a/test/features/to-string/precision/single/constants/array2.js +++ b/test/features/to-string/precision/single/constants/array2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Array(2)'); diff --git a/test/features/to-string/precision/single/constants/array2d.js b/test/features/to-string/precision/single/constants/array2d.js index c48af645..ce81856e 100644 --- a/test/features/to-string/precision/single/constants/array2d.js +++ b/test/features/to-string/precision/single/constants/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants 2d Array'); diff --git a/test/features/to-string/precision/single/constants/array3.js b/test/features/to-string/precision/single/constants/array3.js index e1aee848..cfe3a411 100644 --- a/test/features/to-string/precision/single/constants/array3.js +++ b/test/features/to-string/precision/single/constants/array3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Array(3)'); diff --git a/test/features/to-string/precision/single/constants/array3d.js b/test/features/to-string/precision/single/constants/array3d.js index 784ad56d..fe9cfd37 100644 --- a/test/features/to-string/precision/single/constants/array3d.js +++ b/test/features/to-string/precision/single/constants/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants 3d Array'); diff --git a/test/features/to-string/precision/single/constants/array4.js b/test/features/to-string/precision/single/constants/array4.js index 3290d304..2f4c993b 100644 --- a/test/features/to-string/precision/single/constants/array4.js +++ b/test/features/to-string/precision/single/constants/array4.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Array(4)'); diff --git a/test/features/to-string/precision/single/constants/boolean.js b/test/features/to-string/precision/single/constants/boolean.js index a1bb6f5a..ef2aadf3 100644 --- a/test/features/to-string/precision/single/constants/boolean.js +++ b/test/features/to-string/precision/single/constants/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Boolean'); diff --git a/test/features/to-string/precision/single/constants/float.js b/test/features/to-string/precision/single/constants/float.js index 551a24b4..8ac61d3a 100644 --- a/test/features/to-string/precision/single/constants/float.js +++ b/test/features/to-string/precision/single/constants/float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Float'); diff --git a/test/features/to-string/precision/single/constants/html-image-array.js b/test/features/to-string/precision/single/constants/html-image-array.js index a7b0a3a4..8419ade2 100644 --- a/test/features/to-string/precision/single/constants/html-image-array.js +++ b/test/features/to-string/precision/single/constants/html-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../../../../../src'); +const { GPU, CPUKernel } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants HTMLImageArray'); diff --git a/test/features/to-string/precision/single/constants/html-image.js b/test/features/to-string/precision/single/constants/html-image.js index 904d52a7..c9b047db 100644 --- a/test/features/to-string/precision/single/constants/html-image.js +++ b/test/features/to-string/precision/single/constants/html-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants HTMLImage'); diff --git a/test/features/to-string/precision/single/constants/input.js b/test/features/to-string/precision/single/constants/input.js index 7f600bad..3e9666f5 100644 --- a/test/features/to-string/precision/single/constants/input.js +++ b/test/features/to-string/precision/single/constants/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../../../../../src'); +const { GPU, input } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Input'); diff --git a/test/features/to-string/precision/single/constants/integer.js b/test/features/to-string/precision/single/constants/integer.js index aaae2d20..0cd4c1de 100644 --- a/test/features/to-string/precision/single/constants/integer.js +++ b/test/features/to-string/precision/single/constants/integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants Integer'); diff --git a/test/features/to-string/precision/single/constants/memory-optimized-number-texture.js b/test/features/to-string/precision/single/constants/memory-optimized-number-texture.js index 9f996df6..14804828 100644 --- a/test/features/to-string/precision/single/constants/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/single/constants/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/single/constants/number-texture.js b/test/features/to-string/precision/single/constants/number-texture.js index d8829edc..d34ab0f2 100644 --- a/test/features/to-string/precision/single/constants/number-texture.js +++ b/test/features/to-string/precision/single/constants/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision constants NumberTexture'); diff --git a/test/features/to-string/precision/single/graphical.js b/test/features/to-string/precision/single/graphical.js index 3d86eb7f..d9384bb7 100644 --- a/test/features/to-string/precision/single/graphical.js +++ b/test/features/to-string/precision/single/graphical.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../src'); +const { GPU } = require('../../../../../dist/gpu.js'); describe('feature: to-string single precision graphical'); diff --git a/test/features/to-string/precision/single/kernel-map/array/array.js b/test/features/to-string/precision/single/kernel-map/array/array.js index ef7c52f7..0135b946 100644 --- a/test/features/to-string/precision/single/kernel-map/array/array.js +++ b/test/features/to-string/precision/single/kernel-map/array/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns Array'); diff --git a/test/features/to-string/precision/single/kernel-map/array/array2d.js b/test/features/to-string/precision/single/kernel-map/array/array2d.js index 25bf743c..3fa51f4f 100644 --- a/test/features/to-string/precision/single/kernel-map/array/array2d.js +++ b/test/features/to-string/precision/single/kernel-map/array/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns 2D Array'); diff --git a/test/features/to-string/precision/single/kernel-map/array/array3d.js b/test/features/to-string/precision/single/kernel-map/array/array3d.js index 03c5f117..707dda58 100644 --- a/test/features/to-string/precision/single/kernel-map/array/array3d.js +++ b/test/features/to-string/precision/single/kernel-map/array/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns Array3d'); diff --git a/test/features/to-string/precision/single/kernel-map/array/memory-optimized-number-texture.js b/test/features/to-string/precision/single/kernel-map/array/memory-optimized-number-texture.js index e0b61bac..25c7eee3 100644 --- a/test/features/to-string/precision/single/kernel-map/array/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/single/kernel-map/array/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/single/kernel-map/array/number-texture.js b/test/features/to-string/precision/single/kernel-map/array/number-texture.js index 86e8a3e2..2216ea98 100644 --- a/test/features/to-string/precision/single/kernel-map/array/number-texture.js +++ b/test/features/to-string/precision/single/kernel-map/array/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision array style kernel map returns NumberTexture'); diff --git a/test/features/to-string/precision/single/kernel-map/object/array.js b/test/features/to-string/precision/single/kernel-map/object/array.js index 6fb90600..afe2d1aa 100644 --- a/test/features/to-string/precision/single/kernel-map/object/array.js +++ b/test/features/to-string/precision/single/kernel-map/object/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style returns Array'); diff --git a/test/features/to-string/precision/single/kernel-map/object/array2d.js b/test/features/to-string/precision/single/kernel-map/object/array2d.js index 60b22f91..e82acf30 100644 --- a/test/features/to-string/precision/single/kernel-map/object/array2d.js +++ b/test/features/to-string/precision/single/kernel-map/object/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style returns Array2D'); diff --git a/test/features/to-string/precision/single/kernel-map/object/array3d.js b/test/features/to-string/precision/single/kernel-map/object/array3d.js index 0c1ac27d..cf84fd5f 100644 --- a/test/features/to-string/precision/single/kernel-map/object/array3d.js +++ b/test/features/to-string/precision/single/kernel-map/object/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style returns Array3d'); diff --git a/test/features/to-string/precision/single/kernel-map/object/memory-optimized-number-texture.js b/test/features/to-string/precision/single/kernel-map/object/memory-optimized-number-texture.js index 06c27cd3..d0778e80 100644 --- a/test/features/to-string/precision/single/kernel-map/object/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/single/kernel-map/object/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style kernel map returns MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/single/kernel-map/object/number-texture.js b/test/features/to-string/precision/single/kernel-map/object/number-texture.js index ee294f1e..764d42ea 100644 --- a/test/features/to-string/precision/single/kernel-map/object/number-texture.js +++ b/test/features/to-string/precision/single/kernel-map/object/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string single precision object style kernel map returns NumberTexture'); diff --git a/test/features/to-string/precision/single/returns/array.js b/test/features/to-string/precision/single/returns/array.js index fde332ec..4511b4c6 100644 --- a/test/features/to-string/precision/single/returns/array.js +++ b/test/features/to-string/precision/single/returns/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision returns Array'); diff --git a/test/features/to-string/precision/single/returns/array2d.js b/test/features/to-string/precision/single/returns/array2d.js index bea7ee04..acec9b2a 100644 --- a/test/features/to-string/precision/single/returns/array2d.js +++ b/test/features/to-string/precision/single/returns/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision returns Array2D'); diff --git a/test/features/to-string/precision/single/returns/array3d.js b/test/features/to-string/precision/single/returns/array3d.js index 04828661..141fd522 100644 --- a/test/features/to-string/precision/single/returns/array3d.js +++ b/test/features/to-string/precision/single/returns/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string single precision returns Array3d'); diff --git a/test/features/to-string/precision/unsigned/arguments/array.js b/test/features/to-string/precision/unsigned/arguments/array.js index 18f6ef72..1c5129f5 100644 --- a/test/features/to-string/precision/unsigned/arguments/array.js +++ b/test/features/to-string/precision/unsigned/arguments/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array'); diff --git a/test/features/to-string/precision/unsigned/arguments/array2.js b/test/features/to-string/precision/unsigned/arguments/array2.js index e4ce7279..07cc7c07 100644 --- a/test/features/to-string/precision/unsigned/arguments/array2.js +++ b/test/features/to-string/precision/unsigned/arguments/array2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array(2)'); diff --git a/test/features/to-string/precision/unsigned/arguments/array2d.js b/test/features/to-string/precision/unsigned/arguments/array2d.js index 670a0bf7..cad5f503 100644 --- a/test/features/to-string/precision/unsigned/arguments/array2d.js +++ b/test/features/to-string/precision/unsigned/arguments/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array2D'); diff --git a/test/features/to-string/precision/unsigned/arguments/array3.js b/test/features/to-string/precision/unsigned/arguments/array3.js index e1bc7428..54dd5432 100644 --- a/test/features/to-string/precision/unsigned/arguments/array3.js +++ b/test/features/to-string/precision/unsigned/arguments/array3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array(3)'); diff --git a/test/features/to-string/precision/unsigned/arguments/array3d.js b/test/features/to-string/precision/unsigned/arguments/array3d.js index 46e465f0..b7035786 100644 --- a/test/features/to-string/precision/unsigned/arguments/array3d.js +++ b/test/features/to-string/precision/unsigned/arguments/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array3D'); diff --git a/test/features/to-string/precision/unsigned/arguments/array4.js b/test/features/to-string/precision/unsigned/arguments/array4.js index ca319303..d43dbfbc 100644 --- a/test/features/to-string/precision/unsigned/arguments/array4.js +++ b/test/features/to-string/precision/unsigned/arguments/array4.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Array(4)'); diff --git a/test/features/to-string/precision/unsigned/arguments/boolean.js b/test/features/to-string/precision/unsigned/arguments/boolean.js index 157b3ac3..6b59f5d8 100644 --- a/test/features/to-string/precision/unsigned/arguments/boolean.js +++ b/test/features/to-string/precision/unsigned/arguments/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Boolean'); diff --git a/test/features/to-string/precision/unsigned/arguments/float.js b/test/features/to-string/precision/unsigned/arguments/float.js index aabe1cf2..d3bab22c 100644 --- a/test/features/to-string/precision/unsigned/arguments/float.js +++ b/test/features/to-string/precision/unsigned/arguments/float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Float'); diff --git a/test/features/to-string/precision/unsigned/arguments/html-image-array.js b/test/features/to-string/precision/unsigned/arguments/html-image-array.js index a259b44a..8dcaac22 100644 --- a/test/features/to-string/precision/unsigned/arguments/html-image-array.js +++ b/test/features/to-string/precision/unsigned/arguments/html-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../../../../../src'); +const { GPU, CPUKernel } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments HTMLImageArray'); diff --git a/test/features/to-string/precision/unsigned/arguments/html-image.js b/test/features/to-string/precision/unsigned/arguments/html-image.js index 86134f88..c0152af2 100644 --- a/test/features/to-string/precision/unsigned/arguments/html-image.js +++ b/test/features/to-string/precision/unsigned/arguments/html-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments HTMLImage'); diff --git a/test/features/to-string/precision/unsigned/arguments/html-video.js b/test/features/to-string/precision/unsigned/arguments/html-video.js index 5c4f477e..69c46ed3 100644 --- a/test/features/to-string/precision/unsigned/arguments/html-video.js +++ b/test/features/to-string/precision/unsigned/arguments/html-video.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments HTMLVideo'); diff --git a/test/features/to-string/precision/unsigned/arguments/input.js b/test/features/to-string/precision/unsigned/arguments/input.js index 0d96103d..b6908f87 100644 --- a/test/features/to-string/precision/unsigned/arguments/input.js +++ b/test/features/to-string/precision/unsigned/arguments/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../../../../../src'); +const { GPU, input } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Input'); diff --git a/test/features/to-string/precision/unsigned/arguments/integer.js b/test/features/to-string/precision/unsigned/arguments/integer.js index 22d1e750..65e1e02b 100644 --- a/test/features/to-string/precision/unsigned/arguments/integer.js +++ b/test/features/to-string/precision/unsigned/arguments/integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments Integer'); diff --git a/test/features/to-string/precision/unsigned/arguments/memory-optimized-number-texture.js b/test/features/to-string/precision/unsigned/arguments/memory-optimized-number-texture.js index 6695695e..f264a4b5 100644 --- a/test/features/to-string/precision/unsigned/arguments/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/unsigned/arguments/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/unsigned/arguments/number-texture.js b/test/features/to-string/precision/unsigned/arguments/number-texture.js index a0012393..dd0e89cf 100644 --- a/test/features/to-string/precision/unsigned/arguments/number-texture.js +++ b/test/features/to-string/precision/unsigned/arguments/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision arguments NumberTexture'); diff --git a/test/features/to-string/precision/unsigned/constants/array.js b/test/features/to-string/precision/unsigned/constants/array.js index 5e7073c3..b98da77f 100644 --- a/test/features/to-string/precision/unsigned/constants/array.js +++ b/test/features/to-string/precision/unsigned/constants/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array'); diff --git a/test/features/to-string/precision/unsigned/constants/array2.js b/test/features/to-string/precision/unsigned/constants/array2.js index bce3d0eb..f2559568 100644 --- a/test/features/to-string/precision/unsigned/constants/array2.js +++ b/test/features/to-string/precision/unsigned/constants/array2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array(2)'); diff --git a/test/features/to-string/precision/unsigned/constants/array2d.js b/test/features/to-string/precision/unsigned/constants/array2d.js index 5728c074..3d97006e 100644 --- a/test/features/to-string/precision/unsigned/constants/array2d.js +++ b/test/features/to-string/precision/unsigned/constants/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array2D'); diff --git a/test/features/to-string/precision/unsigned/constants/array3.js b/test/features/to-string/precision/unsigned/constants/array3.js index fae63691..050234c7 100644 --- a/test/features/to-string/precision/unsigned/constants/array3.js +++ b/test/features/to-string/precision/unsigned/constants/array3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array(3)'); diff --git a/test/features/to-string/precision/unsigned/constants/array3d.js b/test/features/to-string/precision/unsigned/constants/array3d.js index 680ae6e2..43e1fe70 100644 --- a/test/features/to-string/precision/unsigned/constants/array3d.js +++ b/test/features/to-string/precision/unsigned/constants/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array3D'); diff --git a/test/features/to-string/precision/unsigned/constants/array4.js b/test/features/to-string/precision/unsigned/constants/array4.js index a0a93754..2696f826 100644 --- a/test/features/to-string/precision/unsigned/constants/array4.js +++ b/test/features/to-string/precision/unsigned/constants/array4.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Array(4)'); diff --git a/test/features/to-string/precision/unsigned/constants/boolean.js b/test/features/to-string/precision/unsigned/constants/boolean.js index 6e65b715..57b6251a 100644 --- a/test/features/to-string/precision/unsigned/constants/boolean.js +++ b/test/features/to-string/precision/unsigned/constants/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Boolean'); diff --git a/test/features/to-string/precision/unsigned/constants/float.js b/test/features/to-string/precision/unsigned/constants/float.js index abdebe81..d4dcaf1b 100644 --- a/test/features/to-string/precision/unsigned/constants/float.js +++ b/test/features/to-string/precision/unsigned/constants/float.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Float'); diff --git a/test/features/to-string/precision/unsigned/constants/html-image-array.js b/test/features/to-string/precision/unsigned/constants/html-image-array.js index db3f5267..b21ba210 100644 --- a/test/features/to-string/precision/unsigned/constants/html-image-array.js +++ b/test/features/to-string/precision/unsigned/constants/html-image-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, CPUKernel } = require('../../../../../../src'); +const { GPU, CPUKernel } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants HTMLImageArray'); diff --git a/test/features/to-string/precision/unsigned/constants/html-image.js b/test/features/to-string/precision/unsigned/constants/html-image.js index f69bb291..7eaec51b 100644 --- a/test/features/to-string/precision/unsigned/constants/html-image.js +++ b/test/features/to-string/precision/unsigned/constants/html-image.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, utils } = require('../../../../../../src'); +const { GPU, utils } = require('../../../../../../dist/gpu.js'); const { loadImage, imageToArray, check2DImage } = require('../../../../../browser-test-utils'); describe('feature: to-string unsigned precision constants HTMLImage'); diff --git a/test/features/to-string/precision/unsigned/constants/input.js b/test/features/to-string/precision/unsigned/constants/input.js index 8b435a2a..427373e5 100644 --- a/test/features/to-string/precision/unsigned/constants/input.js +++ b/test/features/to-string/precision/unsigned/constants/input.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, input } = require('../../../../../../src'); +const { GPU, input } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Input'); diff --git a/test/features/to-string/precision/unsigned/constants/integer.js b/test/features/to-string/precision/unsigned/constants/integer.js index 8244c9d8..b128e968 100644 --- a/test/features/to-string/precision/unsigned/constants/integer.js +++ b/test/features/to-string/precision/unsigned/constants/integer.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants Integer'); diff --git a/test/features/to-string/precision/unsigned/constants/memory-optimized-number-texture.js b/test/features/to-string/precision/unsigned/constants/memory-optimized-number-texture.js index bb65fcc9..b5eb8ce7 100644 --- a/test/features/to-string/precision/unsigned/constants/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/unsigned/constants/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/unsigned/constants/number-texture.js b/test/features/to-string/precision/unsigned/constants/number-texture.js index b41fd742..b7171e28 100644 --- a/test/features/to-string/precision/unsigned/constants/number-texture.js +++ b/test/features/to-string/precision/unsigned/constants/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision constants NumberTexture'); diff --git a/test/features/to-string/precision/unsigned/graphical.js b/test/features/to-string/precision/unsigned/graphical.js index b6198589..6444ad13 100644 --- a/test/features/to-string/precision/unsigned/graphical.js +++ b/test/features/to-string/precision/unsigned/graphical.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../src'); +const { GPU } = require('../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision graphical'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/array.js b/test/features/to-string/precision/unsigned/kernel-map/array/array.js index 093004f3..f8991b4e 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/array.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns Array'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/array2d.js b/test/features/to-string/precision/unsigned/kernel-map/array/array2d.js index e4d8c555..3898e7f7 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/array2d.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns Array2D'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/array3d.js b/test/features/to-string/precision/unsigned/kernel-map/array/array3d.js index 631d0c7f..283d9825 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/array3d.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns Array3d'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/memory-optimized-number-texture.js b/test/features/to-string/precision/unsigned/kernel-map/array/memory-optimized-number-texture.js index 783dbf72..8299cf35 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/array/number-texture.js b/test/features/to-string/precision/unsigned/kernel-map/array/number-texture.js index 3ace604a..7a8240b7 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/array/number-texture.js +++ b/test/features/to-string/precision/unsigned/kernel-map/array/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision array style kernel map returns NumberTexture'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/array.js b/test/features/to-string/precision/unsigned/kernel-map/object/array.js index 87c40562..02b069c9 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/array.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style returns Array'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/array2d.js b/test/features/to-string/precision/unsigned/kernel-map/object/array2d.js index 05b4231e..b5ed4755 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/array2d.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style returns Array2D'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/array3d.js b/test/features/to-string/precision/unsigned/kernel-map/object/array3d.js index 16f1fede..24ffa8d6 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/array3d.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style returns Array3d'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/memory-optimized-number-texture.js b/test/features/to-string/precision/unsigned/kernel-map/object/memory-optimized-number-texture.js index 6df0bf2e..6ba5f013 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/memory-optimized-number-texture.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/memory-optimized-number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style kernel map returns MemoryOptimizedNumberTexture'); diff --git a/test/features/to-string/precision/unsigned/kernel-map/object/number-texture.js b/test/features/to-string/precision/unsigned/kernel-map/object/number-texture.js index 22607128..7f10c43c 100644 --- a/test/features/to-string/precision/unsigned/kernel-map/object/number-texture.js +++ b/test/features/to-string/precision/unsigned/kernel-map/object/number-texture.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../../src'); +const { GPU } = require('../../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision object style kernel map returns NumberTexture'); diff --git a/test/features/to-string/precision/unsigned/returns/array.js b/test/features/to-string/precision/unsigned/returns/array.js index 612aad73..5164f74b 100644 --- a/test/features/to-string/precision/unsigned/returns/array.js +++ b/test/features/to-string/precision/unsigned/returns/array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision returns Array'); diff --git a/test/features/to-string/precision/unsigned/returns/array2d.js b/test/features/to-string/precision/unsigned/returns/array2d.js index eacfc731..7f668cbd 100644 --- a/test/features/to-string/precision/unsigned/returns/array2d.js +++ b/test/features/to-string/precision/unsigned/returns/array2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision returns Array2D'); diff --git a/test/features/to-string/precision/unsigned/returns/array3d.js b/test/features/to-string/precision/unsigned/returns/array3d.js index edebde18..47e302de 100644 --- a/test/features/to-string/precision/unsigned/returns/array3d.js +++ b/test/features/to-string/precision/unsigned/returns/array3d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../../../../../src'); +const { GPU } = require('../../../../../../dist/gpu.js'); describe('feature: to-string unsigned precision returns Array3d'); diff --git a/test/features/type-management.js b/test/features/type-management.js index f834a3c8..dd267948 100644 --- a/test/features/type-management.js +++ b/test/features/type-management.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only } = require('qunit'); -const { WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../src'); +const { WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../dist/gpu.js'); describe('features: type management'); diff --git a/test/features/unsigned-precision-textures.js b/test/features/unsigned-precision-textures.js index 167a3fcd..031247f0 100644 --- a/test/features/unsigned-precision-textures.js +++ b/test/features/unsigned-precision-textures.js @@ -1,5 +1,5 @@ const { assert, skip, test, only, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('features: unsigned precision textures'); diff --git a/test/index.js b/test/index.js index d24b5b6a..34a21555 100644 --- a/test/index.js +++ b/test/index.js @@ -1,72 +1,73 @@ -const { expect } = require('chai'); - -const GPU = require('../src/index.js'); - -describe('Test Node GPU', () => { - describe('gpu mode', () => { - it('should find and use gpu runner', () => { - const gpu = new GPU({ mode: 'gpu' }); - - const kernel = gpu.createKernel(function() { - return 1; - }).setOutput([1]); - - const result = kernel(); - - expect(gpu.runner.constructor).to.equal(GPU.HeadlessGLRunner); - expect(result[0]).to.equal(1); - }); - - it('supports 2x2 size', () => { - const gpu = new GPU({ mode: 'gpu' }); - - const kernel = gpu.createKernel(function() { - return this.thread.x * this.thread.y; - }).setOutput([2, 2]); - - const result = kernel(); - - expect(gpu.runner.constructor).to.equal(GPU.HeadlessGLRunner); - expect(result).to.deep.equal( - [ - Float32Array.from([0,0]), - Float32Array.from([0,1]) - ] - ); - }); - }); - - describe('cpu mode', () => { - it('should find and use gpu runner', () => { - const gpu = new GPU({ mode: 'cpu' }); - - const kernel = gpu.createKernel(function() { - return 1; - }).setOutput([1]); - - const result = kernel(); - - expect(gpu.runner.constructor).to.equal(GPU.CPURunner); - expect(result[0]).to.equal(1); - }); - - it('supports 2x2 size', () => { - const gpu = new GPU({ mode: 'cpu' }); - - const kernel = gpu.createKernel(function() { - return this.thread.x * this.thread.y; - }).setOutput([2, 2]); - - const result = kernel(); - - expect(gpu.runner.constructor).to.equal(GPU.CPURunner); - expect(result).to.deep.equal( - [ - Float32Array.from([0,0]), - Float32Array.from([0,1]) - ] - ); - }); - }); -}); - +const { module: describe, test: it } = require('qunit'); +const { expect } = require('chai'); + +const { GPU } = require('../dist/gpu.js'); + +describe('Test Node GPU', () => { + describe('gpu mode', () => { + it('should find and use gpu runner', () => { + const gpu = new GPU({ mode: 'gpu' }); + + const kernel = gpu.createKernel(function() { + return 1; + }).setOutput([1]); + + const result = kernel(); + + expect(gpu.runner.constructor).to.equal(GPU.HeadlessGLRunner); + expect(result[0]).to.equal(1); + }); + + it('supports 2x2 size', () => { + const gpu = new GPU({ mode: 'gpu' }); + + const kernel = gpu.createKernel(function() { + return this.thread.x * this.thread.y; + }).setOutput([2, 2]); + + const result = kernel(); + + expect(gpu.runner.constructor).to.equal(GPU.HeadlessGLRunner); + expect(result).to.deep.equal( + [ + Float32Array.from([0,0]), + Float32Array.from([0,1]) + ] + ); + }); + }); + + describe('cpu mode', () => { + it('should find and use gpu runner', () => { + const gpu = new GPU({ mode: 'cpu' }); + + const kernel = gpu.createKernel(function() { + return 1; + }).setOutput([1]); + + const result = kernel(); + + expect(gpu.runner.constructor).to.equal(GPU.CPURunner); + expect(result[0]).to.equal(1); + }); + + it('supports 2x2 size', () => { + const gpu = new GPU({ mode: 'cpu' }); + + const kernel = gpu.createKernel(function() { + return this.thread.x * this.thread.y; + }).setOutput([2, 2]); + + const result = kernel(); + + expect(gpu.runner.constructor).to.equal(GPU.CPURunner); + expect(result).to.deep.equal( + [ + Float32Array.from([0,0]), + Float32Array.from([0,1]) + ] + ); + }); + }); +}); + diff --git a/test/internal/.DS_Store b/test/internal/.DS_Store deleted file mode 100644 index f206f7d1..00000000 Binary files a/test/internal/.DS_Store and /dev/null differ diff --git a/test/internal/argument-texture-switching.js b/test/internal/argument-texture-switching.js index eb5a1f8b..f2ea5ccd 100644 --- a/test/internal/argument-texture-switching.js +++ b/test/internal/argument-texture-switching.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: argument texture switching'); diff --git a/test/internal/backend/.DS_Store b/test/internal/backend/.DS_Store deleted file mode 100644 index d9cd1ee4..00000000 Binary files a/test/internal/backend/.DS_Store and /dev/null differ diff --git a/test/internal/backend/cpu/function-node.js b/test/internal/backend/cpu/function-node.js index 5fe47d99..f4c51325 100644 --- a/test/internal/backend/cpu/function-node.js +++ b/test/internal/backend/cpu/function-node.js @@ -1,6 +1,6 @@ const { assert, skip, test, module: describe, only } = require('qunit'); const sinon = require('sinon'); -const { CPUFunctionNode } = require('../../../../src'); +const { CPUFunctionNode } = require('../../../../dist/gpu.js'); describe('internal: CPUFunctionNode'); diff --git a/test/internal/backend/headless-gl/kernel/index.js b/test/internal/backend/headless-gl/kernel/index.js index 7e02a453..d2252b24 100644 --- a/test/internal/backend/headless-gl/kernel/index.js +++ b/test/internal/backend/headless-gl/kernel/index.js @@ -10,7 +10,7 @@ describe('internal: HeadlessGLKernel'); } }; // this is done late on purpose! Do not change this, as it causes HeadlessGL to initialize with certain values -const { HeadlessGLKernel } = require('../../../../../src'); +const { HeadlessGLKernel } = require('../../../../../dist/gpu.js'); HeadlessGLKernel.setupFeatureChecks(); assert.ok(true); delete global.document; diff --git a/test/internal/backend/web-gl/function-node/index.js b/test/internal/backend/web-gl/function-node/index.js index dc6f1e48..def4cb5c 100644 --- a/test/internal/backend/web-gl/function-node/index.js +++ b/test/internal/backend/web-gl/function-node/index.js @@ -1,6 +1,6 @@ const { assert, skip, test, module: describe, only } = require('qunit'); const sinon = require('sinon'); -const { WebGLFunctionNode } = require('../../../../../src'); +const { WebGLFunctionNode } = require('../../../../../dist/gpu.js'); describe('internal: WebGLFunctionNode'); diff --git a/test/internal/backend/web-gl/kernel/index.js b/test/internal/backend/web-gl/kernel/index.js index 9ccd37a8..c0cbc85d 100644 --- a/test/internal/backend/web-gl/kernel/index.js +++ b/test/internal/backend/web-gl/kernel/index.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGLKernel } = require('../../../../../src'); +const { WebGLKernel } = require('../../../../../dist/gpu.js'); describe('internal: WebGLKernel'); diff --git a/test/internal/backend/web-gl/kernel/setupArguments.js b/test/internal/backend/web-gl/kernel/setupArguments.js index 83e4bbc8..024e1ecc 100644 --- a/test/internal/backend/web-gl/kernel/setupArguments.js +++ b/test/internal/backend/web-gl/kernel/setupArguments.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGLKernel, input } = require('../../../../../src'); +const { WebGLKernel, input } = require('../../../../../dist/gpu.js'); describe('internal WebGLKernel.setupArguments Array'); const gl = { diff --git a/test/internal/backend/web-gl/kernel/setupConstants.js b/test/internal/backend/web-gl/kernel/setupConstants.js index 6e38288e..536e72ac 100644 --- a/test/internal/backend/web-gl/kernel/setupConstants.js +++ b/test/internal/backend/web-gl/kernel/setupConstants.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGLKernel, input } = require('../../../../../src'); +const { WebGLKernel, input } = require('../../../../../dist/gpu.js'); describe('internal WebGLKernel.setupConstants Array'); const gl = { diff --git a/test/internal/backend/web-gl2/.DS_Store b/test/internal/backend/web-gl2/.DS_Store deleted file mode 100644 index 3e175002..00000000 Binary files a/test/internal/backend/web-gl2/.DS_Store and /dev/null differ diff --git a/test/internal/backend/web-gl2/kernel/index.js b/test/internal/backend/web-gl2/kernel/index.js index 97221a5c..e92cd2c4 100644 --- a/test/internal/backend/web-gl2/kernel/index.js +++ b/test/internal/backend/web-gl2/kernel/index.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGL2Kernel } = require('../../../../../src'); +const { WebGL2Kernel } = require('../../../../../dist/gpu.js'); describe('internal: WebGL2Kernel'); diff --git a/test/internal/backend/web-gl2/kernel/setupArguments.js b/test/internal/backend/web-gl2/kernel/setupArguments.js index b78892f2..b4f860ca 100644 --- a/test/internal/backend/web-gl2/kernel/setupArguments.js +++ b/test/internal/backend/web-gl2/kernel/setupArguments.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGL2Kernel, input } = require('../../../../../src'); +const { WebGL2Kernel, input } = require('../../../../../dist/gpu.js'); describe('internal WebGL2Kernel.setupArguments Array'); const gl = { diff --git a/test/internal/backend/web-gl2/kernel/setupConstants.js b/test/internal/backend/web-gl2/kernel/setupConstants.js index d0649b22..dabcce64 100644 --- a/test/internal/backend/web-gl2/kernel/setupConstants.js +++ b/test/internal/backend/web-gl2/kernel/setupConstants.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGL2Kernel, input } = require('../../../../../src'); +const { WebGL2Kernel, input } = require('../../../../../dist/gpu.js'); describe('internal WebGL2Kernel.setupConstants Array'); const gl = { diff --git a/test/internal/boolean.js b/test/internal/boolean.js index abb2a9df..a65a586f 100644 --- a/test/internal/boolean.js +++ b/test/internal/boolean.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: boolean'); diff --git a/test/internal/casting.js b/test/internal/casting.js index 89635afb..84b852b3 100644 --- a/test/internal/casting.js +++ b/test/internal/casting.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: casting'); diff --git a/test/internal/constants-texture-switching.js b/test/internal/constants-texture-switching.js index d00951bc..78d2fdd0 100644 --- a/test/internal/constants-texture-switching.js +++ b/test/internal/constants-texture-switching.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: constants texture switching'); diff --git a/test/internal/constructor-features.js b/test/internal/constructor-features.js index be654879..d0b68e00 100644 --- a/test/internal/constructor-features.js +++ b/test/internal/constructor-features.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: constructor features'); diff --git a/test/internal/context-inheritance.js b/test/internal/context-inheritance.js index 01f7ce4e..e44f2924 100644 --- a/test/internal/context-inheritance.js +++ b/test/internal/context-inheritance.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, WebGLKernel, WebGL2Kernel, HeadlessGLKernel } = require('../../src'); +const { GPU, WebGLKernel, WebGL2Kernel, HeadlessGLKernel } = require('../../dist/gpu.js'); describe('internal: context inheritance'); diff --git a/test/internal/deep-types.js b/test/internal/deep-types.js index 5fa1cd43..8e08a9f3 100644 --- a/test/internal/deep-types.js +++ b/test/internal/deep-types.js @@ -1,6 +1,6 @@ const sinon = require('sinon'); const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU, FunctionBuilder } = require('../../src'); +const { GPU, FunctionBuilder } = require('../../dist/gpu.js'); describe('internal: deep types'); diff --git a/test/internal/deprecated.js b/test/internal/deprecated.js index f5c2848b..1efa83a0 100644 --- a/test/internal/deprecated.js +++ b/test/internal/deprecated.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only, skip } = require('qunit'); -const { GPU, Kernel } = require('../../src'); +const { GPU, Kernel } = require('../../dist/gpu.js'); describe('internal: deprecated'); diff --git a/test/internal/function-builder.js b/test/internal/function-builder.js index 7755507a..291f71e5 100644 --- a/test/internal/function-builder.js +++ b/test/internal/function-builder.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only } = require('qunit'); -const { FunctionBuilder, CPUFunctionNode, WebGL2FunctionNode, WebGLFunctionNode } = require('../../src'); +const { FunctionBuilder, CPUFunctionNode, WebGL2FunctionNode, WebGLFunctionNode } = require('../../dist/gpu.js'); describe('internal: function builder'); diff --git a/test/internal/function-composition.js b/test/internal/function-composition.js index a65cc81d..14cc8572 100644 --- a/test/internal/function-composition.js +++ b/test/internal/function-composition.js @@ -1,6 +1,6 @@ const { assert, test, skip, module: describe, only } = require('qunit'); const sinon = require('sinon'); -const { CPUFunctionNode, FunctionBuilder, GPU, WebGL2FunctionNode, WebGLFunctionNode } = require('../../src'); +const { CPUFunctionNode, FunctionBuilder, GPU, WebGL2FunctionNode, WebGLFunctionNode } = require('../../dist/gpu.js'); describe('internal: function composition return values'); diff --git a/test/internal/function-node.js b/test/internal/function-node.js index fba0fc39..69652932 100644 --- a/test/internal/function-node.js +++ b/test/internal/function-node.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, only } = require('qunit'); -const { CPUFunctionNode, WebGLFunctionNode, WebGL2FunctionNode } = require('../../src'); +const { CPUFunctionNode, WebGLFunctionNode, WebGL2FunctionNode } = require('../../dist/gpu.js'); describe('internal: function node'); diff --git a/test/internal/function-return-type-detection.js b/test/internal/function-return-type-detection.js index f8bd462a..952ed1e0 100644 --- a/test/internal/function-return-type-detection.js +++ b/test/internal/function-return-type-detection.js @@ -1,5 +1,5 @@ const { assert, test, skip, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: Function return type detection'); diff --git a/test/internal/gpu-methods.js b/test/internal/gpu-methods.js index b9acb266..dbc6617a 100644 --- a/test/internal/gpu-methods.js +++ b/test/internal/gpu-methods.js @@ -1,5 +1,5 @@ const { assert, test, skip, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: GPU methods'); diff --git a/test/internal/implied-else.js b/test/internal/implied-else.js index 9eae23b7..68e40520 100644 --- a/test/internal/implied-else.js +++ b/test/internal/implied-else.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: Implied else'); diff --git a/test/internal/kernel.js b/test/internal/kernel.js index e3fdb187..247686c9 100644 --- a/test/internal/kernel.js +++ b/test/internal/kernel.js @@ -1,5 +1,5 @@ const { assert, test, module: describe, skip } = require('qunit'); -const { GPU, CPUKernel, WebGLKernel, WebGL2Kernel, HeadlessGLKernel } = require('../../src'); +const { GPU, CPUKernel, WebGLKernel, WebGL2Kernel, HeadlessGLKernel } = require('../../dist/gpu.js'); describe('internal: kernel'); diff --git a/test/internal/loop-int.js b/test/internal/loop-int.js index d9322a7e..cda49977 100644 --- a/test/internal/loop-int.js +++ b/test/internal/loop-int.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, WebGLFunctionNode, WebGL2FunctionNode } = require('../../src'); +const { GPU, WebGLFunctionNode, WebGL2FunctionNode } = require('../../dist/gpu.js'); describe('internal: loop int'); test('loop int constant output webgl', () => { diff --git a/test/internal/loop-max.js b/test/internal/loop-max.js index eb11fa76..b06b480e 100644 --- a/test/internal/loop-max.js +++ b/test/internal/loop-max.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, WebGLFunctionNode, WebGL2FunctionNode } = require('../../src'); +const { GPU, WebGLFunctionNode, WebGL2FunctionNode } = require('../../dist/gpu.js'); describe('internal: loop max'); diff --git a/test/internal/math.random.js b/test/internal/math.random.js index b1d11c9a..b34a4ab7 100644 --- a/test/internal/math.random.js +++ b/test/internal/math.random.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('Math.random() unique'); diff --git a/test/internal/matrix-multiply-precision.js b/test/internal/matrix-multiply-precision.js index 126f20d8..d516b5cf 100644 --- a/test/internal/matrix-multiply-precision.js +++ b/test/internal/matrix-multiply-precision.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: matrix multiply precision'); diff --git a/test/internal/mixed-memory-optimize.js b/test/internal/mixed-memory-optimize.js index efdd92dd..cc3e46ea 100644 --- a/test/internal/mixed-memory-optimize.js +++ b/test/internal/mixed-memory-optimize.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: mixed memory optimize'); diff --git a/test/internal/modes.js b/test/internal/modes.js index 997c9770..a28758ee 100644 --- a/test/internal/modes.js +++ b/test/internal/modes.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, WebGLKernel, WebGL2Kernel, HeadlessGLKernel, CPUKernel } = require('../../src'); +const { GPU, WebGLKernel, WebGL2Kernel, HeadlessGLKernel, CPUKernel } = require('../../dist/gpu.js'); describe('internal: modes'); diff --git a/test/internal/overloading.js b/test/internal/overloading.js index f97a4cf5..219f9347 100644 --- a/test/internal/overloading.js +++ b/test/internal/overloading.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: overloading'); // TODO: planned for after v2, overload generated functions so as to cut down on casting diff --git a/test/internal/precision.js b/test/internal/precision.js index e3f06cec..8948f5fd 100644 --- a/test/internal/precision.js +++ b/test/internal/precision.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: precision'); diff --git a/test/internal/texture-index.js b/test/internal/texture-index.js index 1f5af264..29c58e70 100644 --- a/test/internal/texture-index.js +++ b/test/internal/texture-index.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('internal: texture index'); function createKernelWithNumberConstants(mode) { diff --git a/test/internal/utils.js b/test/internal/utils.js index f72f10ed..b804f225 100644 --- a/test/internal/utils.js +++ b/test/internal/utils.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { utils } = require('../../src'); +const { utils } = require('../../dist/gpu.js'); describe('internal: utils'); diff --git a/test/issues/114-create-kernel-map-run-second-time.js b/test/issues/114-create-kernel-map-run-second-time.js index 7d15c517..889e1ad1 100644 --- a/test/issues/114-create-kernel-map-run-second-time.js +++ b/test/issues/114-create-kernel-map-run-second-time.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue # 114'); function secondKernelMap(mode) { diff --git a/test/issues/116-multiple-kernels-run-again.js b/test/issues/116-multiple-kernels-run-again.js index a3bd4a22..c5231bce 100644 --- a/test/issues/116-multiple-kernels-run-again.js +++ b/test/issues/116-multiple-kernels-run-again.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #116'); diff --git a/test/issues/130-typed-array.js b/test/issues/130-typed-array.js index ab79483e..c617a9ba 100644 --- a/test/issues/130-typed-array.js +++ b/test/issues/130-typed-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #130'); function typedArrays(mode) { diff --git a/test/issues/147-missing-constant.js b/test/issues/147-missing-constant.js index f6d8a5d9..3804e447 100644 --- a/test/issues/147-missing-constant.js +++ b/test/issues/147-missing-constant.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #147'); diff --git a/test/issues/152-for-vars.js b/test/issues/152-for-vars.js index af1eef22..848879cc 100644 --- a/test/issues/152-for-vars.js +++ b/test/issues/152-for-vars.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #152'); diff --git a/test/issues/159-3d.js b/test/issues/159-3d.js index 4f4f66ca..d78ce0ee 100644 --- a/test/issues/159-3d.js +++ b/test/issues/159-3d.js @@ -3,7 +3,7 @@ const { assert, skip, test, module: describe } = require('qunit'); describe('issue # 159'); (function() { - const { GPU } = require('../../src'); + const { GPU } = require('../../dist/gpu.js'); function threeD(mode) { const gpu = new GPU({ mode }); diff --git a/test/issues/174-webgl-context-warning.js b/test/issues/174-webgl-context-warning.js index b9329011..ce4b7c6a 100644 --- a/test/issues/174-webgl-context-warning.js +++ b/test/issues/174-webgl-context-warning.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue # 174'); diff --git a/test/issues/195-read-from-texture2d.js b/test/issues/195-read-from-texture2d.js index 00e1e68f..4d8570b9 100644 --- a/test/issues/195-read-from-texture2d.js +++ b/test/issues/195-read-from-texture2d.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #195'); function makeKernel(gpu) { diff --git a/test/issues/207-same-function-reuse.js b/test/issues/207-same-function-reuse.js index c117ada9..25f6e755 100644 --- a/test/issues/207-same-function-reuse.js +++ b/test/issues/207-same-function-reuse.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #207'); diff --git a/test/issues/212-funky-function-support.js b/test/issues/212-funky-function-support.js index de65e5e3..e5ed0584 100644 --- a/test/issues/212-funky-function-support.js +++ b/test/issues/212-funky-function-support.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #212'); diff --git a/test/issues/233-kernel-map-single-precision.js b/test/issues/233-kernel-map-single-precision.js index c82ac744..0f5402e5 100644 --- a/test/issues/233-kernel-map-single-precision.js +++ b/test/issues/233-kernel-map-single-precision.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue # 233'); diff --git a/test/issues/241-CPU-vs-GPU-maps-output-differently.js b/test/issues/241-CPU-vs-GPU-maps-output-differently.js index 2297a178..e86424ac 100644 --- a/test/issues/241-CPU-vs-GPU-maps-output-differently.js +++ b/test/issues/241-CPU-vs-GPU-maps-output-differently.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #241'); diff --git a/test/issues/259-atan2.js b/test/issues/259-atan2.js index 1aa9a122..30d7550d 100644 --- a/test/issues/259-atan2.js +++ b/test/issues/259-atan2.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #259'); diff --git a/test/issues/263-to-string.js b/test/issues/263-to-string.js index f811e017..7723f544 100644 --- a/test/issues/263-to-string.js +++ b/test/issues/263-to-string.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #263'); diff --git a/test/issues/267-immutable-sub-kernels.js b/test/issues/267-immutable-sub-kernels.js index eda40838..de4052f3 100644 --- a/test/issues/267-immutable-sub-kernels.js +++ b/test/issues/267-immutable-sub-kernels.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #267 kernel'); diff --git a/test/issues/270-cache.js b/test/issues/270-cache.js index d08a6e80..23a44763 100644 --- a/test/issues/270-cache.js +++ b/test/issues/270-cache.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { WebGLKernel } = require('../../src'); +const { WebGLKernel } = require('../../dist/gpu.js'); describe('issue # 270'); diff --git a/test/issues/279-wrong-canvas-size.js b/test/issues/279-wrong-canvas-size.js index ea072def..40978b3d 100644 --- a/test/issues/279-wrong-canvas-size.js +++ b/test/issues/279-wrong-canvas-size.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #279'); diff --git a/test/issues/300-nested-array-index.js b/test/issues/300-nested-array-index.js index c20d59cf..bbeb5f8a 100644 --- a/test/issues/300-nested-array-index.js +++ b/test/issues/300-nested-array-index.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #300'); diff --git a/test/issues/31-nested-var-declare-test.js b/test/issues/31-nested-var-declare-test.js index f87deb41..3e81876f 100644 --- a/test/issues/31-nested-var-declare-test.js +++ b/test/issues/31-nested-var-declare-test.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU, FunctionBuilder, WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../src'); +const { GPU, FunctionBuilder, WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../dist/gpu.js'); describe('issue #31 redeclare'); diff --git a/test/issues/313-variable-lookup.js b/test/issues/313-variable-lookup.js index e1dd00e9..31c73276 100644 --- a/test/issues/313-variable-lookup.js +++ b/test/issues/313-variable-lookup.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #313'); diff --git a/test/issues/314-large-input-array-addressing.js b/test/issues/314-large-input-array-addressing.js index 27882652..a6dc9de3 100644 --- a/test/issues/314-large-input-array-addressing.js +++ b/test/issues/314-large-input-array-addressing.js @@ -1,59 +1,59 @@ -const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, WebGLKernel, HeadlessGLKernel } = require('../../src'); - -describe('issue #314'); - -// max size of ok addressing was 8388608, 8388609 is shifted by 1 so index seems to be 8388610 -// after this fix max addressing is 2^31 which is the max a int32 can handle -// run out of heap before being able to create a butter that big! -// wanted to use uints but caused more problems than it solved -const DATA_MAX = (GPU.isHeadlessGLSupported ? HeadlessGLKernel : WebGLKernel).features.maxTextureSize*8; -const divisor = 100; -const data = new Uint16Array(DATA_MAX); -let v = 0; -for (let i = 0; i < DATA_MAX/divisor; i++) { - for (let j = 0; j < divisor; j++) { - data[i*divisor + j] = v++; - } -} -function buildLargeArrayAddressKernel(mode) { - const gpu = new GPU({ mode }); - const largeArrayAddressKernel = gpu.createKernel(function(data) { - return data[this.thread.x]; - }, { - precision: 'unsigned', - }) - .setOutput([DATA_MAX]); - - const result = largeArrayAddressKernel(data); - - let same = true; - let i = 0; - for (; i < DATA_MAX; i++) { - if (result[i] !== data[i]) { - same = false; - break; - } - } - assert.ok(same, "not all elements are the same, failed on index:" + i); - gpu.destroy(); -} - -test('Issue #314 Large array addressing - auto', () => { - buildLargeArrayAddressKernel(null); -}); - -test('Issue #314 Large array addressing - gpu', () => { - buildLargeArrayAddressKernel('gpu'); -}); - -(GPU.isWebGLSupported ? test : skip)('Issue #314 Large array addressing - webgl', () => { - buildLargeArrayAddressKernel('webgl'); -}); - -(GPU.isWebGL2Supported ? test : skip)('Issue #314 Large array addressing - webgl2', () => { - buildLargeArrayAddressKernel('webgl2'); -}); -(GPU.isHeadlessGLSupported ? test : skip)('Issue #314 Large array addressing - headlessgl', () => { - buildLargeArrayAddressKernel('headlessgl'); -}); +const { assert, skip, test, module: describe } = require('qunit'); +const { GPU, WebGLKernel, HeadlessGLKernel } = require('../../dist/gpu.js'); + +describe('issue #314'); + +// max size of ok addressing was 8388608, 8388609 is shifted by 1 so index seems to be 8388610 +// after this fix max addressing is 2^31 which is the max a int32 can handle +// run out of heap before being able to create a butter that big! +// wanted to use uints but caused more problems than it solved +const DATA_MAX = (GPU.isHeadlessGLSupported ? HeadlessGLKernel : WebGLKernel).features.maxTextureSize*8; +const divisor = 100; +const data = new Uint16Array(DATA_MAX); +let v = 0; +for (let i = 0; i < DATA_MAX/divisor; i++) { + for (let j = 0; j < divisor; j++) { + data[i*divisor + j] = v++; + } +} +function buildLargeArrayAddressKernel(mode) { + const gpu = new GPU({ mode }); + const largeArrayAddressKernel = gpu.createKernel(function(data) { + return data[this.thread.x]; + }, { + precision: 'unsigned', + }) + .setOutput([DATA_MAX]); + + const result = largeArrayAddressKernel(data); + + let same = true; + let i = 0; + for (; i < DATA_MAX; i++) { + if (result[i] !== data[i]) { + same = false; + break; + } + } + assert.ok(same, "not all elements are the same, failed on index:" + i); + gpu.destroy(); +} + +test('Issue #314 Large array addressing - auto', () => { + buildLargeArrayAddressKernel(null); +}); + +test('Issue #314 Large array addressing - gpu', () => { + buildLargeArrayAddressKernel('gpu'); +}); + +(GPU.isWebGLSupported ? test : skip)('Issue #314 Large array addressing - webgl', () => { + buildLargeArrayAddressKernel('webgl'); +}); + +(GPU.isWebGL2Supported ? test : skip)('Issue #314 Large array addressing - webgl2', () => { + buildLargeArrayAddressKernel('webgl2'); +}); +(GPU.isHeadlessGLSupported ? test : skip)('Issue #314 Large array addressing - headlessgl', () => { + buildLargeArrayAddressKernel('headlessgl'); +}); diff --git a/test/issues/335-missing-z-index-issue.js b/test/issues/335-missing-z-index-issue.js index e27d1666..add08d90 100644 --- a/test/issues/335-missing-z-index-issue.js +++ b/test/issues/335-missing-z-index-issue.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #335'); diff --git a/test/issues/346-uint8array-converted.js b/test/issues/346-uint8array-converted.js index 99b749c0..c55291f7 100644 --- a/test/issues/346-uint8array-converted.js +++ b/test/issues/346-uint8array-converted.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #346'); diff --git a/test/issues/349-division-by-factors-of-3.js b/test/issues/349-division-by-factors-of-3.js index 72462ea0..9f093d85 100644 --- a/test/issues/349-division-by-factors-of-3.js +++ b/test/issues/349-division-by-factors-of-3.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #349 divide by 3'); diff --git a/test/issues/357-modulus-issue.js b/test/issues/357-modulus-issue.js index 96b0cd48..c9db53f9 100644 --- a/test/issues/357-modulus-issue.js +++ b/test/issues/357-modulus-issue.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #357'); diff --git a/test/issues/359-addfunction-params-wrong.js b/test/issues/359-addfunction-params-wrong.js index 02186d74..3992a56f 100644 --- a/test/issues/359-addfunction-params-wrong.js +++ b/test/issues/359-addfunction-params-wrong.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #359'); diff --git a/test/issues/378-only-first-iteration.js b/test/issues/378-only-first-iteration.js index 39c5053b..af96f3df 100644 --- a/test/issues/378-only-first-iteration.js +++ b/test/issues/378-only-first-iteration.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #378'); diff --git a/test/issues/382-bad-constant.js b/test/issues/382-bad-constant.js index aa711ce5..bf942e1b 100644 --- a/test/issues/382-bad-constant.js +++ b/test/issues/382-bad-constant.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #382'); diff --git a/test/issues/390-thread-assignment.js b/test/issues/390-thread-assignment.js index d20dd92b..e7164ad6 100644 --- a/test/issues/390-thread-assignment.js +++ b/test/issues/390-thread-assignment.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../src'); +const { WebGLFunctionNode, WebGL2FunctionNode, CPUFunctionNode } = require('../../dist/gpu.js'); describe('issue #390'); diff --git a/test/issues/396-combine-kernels-example.js b/test/issues/396-combine-kernels-example.js index 3e381431..d2fb1323 100644 --- a/test/issues/396-combine-kernels-example.js +++ b/test/issues/396-combine-kernels-example.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #396 - combine kernels example'); diff --git a/test/issues/399-double-definition.js b/test/issues/399-double-definition.js index 515836c9..49502883 100644 --- a/test/issues/399-double-definition.js +++ b/test/issues/399-double-definition.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #399'); diff --git a/test/issues/401-cpu-canvas-check.js b/test/issues/401-cpu-canvas-check.js index 9c8c9fcd..34602a0b 100644 --- a/test/issues/401-cpu-canvas-check.js +++ b/test/issues/401-cpu-canvas-check.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, CPUKernel } = require('../../src'); +const { GPU, CPUKernel } = require('../../dist/gpu.js'); describe('issue #401'); diff --git a/test/issues/410-if-statement.js b/test/issues/410-if-statement.js index 1aad96a6..cb02e90f 100644 --- a/test/issues/410-if-statement.js +++ b/test/issues/410-if-statement.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #410 - if statement when unsigned on NVidia'); diff --git a/test/issues/422-warnings.js b/test/issues/422-warnings.js index 71a31c7f..0d174295 100644 --- a/test/issues/422-warnings.js +++ b/test/issues/422-warnings.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #422 - warnings'); diff --git a/test/issues/470-modulus-wrong.js b/test/issues/470-modulus-wrong.js index 0f9c0e7f..12533787 100644 --- a/test/issues/470-modulus-wrong.js +++ b/test/issues/470-modulus-wrong.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #470 - modulus wrong'); diff --git a/test/issues/471-canvas-issue.js b/test/issues/471-canvas-issue.js index c5030bce..a3663b84 100644 --- a/test/issues/471-canvas-issue.js +++ b/test/issues/471-canvas-issue.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #471 - canvas issue'); diff --git a/test/issues/472-compilation-issue.js b/test/issues/472-compilation-issue.js index 19eeef70..bd03e381 100644 --- a/test/issues/472-compilation-issue.js +++ b/test/issues/472-compilation-issue.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #472 - compilation issue'); diff --git a/test/issues/473-4-pixels.js b/test/issues/473-4-pixels.js index fb4ffd94..5b7c597b 100644 --- a/test/issues/473-4-pixels.js +++ b/test/issues/473-4-pixels.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #473 - only 4 pixels are shown'); diff --git a/test/issues/487-dynamic-arguments.js b/test/issues/487-dynamic-arguments.js index 3c68bb72..812b4a59 100644 --- a/test/issues/487-dynamic-arguments.js +++ b/test/issues/487-dynamic-arguments.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #487 - pipeline dynamic arguments'); diff --git a/test/issues/493-strange-literal.js b/test/issues/493-strange-literal.js index 089032ac..c364b11a 100644 --- a/test/issues/493-strange-literal.js +++ b/test/issues/493-strange-literal.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #493 - strange literal'); diff --git a/test/issues/91-create-kernel-map-array.js b/test/issues/91-create-kernel-map-array.js index fd42645e..21e6bd17 100644 --- a/test/issues/91-create-kernel-map-array.js +++ b/test/issues/91-create-kernel-map-array.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe } = require('qunit'); -const { GPU, HeadlessGLKernel, WebGLKernel, WebGL2Kernel, CPUKernel } = require('../../src'); +const { GPU, HeadlessGLKernel, WebGLKernel, WebGL2Kernel, CPUKernel } = require('../../dist/gpu.js'); describe('issue #91'); function getResult(mode) { diff --git a/test/issues/96-param-names.js b/test/issues/96-param-names.js index 7ac7054f..aa1fc480 100644 --- a/test/issues/96-param-names.js +++ b/test/issues/96-param-names.js @@ -1,5 +1,5 @@ const { assert, skip, test, module: describe, only } = require('qunit'); -const { GPU } = require('../../src'); +const { GPU } = require('../../dist/gpu.js'); describe('issue #96'); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy