diff --git a/dist/image-sequencer-ui.brow.js b/dist/image-sequencer-ui.brow.js new file mode 100644 index 0000000000..d1fc639e30 --- /dev/null +++ b/dist/image-sequencer-ui.brow.js @@ -0,0 +1,49817 @@ +require=(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 { + this.ignoreFocusOpen = true; + setTimeout(() => { + // Trigger onFocus and open dropdown. + this.ignoreFocusOpen = false; + }, 50); + }); + }, + // Open dropdown after timeout of onClick. + onFocus: function () { + if (!this.ignoreFocusOpen) { + this.open(); + } + } + }; + + versionManagement.getLatestVersionNumber(function(versionNumber) { + console.log('The latest NPM version number for Image Sequencer (from GitHub) is v' + versionNumber); + }); + console.log('The local version number for Image Sequencer is v' + versionManagement.getLocalVersionNumber()); + + function displayVersionNumber() { + $('#version-number-text').text('Image Sequencer v' + versionManagement.getLocalVersionNumber()); + $('#version-number-top-right').text('v' + versionManagement.getLocalVersionNumber()); + } + displayVersionNumber(); + + function refreshOptions(options) { + // Default options if parameter is empty. + if (options == undefined) options = { sortField: 'text' }; + // Load information of all modules (Name, Inputs, Outputs) + var modulesInfo = sequencer.modulesInfo(); + + var addStepSelect = $('#addStep select'); + addStepSelect.html(''); + + // Add modules to the addStep dropdown + for (var m in modulesInfo) { + if (modulesInfo[m] && modulesInfo[m].name) + addStepSelect.append( + '' + ); + } + // Null option + addStepSelect.append(''); + addStepSelect.selectize(options); + } + refreshOptions(options); + + $(window).on('scroll', scrollFunction); + + /** + * @description Method to toggle the scroll-up arrow. + */ + function scrollFunction(A, B) { + var shouldDisplay = $('body').scrollTop() > 20 || $(':root').scrollTop() > 20; + + $('#move-up').css({ + display: shouldDisplay ? 'block' : 'none' + }); + } + + /** + * @description Method to scroll to the top of the page. + */ + function topFunction() { + $('body').animate({scrollTop: 0}); + $(':root').animate({scrollTop: 0}); + } + + $('#move-up').on('click', topFunction); + + + // UI for each step: + sequencer.setUI(DefaultHtmlStepUi(sequencer)); + + // UI for the overall demo: + var ui = defaultHtmlSequencerUi(sequencer); + + // Load image data from URL `src` parameter. + if (urlHash.getUrlHashParameter('src')) { + sequencer.loadImage(urlHash.getUrlHashParameter('src'), ui.onLoad); + } else { + sequencer.loadImage('images/tulips.png', ui.onLoad); + } + + var resetSequence = function () { + var r = confirm('Do you want to reset the sequence?'); + if (r) + { + window.location.hash = ''; + location.reload(); + } + }; + + $('#addStep select').on('change', ui.selectNewStepUi); + $('#addStep #add-step-btn').on('click', ui.addStepUi); + $('#resetButton').on('click', resetSequence); + + // Module Selector quick buttons click handler. + $('.radio-group .radio').on('click', function () { + $(this).parent().find('.radio').removeClass('selected'); + $(this).addClass('selected'); + newStep = $(this).attr('data-value'); + + $('#addStep select').val(newStep); + ui.selectNewStepUi(newStep); + ui.addStepUi(newStep); + $(this).removeClass('selected'); + }); + + /** + * @method displayMessageOnSaveSequence + * @description When a sequence is saved to a browser, notification is displayed. + * @returns {Null} + */ + function displayMessageOnSaveSequence() { + $('.savesequencemsg').fadeIn(); + setTimeout(function () { + $('.savesequencemsg').fadeOut(); + }, 3000); + } + + $('body').on('click', 'button.remove', ui.removeStepUi); + function saveSequence() { // 1. save seq + var result = window.prompt('Please give a name to your sequence... (Saved sequence will only be available in this browser).'); + if (result) { + result = result + ' (local)'; + sequencer.saveSequence(result, sequencer.toString()); // 1.a study saveSequence + sequencer.loadModules(); + displayMessageOnSaveSequence(); + refreshOptions(); + } + } + $('#saveButton').on('click', function () { + // Different handlers triggered for different dropdown options. + + let dropDownValue = $('#selectSaveOption option:selected').val(); + + if (dropDownValue == 'save-image') { + $('.download-btn:last()').trigger('click'); + } + else if (dropDownValue == 'save-gif') { + handleSavePNG(); + } + else if (dropDownValue == 'save-seq') { + saveSequence(); + } else if(dropDownValue == 'save-pdf') { + savePDF(getLastImage()); + } + else if (dropDownValue == 'save-to-publiclab.org' ){ + SaveToPubliclab(); + } + }); + + let isWorkingOnGifGeneration = false; + + $('.js-view-as-gif').on('click', function (event) { // GIF generation and display + if (isWorkingOnGifGeneration) return; // Prevent multiple button clicks + + isWorkingOnGifGeneration = true; + + var button = event.target; + button.disabled = true; + button.innerHTML = ''; + + try { + // Get GIF resources from previous steps + let options = getGifResources(); + + gifshot.createGIF(options, function (obj) { // GIF generation + if (!obj.error) { + // Final GIF encoded with base64 format + var image = obj.image; + var animatedImage = document.createElement('img'); + + animatedImage.id = 'gif_element'; + animatedImage.src = image; + + let modal = $('#js-download-gif-modal'); + + $('#js-download-as-gif-button').one('click', function () { + downloadGif(image); // Trigger GIF download + modal.modal('hide'); + }); + + var gifContainer = document.getElementById('js-download-modal-gif-container'); + + // Clear previous results + gifContainer.innerHTML = ''; + + // Insert image + gifContainer.appendChild(animatedImage); + + // Open modal + modal.modal(); + + button.disabled = false; + button.innerHTML = 'View GIF'; + isWorkingOnGifGeneration = false; + } + }); + } + catch (e) { + console.error(e); + button.disabled = false; + button.innerHTML = 'View GIF'; + isWorkingOnGifGeneration = false; + } + }); + + function getGifResources() { + // Returns an object with specific gif options + let imgs = document.getElementsByClassName('step-thumbnail'); + var imgSrcs = []; + + // Pushes image sources of all the modules in the DOM + for (var i = 0; i < imgs.length; i++) { + imgSrcs.push(imgs[i].src); + } + + var options = { // GIF frame options + 'gifWidth': imgs[0].width, + 'gifHeight': imgs[0].height, + 'images': imgSrcs, + 'frameDuration': 7, + }; + + return options; + } + + function handleSavePNG() { + let options = getGifResources(); + gifshot.createGIF(options, function(obj){ + + downloadGif(obj.image); + + }); + } + + /** + * Get the data URL for the last image in the sequence. + * @return {string} The data URL for the last image in the sequence. + */ + function getLastImage() { + // Get the image from the last step. + let imgs = document.getElementsByClassName('step-thumbnail'); + let lastStepImage = imgs[imgs.length - 1]; + return lastStepImage.getAttribute('src'); + } + + /** + * Download the given image URL as a PDF file. + * @param {string} imageDataURL - The data URL for the image. + */ + function savePDF(imageDataURL) { + sequencer.getImageDimensions(imageDataURL, function(dimensions) { + if (isGIF(imageDataURL)) { + // Get the dimensions of the image. + let pageWidth = dimensions.width; + let pageHeight = dimensions.height; + + // Create a new pdf with the same dimensions as the image. + const pdf = new jsPDF({ + orientation: pageHeight > pageWidth ? 'portrait' : 'landscape', + unit: 'px', + format: [pageHeight, pageWidth] + }); + + // Add the image to the pdf with dimensions equal to the internal dimensions of the page. + pdf.addImage(imageDataURL, 0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight()); + + // Save the pdf with the filename specified here: + pdf.save('index.pdf'); + } + else console.log('GIFs cannot be converted to PDF'); + }); + } + + + + function downloadGif(image) { + download(image, 'index.gif', 'image/gif'); // Downloadjs library function + } + + function SaveToPubliclab() { + function postToPL(imgSrc) { + var uniq = Date.now(); + $('body').append('
'); + f = $('#postToPL' + uniq)[0]; + f.datauri_main_image.value = imgSrc; + window.open('', 'postToPLWindow'); + f.submit(); + } + postToPL($('img')[sequencer.steps.length - 1].src); + } + + // Image selection and drag/drop handling from examples/lib/imageSelection.js + sequencer.setInputStep({ + dropZoneSelector: '#dropzone', + fileInputSelector: '#fileInput', + takePhotoSelector: '#take-photo', + onLoad: function onFileReaderLoad(progress) { + var reader = progress.target; + var step = sequencer.steps[0]; + var util = intermediateHtmlStepUi(sequencer); + step.output.src = reader.result; + sequencer.run({ index: 0 }); + if (typeof step.options !== 'undefined') + step.options.step.imgElement.src = reader.result; + else + step.imgElement.src = reader.result; + + insertPreview.updatePreviews(reader.result, document.querySelector('#addStep')); + DefaultHtmlStepUi(sequencer).updateDimensions(step); + }, + onTakePhoto: function (url) { + var step = sequencer.steps[0]; + step.output.src = url; + sequencer.run({ index: 0 }); + if (typeof step.options !== 'undefined') + step.options.step.imgElement.src = url; + else + step.imgElement.src = url; + insertPreview.updatePreviews(url, document.querySelector('#addStep')); + DefaultHtmlStepUi(sequencer).updateDimensions(step); + } + }); + + setupCache(); + + if (urlHash.getUrlHashParameter('src')) { // Gets the sequence from the URL + insertPreview.updatePreviews(urlHash.getUrlHashParameter('src'), document.querySelector('#addStep')); + } else { + insertPreview.updatePreviews('images/tulips.png', document.querySelector('#addStep')); + } +}; +},{"../src/util/isGif":171,"./lib/cache.js":2,"./lib/defaultHtmlSequencerUi.js":3,"./lib/defaultHtmlStepUi.js":4,"./lib/insertPreview.js":5,"./lib/intermediateHtmlStepUi.js":6,"./lib/urlHash.js":9,"./lib/versionManagement.js":10}],2:[function(require,module,exports){ +var setupCache = function() { + let newWorker; // When sw.js is changed, this is the new service worker generated. + + // Toggle a CSS class to display a popup prompting the user to fetch a new version. + function showUpdateModal() { + $('#update-prompt-modal').addClass('show'); + } + + /** + * When a new service worker has been loaded, the button in the update prompt + * modal should trigger the skipWaiting event to replace the current + * service worker with the new one. + */ + $('#reload').on('click', function() { + newWorker.postMessage({ action: 'skipWaiting' }); + }); + + if ('serviceWorker' in navigator) { + // Register the service worker. + navigator.serviceWorker.register('sw.js', { scope: '/examples/' }) + .then(function(registration) { + registration.addEventListener('updatefound', () => { + // When sw.js has been changed, get a reference to the new service worker. + newWorker = registration.installing; + newWorker.addEventListener('statechange', () => { + // Check if service worker state has changed. + switch(newWorker.state) { + case 'installed': + if(navigator.serviceWorker.controller) { + // New service worker available; prompt the user to update. + showUpdateModal(); + } + // No updates available; do nothing. + break; + } + }); + }); + + const installingWorker = registration.installing; + installingWorker.onstatechange = () => { + console.log(installingWorker); + if (installingWorker.state === 'installed') { + location.reload(); + } + }; + console.log('Registration successful, scope is:', registration.scope); + }) + .catch(function(error) { + console.log('Service worker registration failed, error:', error); + }); + + /** + * This is the event listener for when the service worker updates. + * When the service worker updates, reload the page. + */ + let refreshing; + navigator.serviceWorker.addEventListener('controllerchange', function() { + if(refreshing) return; + window.location.reload(); + refreshing = true; + }); + } + + if ('serviceWorker' in navigator) { + caches.keys().then(function(cacheNames) { + cacheNames.forEach(function(cacheName) { + $('#clear-cache').append(' ' + cacheName); + }); + }); + } + + $('#clear-cache').click(function() { + if ('serviceWorker' in navigator) { + caches.keys().then(function(cacheNames) { + cacheNames.forEach(function(cacheName) { + caches.delete(cacheName); + }); + }); + } + location.reload(); + }); + + + + + +}; + +module.exports = setupCache; + +},{}],3:[function(require,module,exports){ +var urlHash = require('./urlHash.js'); + insertPreview = require('./insertPreview.js'); +function DefaultHtmlSequencerUi(_sequencer, options) { + + options = options || {}; + var addStepSel = options.addStepSel = options.addStepSel || '#addStep'; + var removeStepSel = options.removeStepSel = options.removeStepSel || 'button.remove'; + var selectStepSel = options.selectStepSel = options.selectStepSel || '#selectStep'; + + function onLoad() { + importStepsFromUrlHash(); + if ($('#selectStep').val() === 'none') + $(addStepSel + ' #add-step-btn').prop('disabled', true); + handleSaveSequence(); + } + + // look up needed steps from Url Hash: + function importStepsFromUrlHash() { + var hash = urlHash.getUrlHashParameter('steps'); + + if (hash) { + _sequencer.importString(hash); + _sequencer.run({ index: 0 }); + } + urlHash.setUrlHashParameter('steps', sequencer.toString()); + } + + function selectNewStepUi() { + var m = $(addStepSel + ' select').val(); + if(!m) m = arguments[0]; + else $(addStepSel + ' .info').html(_sequencer.modulesInfo(m).description); + $(addStepSel + ' #add-step-btn').prop('disabled', false); + } + + function removeStepUi() { + var index = $(removeStepSel).index(this) + 1; + // If last step is removed. + if(sequencer.steps.length==index+1){ + console.log("inside") + insertPreview.updatePreviews(sequencer.steps[index-1].output.src, document.querySelector('#addStep')); + } + sequencer.removeSteps(index).run({ index: index - 1 }); + // remove from URL hash too + urlHash.setUrlHashParameter('steps', sequencer.toString()); + //disable save-sequence button if all steps are removed + handleSaveSequence(); + } + + function addStepUi() { + if ($(addStepSel + ' select').val() == 'none') return; + var newStepName; + if(typeof arguments[0] !== 'string') + newStepName = $(addStepSel + ' select option').html().toLowerCase().split(' ').join('-'); + else newStepName = arguments[0]; + + + /* + * after adding the step we run the sequencer from defined step + * and since loadImage is not a part of the drawarray the step lies at current + * length - 2 of the drawarray + */ + var sequenceLength = 1; + if (sequencer.sequences[newStepName]) { + sequenceLength = sequencer.sequences[newStepName].length; + } else if (sequencer.modules[newStepName][1]['length']) { + sequenceLength = sequencer.modules[newStepName][1]['length']; + } + _sequencer + .addSteps(newStepName, options) + .run({ index: _sequencer.steps.length - sequenceLength - 1 }); + $(addStepSel + ' .info').html('Select a new module to add to your sequence.'); + $(addStepSel + ' select').val('none'); + + //enable save-sequence button if disabled initially + handleSaveSequence(); + + // add to URL hash too + urlHash.setUrlHashParameter('steps', _sequencer.toString()); + } + + function handleSaveSequence(){ + var stepCount = sequencer.steps.length; + if(stepCount < 2) + $(' #save-seq').prop('disabled', true); + else + $(' #save-seq').prop('disabled', false); + } + + return { + onLoad: onLoad, + importStepsFromUrlHash: importStepsFromUrlHash, + selectNewStepUi: selectNewStepUi, + removeStepUi: removeStepUi, + addStepUi: addStepUi + }; +} + +module.exports = DefaultHtmlSequencerUi; + + +},{"./insertPreview.js":5,"./urlHash.js":9}],4:[function(require,module,exports){ +// Set the UI in sequencer. This Will generate HTML based on +// Image Sequencer events : +// onSetup : Called every time a step is added +// onDraw : Called every time a step starts draw +// onComplete : Called every time a step finishes drawing +// onRemove : Called everytime a step is removed +// The variable 'step' stores useful data like input and +// output values, step information. +// See documetation for more details. + +const intermediateHtmlStepUi = require('./intermediateHtmlStepUi.js'), + urlHash = require('./urlHash.js'), + _ = require('lodash'), + insertPreview = require('./insertPreview.js'); + mapHtmlTypes = require('./mapHtmltypes'), + scopeQuery = require('./scopeQuery'), + isGIF = require('../../src/util/isGif'); + +function DefaultHtmlStepUi(_sequencer, options) { + options = options || {}; + var stepsEl = options.stepsEl || document.querySelector('#steps'); + var selectStepSel = options.selectStepSel = options.selectStepSel || '#selectStep'; + + function onSetup(step, stepOptions) { + if (step.options && step.options.description) + step.description = step.options.description; + + step.ui = // Basic UI markup for the step + '\ +
\ +
\ +
\ +
\ + \ + \ +
\ +

' + + '' + step.name + ' \ + \ +

\ +
\ +
\ +
\ +
\ +
\ + \ +
\ +
\ + \ +
\ + \ +
\ +
\ +
\ +
\ + \ +
\ +
\ +
'; + + var tools = + '
\ + \ +
'; + + var util = intermediateHtmlStepUi(_sequencer, step); + + var parser = new DOMParser(); + step.ui = parser.parseFromString(step.ui, 'text/html'); // Convert the markup string to a DOM node. + step.ui = step.ui.querySelector('div.container-fluid'); + + step.$step = scopeQuery.scopeSelector(step.ui); // Shorthand methods for scoped DOM queries. Read the docs [CONTRIBUTING.md](https://github.com/publiclab/image-sequencer/blob/main/CONTRIBUTING.md) for more info. + step.$stepAll = scopeQuery.scopeSelectorAll(step.ui); + let {$step, $stepAll} = step; + + step.linkElements = step.ui.querySelectorAll('a'); // All the anchor tags in the step UI + step.imgElement = $step('a img.img-thumbnail')[0]; // The output image + + if (_sequencer.modulesInfo().hasOwnProperty(step.name)) { + var inputs = _sequencer.modulesInfo(step.name).inputs; + var outputs = _sequencer.modulesInfo(step.name).outputs; + var merged = Object.assign(inputs, outputs); // Combine outputs with inputs + + for (var paramName in merged) { + var isInput = inputs.hasOwnProperty(paramName); + var html = ''; + var inputDesc = isInput ? mapHtmlTypes(inputs[paramName]) : {}; + if (!isInput) { + html += ''; + } + else if (inputDesc.type.toLowerCase() == 'select') { + + html += ''; + } + else { + let paramVal = step.options[paramName] || inputDesc.default; + + if (inputDesc.id == 'color-picker') { // Separate input field for color-picker + html += + '
' + + '' + '' + + '
'; + } + else { // Non color-picker input types + html = + '' + '' + paramVal + ''; + + } + else html += '">'; + } + } + + var div = document.createElement('div'); + div.className = 'row'; + div.setAttribute('name', paramName); + var description = inputs[paramName].desc || paramName; + div.innerHTML = + '
\ + \ + ' + + html + + '\ +
'; + $step('div.details').append(div); + } + $step('div.panel-footer').append( // Save button + '
Press apply to see changes
' + ); + $step('div.panel-footer').prepend( // Markup for tools: download and insert step buttons + '\ + ' + ); + } + + if (step.name != 'load-image') { + $step('div.trash-container') + .prepend( + parser.parseFromString(tools, 'text/html').querySelector('div') + ); + + $stepAll('.remove').on('click', function() {notify('Step Removed', 'remove-notification');}); // Notification on removal of a step + $step('.insert-step').on('click', function() { util.insertStep(step.ID); }); // Insert a step in between the sequence + // Insert the step's UI in the right place + + if (stepOptions.index == _sequencer.steps.length) { + stepsEl.appendChild(step.ui); + $('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true); + if($('#steps .step-container:nth-last-child(2)')) + $('#steps .step-container:nth-last-child(2) .insert-step').prop('disabled', false); + } + else { + stepsEl.insertBefore(step.ui, $(stepsEl).children()[stepOptions.index]); + } + + // Enable the load-image insert-step button when there are steps after load-image + // The logical operator is `> 0` because the number of steps is found before adding the step, actual logic is `steps.length + 1 > 1` which is later simplified. + if (_sequencer.steps.length > 0) $('#load-image .insert-step').prop('disabled', false); + else $('#load-image .insert-step').prop('disabled', true); + } + else { + $('#load-image').append(step.ui); // Default UI without extra tools for the first step(load image) + + $step('div.panel-footer').prepend( ` + ` + ); + + $step('.insert-step').on('click', function() { util.insertStep(step.ID); }); + } + $step('.toggle').on('click', () => { // Step container dropdown + $step('.toggleIcon').toggleClass('rotated'); + $stepAll('.cal').collapse('toggle'); + }); + + $(step.imgElement).on('mousemove', _.debounce(() => imageHover(step), 150)); // Shows the pixel coordinates on hover + $(step.imgElement).on('click', (e) => {e.preventDefault(); }); + $stepAll('#color-picker').colorpicker(); + + function saveOptions(e) { // 1. SAVE OPTIONS + e.preventDefault(); + if (optionsChanged){ + $step('div.details') + .find('input,select') + .each(function(i, input) { + $(input) + .data('initValue', $(input).val()) + .data('hasChangedBefore', false); + step.options[$(input).attr('name')] = $(input).val(); + }); + _sequencer.run({ index: step.index - 1 }); + + // Modify the URL hash + urlHash.setUrlHashParameter('steps', _sequencer.toString()); + // Disable the save button + $step('.btn-save').prop('disabled', true); + optionsChanged = false; + changedInputs = 0; + } + } + + /** + * @method handleInputValueChange + * @description Enables the save button on input change + * @param {*} currentValue The current value of the input + * @param {*} initValue The initial/old value of the input + * @param {Boolean} hasChangedBefore Whether the input was changed before + * @returns {Boolean} True if the value has changed + */ + function handleInputValueChange(currentValue, initValue, hasChangedBefore) { + var inputChanged = !(isNaN(initValue) || isNaN(currentValue) ? currentValue === initValue : currentValue - initValue === 0); + changedInputs += hasChangedBefore ? inputChanged ? 0 : -1 : inputChanged ? 1 : 0; + optionsChanged = changedInputs > 0; + + $step('.btn-save').prop('disabled', !optionsChanged); + return inputChanged; + } + + var + changedInputs = 0, + optionsChanged = false; + $step('.input-form').on('submit', saveOptions); + $stepAll('.target').each(function(i, input) { + $(input) + .data('initValue', $(input).val()) + .data('hasChangedBefore', false) + .on('input change', function() { + $(this) + .focus() + .data('hasChangedBefore', + handleInputValueChange( + $(this).val(), + $(this).data('initValue'), + $(this).data('hasChangedBefore') + ) + ); + }); + }); + + $stepAll('.color-picker-target').each(function(i, input) { + $(input) + .data('initValue', $(input).val()) + .data('hasChangedBefore', false) + .on('input change', function() { + $(this) + .data('hasChangedBefore', + handleInputValueChange( + $(this).val(), + $(this).data('initValue'), + $(this).data('hasChangedBefore') + ) + ); + }); + }); + + + $('input[type="range"]').on('input', function() { + $(this).next().html($(this).val()); + }); + } + + + function onDraw({$step, $stepAll}) { + $step('.load').show(); + $step('img').hide(); + $stepAll('.load-spin').show(); + } + + function onComplete(step) { + let {$step, $stepAll} = step; + $step('img').show(); + $stepAll('.load-spin').hide(); + $step('.load').hide(); + + $stepAll('.download-btn').off('click'); + + step.imgElement.src = (step.name == 'load-image') ? step.output.src : step.output; + var imgthumbnail = $step('.img-thumbnail').getDomElem(); + for (let index = 0; index < step.linkElements.length; index++) { + if (step.linkElements[index].contains(imgthumbnail)) + step.linkElements[index].href = step.imgElement.src; + } + + // TODO: use a generalized version of this. + function fileExtension(output) { + return output.split('/')[1].split(';')[0]; + } + + $stepAll('.download-btn').on('click', () => { + + var element = document.createElement('a'); + element.setAttribute('href', step.output); + element.setAttribute('download', step.name + '.' + fileExtension(step.imgElement.src)); + element.style.display = 'none'; + document.body.appendChild(element); + + element.click(); + }); + + // Fill inputs with stored step options + if (_sequencer.modulesInfo().hasOwnProperty(step.name)) { + var inputs = _sequencer.modulesInfo(step.name).inputs; + var outputs = _sequencer.modulesInfo(step.name).outputs; + for (var i in inputs) { + if (step.options[i] !== undefined) { + if (inputs[i].type.toLowerCase() === 'input') + $step('div[name="' + i + '"] input') + .val(step.options[i]) + .data('initValue', step.options[i]); + if (inputs[i].type.toLowerCase() === 'select') + $step('div[name="' + i + '"] select') + .val(String(step.options[i])) + .data('initValue', step.options[i]); + } + } + for (var i in outputs) { + if (step[i] !== undefined) + $step('div[name="' + i + '"] input') + .val(step[i]); + } + } + + $(function () { + $('[data-toggle="tooltip"]').tooltip(); + updateDimensions(step); + }); + + if (step.name === 'load-image') insertPreview.updatePreviews(step.output.src, document.querySelector('#addStep')); + else insertPreview.updatePreviews(step.output, document.querySelector('#addStep')); + + // Handle the wasm bolt display + + if (step.useWasm) { + if (step.wasmSuccess) $step('.wasm-tooltip').fadeIn(); + else $step('.wasm-tooltip').fadeOut(); + } + else $step('.wasm-tooltip').fadeOut(); + } + /** + * @description Updates Dimension of the image + * @param {Object} step - Current Step + * @returns {void} + * + */ + function updateDimensions(step){ + _sequencer.getImageDimensions(step.imgElement.src, function (dim) { + step.ui.querySelector('.' + step.name).attributes['data-original-title'].value = `

Image Width: ${dim.width}
Image Height: ${dim.height}
${isGIF(step.output) ? `Frames: ${dim.frames}` : ''}

`; + }); + } + + /** + * @method imageHover + * @description Handler to display image coordinates on hover. + * @param {Object} step Current step variable + * @returns {Null} + */ + function imageHover(step){ + + var img = $(step.imgElement); + + img.mousemove(function(e) { + var canvas = document.createElement('canvas'); + canvas.width = img.width(); + canvas.height = img.height(); + var context = canvas.getContext('2d'); + context.drawImage(this, 0, 0); + + var offset = $(this).offset(); + var xPos = e.pageX - offset.left; + var yPos = e.pageY - offset.top; + var myData = context.getImageData(xPos, yPos, 1, 1); + img[0].title = 'rgb: ' + myData.data[0] + ',' + myData.data[1] + ',' + myData.data[2];//+ rgbdata; + }); + } + + function onRemove(step) { + step.ui.remove(); + $('#steps .step-container:nth-last-child(1) .insert-step').prop('disabled', true); + + // Enable the load-image insert-step button when there are steps after load-image + // The logical operator is `> 2` because the number of steps is found before removing the step, actual logic is `steps.length - 1 > 1` which is later simplified. + if (_sequencer.steps.length - 1 > 1) $('#load-image .insert-step').prop('disabled', false); + else $('#load-image .insert-step').prop('disabled', true); + + $(step.imgElement).imgAreaSelect({ + remove: true + }); + } + + function getPreview() { + return step.imgElement; + } + + /** + * @method notify + * @description General purpose DOM toast notification + * @param {String} msg Message to be displayed + * @param {String} id A unique identifier for the notification + * @returns {Null} + */ + function notify(msg, id){ + if ($('#' + id).length == 0) { + var notification = document.createElement('span'); + notification.innerHTML = ' ' + msg ; + notification.id = id; + notification.classList.add('notification'); + + $('body').append(notification); + } + + $('#' + id).fadeIn(500).delay(200).fadeOut(500); + } + + + return { + getPreview: getPreview, + onSetup: onSetup, + onComplete: onComplete, + onRemove: onRemove, + onDraw: onDraw, + notify: notify, + imageHover: imageHover, + updateDimensions: updateDimensions + }; +} + +if(typeof window === 'undefined'){ + module.exports = { + DefaultHtmlStepUi: DefaultHtmlStepUi + }; +} + +module.exports = DefaultHtmlStepUi; + +},{"../../src/util/isGif":171,"./insertPreview.js":5,"./intermediateHtmlStepUi.js":6,"./mapHtmltypes":7,"./scopeQuery":8,"./urlHash.js":9,"lodash":167}],5:[function(require,module,exports){ +// Generate downscaled preview images for quick buttons. +function generatePreview(previewStepName, customValues, path, DomNode) { + var previewSequencer = ImageSequencer(); + function insertPreview(src) { + var img = document.createElement('img'); + img.classList.add('img-thumbnail'); + img.classList.add('no-border'); + img.src = src; + $(img).css('max-width', '200%'); + $(img).css('transform', 'translateX(-20%)'); + $(DomNode.querySelector('.radio-group')).find('.radio').each(function() { + if ($(this).attr('data-value') === previewStepName) { + $(this).find('img').remove(); + $(this).append(img); + } + }); + } + + function loadPreview() { + if (previewStepName === 'crop') { + previewSequencer.addSteps(previewStepName, customValues).run(insertPreview); + } + else { + previewSequencer.addSteps(previewStepName, { [previewStepName]: customValues }).run(insertPreview); + } + } + if(previewStepName === 'resize') + insertPreview(path); + else + previewSequencer.loadImage(path, loadPreview); +} + +function updatePreviews(src, DomNode) { + $(DomNode).find('img').remove(); + + var previewSequencerSteps = { + 'resize': '125%', + 'brightness': '175', + 'saturation': '0.5', + 'rotate': 90, + 'contrast': 90, + 'crop': { + 'x': 0, + 'y': 0, + 'w': '50%', + 'h': '50%', + 'noUI': true + } + }; + + var img = new Image(); + + img.onload = function(){ + var height = img.height; + var width = img.width; + + let percentage = (80 / height) * 100; // Take the min resize value that fits the preview area => (new-width/orig_ht) - '80 as the preview area has 80*80 dimension. + percentage = Math.max((80 / width) * 100, percentage); // Make sure that one dimension doesn't resize greater, leading distorting preview-area fitting. + percentage = Math.ceil(percentage); + + var sequencer = ImageSequencer(); + + sequencer.loadImage(src, function(){ + this.addSteps('resize', {['resize']: percentage + '%'}); + this.run((src)=>{ + Object.keys(previewSequencerSteps).forEach(function (step, index) { + generatePreview(step, Object.values(previewSequencerSteps)[index], src, DomNode); + }); + }); + }); + }; + img.src = src; +} + + +module.exports = { + generatePreview : generatePreview, + updatePreviews : updatePreviews +}; +},{}],6:[function(require,module,exports){ +var urlHash = require('./urlHash.js'), + insertPreview = require('./insertPreview.js'); + +/** + * @method IntermediateHtmlStepUi + * @description Inserts a module selector in between the current sequence + * @param {Object} _sequencer Sequencer instance + * @param {Object} step Current step variable + * @param {Object} options Optional options Object + * @returns {Object} Object containing the insertStep function + */ +function IntermediateHtmlStepUi(_sequencer, step, options) { + function stepUI() { + // Basic markup for the selector + return '
\ +
\ + \ +
\ +
\ +

Select a new module to add to your sequence.

\ +
\ +
\ +
\ + \ +
\ +

Resize

\ +
\ +
\ +
\ + \ +
\ +

Brightness

\ +
\ +
\ +
\ + \ +
\ +

Contrast

\ +
\ +
\ +
\ + \ +
\ +

Saturation

\ +
\ +
\ +
\ + \ +
\ +

Rotate

\ +
\ +
\ +
\ + \ +
\ +

Crop

\ +
\ +
\ +
\ +
\ + \ +
\ +
\ + \ +
\ +
\ +
\ +
\ +
\ +
'; + } + + /** + * @method toggleDiv + * @description Toggles the module selector dropdown. + * @param {Object} $step $step util function + * @param {Fucntion} callback Optional callback function + * @returns {Null} + */ + var toggleDiv = function($step, callback = function(){}){ + $step('.insertDiv').collapse('toggle'); + if ($step('.insert-text').css('display') != 'none'){ + $step('.insert-text').fadeToggle(200, function(){$step('.no-insert-text').fadeToggle(200, callback);}); + } + else { + $step('.no-insert-text').fadeToggle(200, function(){$step('.insert-text').fadeToggle(200, callback);}); + } + }; + + /** + * @method insertStep + * @description Handler to insert selected module in the sequence + * @returns {Null} + */ + insertStep = function (id) { + const $step = step.$step, + $stepAll = step.$stepAll; + var modulesInfo = _sequencer.modulesInfo(); + var parser = new DOMParser(); + var addStepUI = stepUI(); + addStepUI = parser.parseFromString(addStepUI, 'text/html').querySelector('div'); + + if ($step('.insertDiv').length > 0){ + toggleDiv($step); + } + else { + step.ui + .querySelector('div.step') + .insertAdjacentElement('afterend', + addStepUI + ); + toggleDiv($step, function(){ + if (step.name === 'load-image') insertPreview.updatePreviews(step.output.src, $step('.insertDiv').getDomElem()); + else insertPreview.updatePreviews(step.output, $step('.insertDiv').getDomElem()); + }); + } + + + $step('.insertDiv .close-insert-box').off('click').on('click', function(){ + toggleDiv($step); + $step('.insertDiv').removeClass('insertDiv'); + }); + + var insertStepSelect = $step('.insert-step-select'); + insertStepSelect.html(''); + + // Add modules to the insertStep dropdown + for (var m in modulesInfo) { + if (modulesInfo[m] && modulesInfo[m].name) + insertStepSelect.append( + '' + ); + } + + insertStepSelect.selectize({ + sortField: 'text' + }); + + $('.insertDiv .radio-group .radio').on('click', function () { + var newStepName = $(this).attr('data-value'); // Get the name of the module to be inserted + id = $($step('.insertDiv').parents()[3]).prevAll().length; + insert(id, $step, newStepName); // Insert the selected module + }); + + $step('.insertDiv .add-step-btn').on('click', function () { + var newStepName = insertStepSelect.val(); + id = $($step('.insertDiv').parents()[3]).prevAll().length; + insert(id, $step, newStepName); }); + }; + + /** + * @method insert + * @description Inserts the specified step at the specified index in the sequence + * @param {Number} id Index of the step + * @param {Function} $step $step util function + * @param {String} newStepName Name of the new step + */ + function insert(id, $step, newStepName) { + toggleDiv($step); + $step('.insertDiv').removeClass('insertDiv'); + _sequencer.insertSteps(id + 1, newStepName).run({ index: id }); + urlHash.setUrlHashParameter('steps', _sequencer.toString()); + } + + return { + insertStep + }; +} +module.exports = IntermediateHtmlStepUi; + +},{"./insertPreview.js":5,"./urlHash.js":9}],7:[function(require,module,exports){ +/** + * @description Maps module input types to their respective html tag types. + * @param {Object} inputInfo Object containing the type and optionally min/max for range type inputs. + */ +function mapHtmlTypes(inputInfo){ + var htmlType; + switch(inputInfo.type.toLowerCase()){ + case 'integer': + htmlType = inputInfo.min != undefined ? 'range' : 'number'; + break; + case 'string': + htmlType = 'text'; + break; + case 'select': + htmlType = 'select'; + break; + case 'percentage': + htmlType = 'number'; + break; + case 'float': + htmlType = inputInfo.min != undefined ? 'range' : 'text'; + break; + default: + htmlType = 'text'; + break; + } + var response = Object.assign({}, inputInfo); + response.type = htmlType; + return response; +} + +module.exports = mapHtmlTypes; +},{}],8:[function(require,module,exports){ +/** + * @method $scope + * @param {"DOMNode"} scope A DOM Node as the scope + * @returns {Function} Constructor for the scopeSelector Object. + */ +function $scope(scope) { + return function(queryString){ + var element = $(scope.querySelector(queryString)); + + element.elem = function(queryString){ + return new $scope(scope)(queryString); + }; + element.elemAll = function(queryString){ + return new $scopeAll(scope)(queryString); + }; + element.getDomElem = function(i = 0){ + return element[i]; + }; + element.getScope = () => scope; + + return element; + }; +} + +/** + * @method $scopeAll + * @param {"DOMNode"} scope A DOM Node as the scope + * @returns {Function} Constructor for the scopeSelectorAll Object. + */ +function $scopeAll(scope){ + return function(queryString){ + var element = $(scope.querySelectorAll(queryString)); + + element.elem = function(queryString){ + return new $scope(scope)(queryString); + }; + element.elemAll = function(queryString){ + return new $scopeAll(scope)(queryString); + }; + element.getDomElem = function(i = 0){ + return element[i]; + }; + element.getScope = () => scope; + + return element; + }; +} + +/** + * @method scopeSelector + * @description A scoped jQuery selector + * @param {"DOMNode"} scope A DOM Node as the scope + * @returns {Function} + */ +function scopeSelector(scope){ + return $scope(scope); +} + +/** + * @method scopeSelectorAll + * @description A scoped jQuery multiple selector + * @param {"DOMNode} scope A DOM Node as the scope + * @returns {Function} + */ +function scopeSelectorAll(scope){ + return $scopeAll(scope); +} + +module.exports = { + scopeSelector, + scopeSelectorAll +}; +},{}],9:[function(require,module,exports){ +function getUrlHashParameter(param) { + + var params = getUrlHashParameters(); + return params[param]; + +} + +function getUrlHashParameters() { + + var sPageURL = window.location.hash; + if (sPageURL) sPageURL = sPageURL.split('#')[1]; + var pairs = sPageURL.split('&'); + var object = {}; + pairs.forEach(function(pair, i) { + pair = pair.split('='); + if (pair[0] != '') object[pair[0]] = pair[1]; + }); + return object; +} + +// accepts an object like { paramName: value, paramName1: value } +// and transforms to: url.com#paramName=value¶mName1=value +function setUrlHashParameters(params) { + + var keys = Object.keys(params); + var values = Object.values(params); + var pairs = []; + keys.forEach(function(key, i) { + if (key != '') pairs.push(keys[i] + '=' + values[i]); + }); + var hash = pairs.join('&'); + window.location.hash = hash; + +} + +function setUrlHashParameter(param, value) { + + var params = getUrlHashParameters(); + params[param] = value; + setUrlHashParameters(params); + +} + +module.exports = { + getUrlHashParameter: getUrlHashParameter, + setUrlHashParameter: setUrlHashParameter, + getUrlHashParameters: getUrlHashParameters, + setUrlHashParameters: setUrlHashParameters +}; + +},{}],10:[function(require,module,exports){ +/** + * Functions for getting version information. + * Note: these functions are not used by the service worker to check for updates; + * the service worker updates whenever sw.js has changed. + * sw.js is changed when grunt replace:version is run. This task is run during + * grunt build, serve, and productions tasks. + */ + +const package = require('../../package.json'); + +/** + * Get the current version number from package.json on the homepage. + * @param {function} callback The function that uses the version number. + */ +function getLatestVersionNumber(callback) { + // Get the homepage reference from the local package.json. + var homepage = package.homepage; + var request = new XMLHttpRequest(); + request.onreadystatechange = function() { + if (request.readyState == 4 && request.status == 200) { + var response = JSON.parse(this.responseText); + var latestVersionNumber = response.version; + + // Do something with the version number using a callback function. + if (callback) + callback(latestVersionNumber); + } + } + + // Get the package.json file from online using a GET request. + request.open("GET", homepage + "/package.json", true); + request.send(); +} + +// Get the version number from the local package.json file. +function getLocalVersionNumber() { + return package.version; +} + +module.exports = { + getLatestVersionNumber, + getLocalVersionNumber +} + +},{"../../package.json":170}],11:[function(require,module,exports){ +'use strict' + +exports.byteLength = byteLength +exports.toByteArray = toByteArray +exports.fromByteArray = fromByteArray + +var lookup = [] +var revLookup = [] +var Arr = typeof Uint8Array !== 'undefined' ? Uint8Array : Array + +var code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' +for (var i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i] + revLookup[code.charCodeAt(i)] = i +} + +// Support decoding URL-safe base64 strings, as Node.js does. +// See: https://en.wikipedia.org/wiki/Base64#URL_applications +revLookup['-'.charCodeAt(0)] = 62 +revLookup['_'.charCodeAt(0)] = 63 + +function getLens (b64) { + var len = b64.length + + if (len % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // Trim off extra bytes after placeholder bytes are found + // See: https://github.com/beatgammit/base64-js/issues/42 + var validLen = b64.indexOf('=') + if (validLen === -1) validLen = len + + var placeHoldersLen = validLen === len + ? 0 + : 4 - (validLen % 4) + + return [validLen, placeHoldersLen] +} + +// base64 is 4/3 + up to two characters of the original data +function byteLength (b64) { + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} + +function _byteLength (b64, validLen, placeHoldersLen) { + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} + +function toByteArray (b64) { + var tmp + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + + var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) + + var curByte = 0 + + // if there are placeholders, only get up to the last complete 4 chars + var len = placeHoldersLen > 0 + ? validLen - 4 + : validLen + + for (var i = 0; i < len; i += 4) { + tmp = + (revLookup[b64.charCodeAt(i)] << 18) | + (revLookup[b64.charCodeAt(i + 1)] << 12) | + (revLookup[b64.charCodeAt(i + 2)] << 6) | + revLookup[b64.charCodeAt(i + 3)] + arr[curByte++] = (tmp >> 16) & 0xFF + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF + } + + if (placeHoldersLen === 2) { + tmp = + (revLookup[b64.charCodeAt(i)] << 2) | + (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[curByte++] = tmp & 0xFF + } + + if (placeHoldersLen === 1) { + tmp = + (revLookup[b64.charCodeAt(i)] << 10) | + (revLookup[b64.charCodeAt(i + 1)] << 4) | + (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF + } + + return arr +} + +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + + lookup[num >> 12 & 0x3F] + + lookup[num >> 6 & 0x3F] + + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = + ((uint8[i] << 16) & 0xFF0000) + + ((uint8[i + 1] << 8) & 0xFF00) + + (uint8[i + 2] & 0xFF) + output.push(tripletToBase64(tmp)) + } + return output.join('') +} + +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk( + uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength) + )) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + parts.push( + lookup[tmp >> 2] + + lookup[(tmp << 4) & 0x3F] + + '==' + ) + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + uint8[len - 1] + parts.push( + lookup[tmp >> 10] + + lookup[(tmp >> 4) & 0x3F] + + lookup[(tmp << 2) & 0x3F] + + '=' + ) + } + + return parts.join('') +} + +},{}],12:[function(require,module,exports){ +(function (process,__filename){ +/** + * Module dependencies. + */ + +var fs = require('fs'), + path = require('path'), + fileURLToPath = require('file-uri-to-path'), + join = path.join, + dirname = path.dirname, + exists = + (fs.accessSync && + function(path) { + try { + fs.accessSync(path); + } catch (e) { + return false; + } + return true; + }) || + fs.existsSync || + path.existsSync, + defaults = { + arrow: process.env.NODE_BINDINGS_ARROW || ' → ', + compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled', + platform: process.platform, + arch: process.arch, + nodePreGyp: + 'node-v' + + process.versions.modules + + '-' + + process.platform + + '-' + + process.arch, + version: process.versions.node, + bindings: 'bindings.node', + try: [ + // node-gyp's linked version in the "build" dir + ['module_root', 'build', 'bindings'], + // node-waf and gyp_addon (a.k.a node-gyp) + ['module_root', 'build', 'Debug', 'bindings'], + ['module_root', 'build', 'Release', 'bindings'], + // Debug files, for development (legacy behavior, remove for node v0.9) + ['module_root', 'out', 'Debug', 'bindings'], + ['module_root', 'Debug', 'bindings'], + // Release files, but manually compiled (legacy behavior, remove for node v0.9) + ['module_root', 'out', 'Release', 'bindings'], + ['module_root', 'Release', 'bindings'], + // Legacy from node-waf, node <= 0.4.x + ['module_root', 'build', 'default', 'bindings'], + // Production "Release" buildtype binary (meh...) + ['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings'], + // node-qbs builds + ['module_root', 'addon-build', 'release', 'install-root', 'bindings'], + ['module_root', 'addon-build', 'debug', 'install-root', 'bindings'], + ['module_root', 'addon-build', 'default', 'install-root', 'bindings'], + // node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch} + ['module_root', 'lib', 'binding', 'nodePreGyp', 'bindings'] + ] + }; + +/** + * The main `bindings()` function loads the compiled bindings for a given module. + * It uses V8's Error API to determine the parent filename that this function is + * being invoked from, which is then used to find the root directory. + */ + +function bindings(opts) { + // Argument surgery + if (typeof opts == 'string') { + opts = { bindings: opts }; + } else if (!opts) { + opts = {}; + } + + // maps `defaults` onto `opts` object + Object.keys(defaults).map(function(i) { + if (!(i in opts)) opts[i] = defaults[i]; + }); + + // Get the module root + if (!opts.module_root) { + opts.module_root = exports.getRoot(exports.getFileName()); + } + + // Ensure the given bindings name ends with .node + if (path.extname(opts.bindings) != '.node') { + opts.bindings += '.node'; + } + + // https://github.com/webpack/webpack/issues/4175#issuecomment-342931035 + var requireFunc = + typeof __webpack_require__ === 'function' + ? __non_webpack_require__ + : require; + + var tries = [], + i = 0, + l = opts.try.length, + n, + b, + err; + + for (; i < l; i++) { + n = join.apply( + null, + opts.try[i].map(function(p) { + return opts[p] || p; + }) + ); + tries.push(n); + try { + b = opts.path ? requireFunc.resolve(n) : requireFunc(n); + if (!opts.path) { + b.path = n; + } + return b; + } catch (e) { + if (e.code !== 'MODULE_NOT_FOUND' && + e.code !== 'QUALIFIED_PATH_RESOLUTION_FAILED' && + !/not find/i.test(e.message)) { + throw e; + } + } + } + + err = new Error( + 'Could not locate the bindings file. Tried:\n' + + tries + .map(function(a) { + return opts.arrow + a; + }) + .join('\n') + ); + err.tries = tries; + throw err; +} +module.exports = exports = bindings; + +/** + * Gets the filename of the JavaScript file that invokes this function. + * Used to help find the root directory of a module. + * Optionally accepts an filename argument to skip when searching for the invoking filename + */ + +exports.getFileName = function getFileName(calling_file) { + var origPST = Error.prepareStackTrace, + origSTL = Error.stackTraceLimit, + dummy = {}, + fileName; + + Error.stackTraceLimit = 10; + + Error.prepareStackTrace = function(e, st) { + for (var i = 0, l = st.length; i < l; i++) { + fileName = st[i].getFileName(); + if (fileName !== __filename) { + if (calling_file) { + if (fileName !== calling_file) { + return; + } + } else { + return; + } + } + } + }; + + // run the 'prepareStackTrace' function above + Error.captureStackTrace(dummy); + dummy.stack; + + // cleanup + Error.prepareStackTrace = origPST; + Error.stackTraceLimit = origSTL; + + // handle filename that starts with "file://" + var fileSchema = 'file://'; + if (fileName.indexOf(fileSchema) === 0) { + fileName = fileURLToPath(fileName); + } + + return fileName; +}; + +/** + * Gets the root directory of a module, given an arbitrary filename + * somewhere in the module tree. The "root directory" is the directory + * containing the `package.json` file. + * + * In: /home/nate/node-native-module/lib/index.js + * Out: /home/nate/node-native-module + */ + +exports.getRoot = function getRoot(file) { + var dir = dirname(file), + prev; + while (true) { + if (dir === '.') { + // Avoids an infinite loop in rare cases, like the REPL + dir = process.cwd(); + } + if ( + exists(join(dir, 'package.json')) || + exists(join(dir, 'node_modules')) + ) { + // Found the 'package.json' file or 'node_modules' dir; we're done + return dir; + } + if (prev === dir) { + // Got to the top + throw new Error( + 'Could not find module root given file: "' + + file + + '". Do you have a `package.json` file? ' + ); + } + // Try the parent dir next + prev = dir; + dir = join(dir, '..'); + } +}; + +}).call(this,require('_process'),"/node_modules/bindings/bindings.js") +},{"_process":169,"file-uri-to-path":14,"fs":164,"path":168}],13:[function(require,module,exports){ +/** + * Bit twiddling hacks for JavaScript. + * + * Author: Mikola Lysenko + * + * Ported from Stanford bit twiddling hack library: + * http://graphics.stanford.edu/~seander/bithacks.html + */ + +"use strict"; "use restrict"; + +//Number of bits in an integer +var INT_BITS = 32; + +//Constants +exports.INT_BITS = INT_BITS; +exports.INT_MAX = 0x7fffffff; +exports.INT_MIN = -1<<(INT_BITS-1); + +//Returns -1, 0, +1 depending on sign of x +exports.sign = function(v) { + return (v > 0) - (v < 0); +} + +//Computes absolute value of integer +exports.abs = function(v) { + var mask = v >> (INT_BITS-1); + return (v ^ mask) - mask; +} + +//Computes minimum of integers x and y +exports.min = function(x, y) { + return y ^ ((x ^ y) & -(x < y)); +} + +//Computes maximum of integers x and y +exports.max = function(x, y) { + return x ^ ((x ^ y) & -(x < y)); +} + +//Checks if a number is a power of two +exports.isPow2 = function(v) { + return !(v & (v-1)) && (!!v); +} + +//Computes log base 2 of v +exports.log2 = function(v) { + var r, shift; + r = (v > 0xFFFF) << 4; v >>>= r; + shift = (v > 0xFF ) << 3; v >>>= shift; r |= shift; + shift = (v > 0xF ) << 2; v >>>= shift; r |= shift; + shift = (v > 0x3 ) << 1; v >>>= shift; r |= shift; + return r | (v >> 1); +} + +//Computes log base 10 of v +exports.log10 = function(v) { + return (v >= 1000000000) ? 9 : (v >= 100000000) ? 8 : (v >= 10000000) ? 7 : + (v >= 1000000) ? 6 : (v >= 100000) ? 5 : (v >= 10000) ? 4 : + (v >= 1000) ? 3 : (v >= 100) ? 2 : (v >= 10) ? 1 : 0; +} + +//Counts number of bits +exports.popCount = function(v) { + v = v - ((v >>> 1) & 0x55555555); + v = (v & 0x33333333) + ((v >>> 2) & 0x33333333); + return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24; +} + +//Counts number of trailing zeros +function countTrailingZeros(v) { + var c = 32; + v &= -v; + if (v) c--; + if (v & 0x0000FFFF) c -= 16; + if (v & 0x00FF00FF) c -= 8; + if (v & 0x0F0F0F0F) c -= 4; + if (v & 0x33333333) c -= 2; + if (v & 0x55555555) c -= 1; + return c; +} +exports.countTrailingZeros = countTrailingZeros; + +//Rounds to next power of 2 +exports.nextPow2 = function(v) { + v += v === 0; + --v; + v |= v >>> 1; + v |= v >>> 2; + v |= v >>> 4; + v |= v >>> 8; + v |= v >>> 16; + return v + 1; +} + +//Rounds down to previous power of 2 +exports.prevPow2 = function(v) { + v |= v >>> 1; + v |= v >>> 2; + v |= v >>> 4; + v |= v >>> 8; + v |= v >>> 16; + return v - (v>>>1); +} + +//Computes parity of word +exports.parity = function(v) { + v ^= v >>> 16; + v ^= v >>> 8; + v ^= v >>> 4; + v &= 0xf; + return (0x6996 >>> v) & 1; +} + +var REVERSE_TABLE = new Array(256); + +(function(tab) { + for(var i=0; i<256; ++i) { + var v = i, r = i, s = 7; + for (v >>>= 1; v; v >>>= 1) { + r <<= 1; + r |= v & 1; + --s; + } + tab[i] = (r << s) & 0xff; + } +})(REVERSE_TABLE); + +//Reverse bits in a 32 bit word +exports.reverse = function(v) { + return (REVERSE_TABLE[ v & 0xff] << 24) | + (REVERSE_TABLE[(v >>> 8) & 0xff] << 16) | + (REVERSE_TABLE[(v >>> 16) & 0xff] << 8) | + REVERSE_TABLE[(v >>> 24) & 0xff]; +} + +//Interleave bits of 2 coordinates with 16 bits. Useful for fast quadtree codes +exports.interleave2 = function(x, y) { + x &= 0xFFFF; + x = (x | (x << 8)) & 0x00FF00FF; + x = (x | (x << 4)) & 0x0F0F0F0F; + x = (x | (x << 2)) & 0x33333333; + x = (x | (x << 1)) & 0x55555555; + + y &= 0xFFFF; + y = (y | (y << 8)) & 0x00FF00FF; + y = (y | (y << 4)) & 0x0F0F0F0F; + y = (y | (y << 2)) & 0x33333333; + y = (y | (y << 1)) & 0x55555555; + + return x | (y << 1); +} + +//Extracts the nth interleaved component +exports.deinterleave2 = function(v, n) { + v = (v >>> n) & 0x55555555; + v = (v | (v >>> 1)) & 0x33333333; + v = (v | (v >>> 2)) & 0x0F0F0F0F; + v = (v | (v >>> 4)) & 0x00FF00FF; + v = (v | (v >>> 16)) & 0x000FFFF; + return (v << 16) >> 16; +} + + +//Interleave bits of 3 coordinates, each with 10 bits. Useful for fast octree codes +exports.interleave3 = function(x, y, z) { + x &= 0x3FF; + x = (x | (x<<16)) & 4278190335; + x = (x | (x<<8)) & 251719695; + x = (x | (x<<4)) & 3272356035; + x = (x | (x<<2)) & 1227133513; + + y &= 0x3FF; + y = (y | (y<<16)) & 4278190335; + y = (y | (y<<8)) & 251719695; + y = (y | (y<<4)) & 3272356035; + y = (y | (y<<2)) & 1227133513; + x |= (y << 1); + + z &= 0x3FF; + z = (z | (z<<16)) & 4278190335; + z = (z | (z<<8)) & 251719695; + z = (z | (z<<4)) & 3272356035; + z = (z | (z<<2)) & 1227133513; + + return x | (z << 2); +} + +//Extracts nth interleaved component of a 3-tuple +exports.deinterleave3 = function(v, n) { + v = (v >>> n) & 1227133513; + v = (v | (v>>>2)) & 3272356035; + v = (v | (v>>>4)) & 251719695; + v = (v | (v>>>8)) & 4278190335; + v = (v | (v>>>16)) & 0x3FF; + return (v<<22)>>22; +} + +//Computes next combination in colexicographic order (this is mistakenly called nextPermutation on the bit twiddling hacks page) +exports.nextCombination = function(v) { + var t = v | (v - 1); + return (t + 1) | (((~t & -~t) - 1) >>> (countTrailingZeros(v) + 1)); +} + + +},{}],14:[function(require,module,exports){ + +/** + * Module dependencies. + */ + +var sep = require('path').sep || '/'; + +/** + * Module exports. + */ + +module.exports = fileUriToPath; + +/** + * File URI to Path function. + * + * @param {String} uri + * @return {String} path + * @api public + */ + +function fileUriToPath (uri) { + if ('string' != typeof uri || + uri.length <= 7 || + 'file://' != uri.substring(0, 7)) { + throw new TypeError('must pass in a file:// URI to convert to a file path'); + } + + var rest = decodeURI(uri.substring(7)); + var firstSlash = rest.indexOf('/'); + var host = rest.substring(0, firstSlash); + var path = rest.substring(firstSlash + 1); + + // 2. Scheme Definition + // As a special case, can be the string "localhost" or the empty + // string; this is interpreted as "the machine from which the URL is + // being interpreted". + if ('localhost' == host) host = ''; + + if (host) { + host = sep + sep + host; + } + + // 3.2 Drives, drive letters, mount points, file system root + // Drive letters are mapped into the top of a file URI in various ways, + // depending on the implementation; some applications substitute + // vertical bar ("|") for the colon after the drive letter, yielding + // "file:///c|/tmp/test.txt". In some cases, the colon is left + // unchanged, as in "file:///c:/tmp/test.txt". In other cases, the + // colon is simply omitted, as in "file:///c/tmp/test.txt". + path = path.replace(/^(.+)\|/, '$1:'); + + // for Windows, we need to invert the path separators from what a URI uses + if (sep == '\\') { + path = path.replace(/\//g, '\\'); + } + + if (/^.+\:/.test(path)) { + // has Windows drive at beginning of path + } else { + // unix path… + path = sep + path; + } + + return host + path; +} + +},{"path":168}],15:[function(require,module,exports){ +/** + * + * @param {WebGLRenderingContext} gl + * @param {IGLWiretapOptions} [options] + * @returns {GLWiretapProxy} + */ +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() { // need arguments from this, fyi + switch (property) { + case 'getError': + if (throwGetError) { + recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`); + } else { + recording.push(`${indent}${contextName}.getError();`); // flush out errors + } + 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; + } +} + +/** + * + * @param extension + * @param {IGLExtensionWiretapOptions} options + * @returns {*} + */ +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; + } +} + +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; + } +} + +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}`); + } +} + +function trackablePrimitive(value) { + // wrapped in object, so track-able + return new value.constructor(value); +} + +if (typeof module !== 'undefined') { + module.exports = { glWiretap, glExtensionWiretap }; +} + +if (typeof window !== 'undefined') { + glWiretap.glExtensionWiretap = glExtensionWiretap; + window.glWiretap = glWiretap; +} + +},{}],16:[function(require,module,exports){ +if (typeof WebGLRenderingContext !== 'undefined') { + module.exports = require('./src/javascript/browser-index') +} else { + module.exports = require('./src/javascript/node-index') +} + +},{"./src/javascript/browser-index":18,"./src/javascript/node-index":31}],17:[function(require,module,exports){ +module.exports={ + "_from": "gl@4.8.0", + "_id": "gl@4.8.0", + "_inBundle": false, + "_integrity": "sha512-aH73Ilq5cnfa9hF829UqWMjZBdYbIC7aNHYYpisZMN9QJttj8p/nyhxcJ1aGDTwjoL1keR3oN5nkNnAlNSuVcw==", + "_location": "/gl", + "_phantomChildren": { + "abbrev": "1.1.1", + "aws-sign2": "0.7.0", + "aws4": "1.8.0", + "caseless": "0.12.0", + "combined-stream": "1.0.7", + "env-paths": "2.2.0", + "extend": "3.0.2", + "fast-json-stable-stringify": "2.0.0", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "fs.realpath": "1.0.0", + "har-schema": "2.0.0", + "http-signature": "1.2.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "is-typedarray": "1.0.0", + "isexe": "2.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.20", + "minimatch": "3.0.4", + "npmlog": "4.1.2", + "oauth-sign": "0.9.0", + "once": "1.4.0", + "path-is-absolute": "1.0.1", + "performance-now": "2.1.0", + "psl": "1.1.29", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tunnel-agent": "0.6.0", + "uri-js": "4.2.2", + "uuid": "3.3.2" + }, + "_requested": { + "type": "version", + "registry": true, + "raw": "gl@4.8.0", + "name": "gl", + "escapedName": "gl", + "rawSpec": "4.8.0", + "saveSpec": null, + "fetchSpec": "4.8.0" + }, + "_requiredBy": [ + "/gpu.js" + ], + "_resolved": "https://registry.npmjs.org/gl/-/gl-4.8.0.tgz", + "_shasum": "2bf8702d11ae5a76412f3731f3ed652bd77d043b", + "_spec": "gl@4.8.0", + "_where": "/mnt/Data/.My_Projects/githubProjects/image-sequencer/node_modules/gpu.js", + "author": { + "name": "Mikola Lysenko" + }, + "browser": "browser_index.js", + "bugs": { + "url": "https://github.com/stackgl/headless-gl/issues" + }, + "bundleDependencies": false, + "dependencies": { + "bindings": "^1.5.0", + "bit-twiddle": "^1.0.2", + "glsl-tokenizer": "^2.0.2", + "nan": "^2.14.1", + "node-abi": "^2.18.0", + "node-gyp": "^7.1.0", + "prebuild-install": "^5.3.5" + }, + "deprecated": false, + "description": "Creates a WebGL context without a window", + "devDependencies": { + "angle-normals": "^1.0.0", + "bunny": "^1.0.1", + "faucet": "0.0.1", + "gl-conformance": "^2.0.9", + "prebuild": "^10.0.1", + "snazzy": "^8.0.0", + "standard": "^14.3.4", + "tape": "^5.0.1" + }, + "directories": { + "test": "test" + }, + "engines": { + "node": ">=8.0.0" + }, + "gypfile": true, + "homepage": "https://github.com/stackgl/headless-gl#readme", + "keywords": [ + "webgl", + "opengl", + "gl", + "headless", + "server", + "gpgpu" + ], + "license": "BSD-2-Clause", + "main": "index.js", + "name": "gl", + "repository": { + "type": "git", + "url": "git://github.com/stackgl/headless-gl.git" + }, + "scripts": { + "install": "prebuild-install || node-gyp rebuild", + "prebuild": "prebuild --all --strip", + "rebuild": "node-gyp rebuild --verbose", + "test": "standard | snazzy && tape test/*.js | faucet" + }, + "version": "4.8.0" +} + +},{}],18:[function(require,module,exports){ +function createContext (width, height, options) { + width = width | 0 + height = height | 0 + if (!(width > 0 && height > 0)) { + return null + } + + const canvas = document.createElement('canvas') + if (!canvas) { + return null + } + let gl + canvas.width = width + canvas.height = height + + try { + gl = canvas.getContext('webgl', options) + } catch (e) { + try { + gl = canvas.getContext('experimental-webgl', options) + } catch (e) { + return null + } + } + + const _getExtension = gl.getExtension + const extDestroy = { + destroy: function () { + const loseContext = _getExtension.call(gl, 'WEBGL_lose_context') + if (loseContext) { + loseContext.loseContext() + } + } + } + + const extResize = { + resize: function (w, h) { + canvas.width = w + canvas.height = h + } + } + + const _supportedExtensions = gl.getSupportedExtensions().slice() + _supportedExtensions.push( + 'STACKGL_destroy_context', + 'STACKGL_resize_drawingbuffer') + gl.getSupportedExtensions = function () { + return _supportedExtensions.slice() + } + + gl.getExtension = function (extName) { + const name = extName.toLowerCase() + if (name === 'stackgl_resize_drawingbuffer') { + return extResize + } + if (name === 'stackgl_destroy_context') { + return extDestroy + } + return _getExtension.call(gl, extName) + } + + return gl || null +} + +module.exports = createContext + +},{}],19:[function(require,module,exports){ +const { gl } = require('../native-gl') +const { vertexCount } = require('../utils') + +class ANGLEInstancedArrays { + constructor (ctx) { + this.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88fe + this.ctx = ctx + + this._drawArraysInstanced = gl._drawArraysInstanced.bind(ctx) + this._drawElementsInstanced = gl._drawElementsInstanced.bind(ctx) + this._vertexAttribDivisor = gl._vertexAttribDivisor.bind(ctx) + } + + drawArraysInstancedANGLE (mode, first, count, primCount) { + const { ctx } = this + mode |= 0 + first |= 0 + count |= 0 + primCount |= 0 + if (first < 0 || count < 0 || primCount < 0) { + ctx.setError(gl.INVALID_VALUE) + return + } + if (!ctx._checkStencilState()) { + return + } + const reducedCount = vertexCount(mode, count) + if (reducedCount < 0) { + ctx.setError(gl.INVALID_ENUM) + return + } + if (!ctx._framebufferOk()) { + return + } + if (count === 0 || primCount === 0) { + return + } + let maxIndex = first + if (count > 0) { + maxIndex = (count + first - 1) >>> 0 + } + if (this.checkInstancedVertexAttribState(maxIndex, primCount)) { + return this._drawArraysInstanced(mode, first, reducedCount, primCount) + } + } + + drawElementsInstancedANGLE (mode, count, type, ioffset, primCount) { + const { ctx } = this + mode |= 0 + count |= 0 + type |= 0 + ioffset |= 0 + primCount |= 0 + + if (count < 0 || ioffset < 0 || primCount < 0) { + ctx.setError(gl.INVALID_VALUE) + return + } + + if (!ctx._checkStencilState()) { + return + } + + const elementBuffer = ctx._activeElementArrayBuffer + if (!elementBuffer) { + ctx.setError(gl.INVALID_OPERATION) + return + } + + // Unpack element data + let elementData = null + let offset = ioffset + if (type === gl.UNSIGNED_SHORT) { + if (offset % 2) { + ctx.setError(gl.INVALID_OPERATION) + return + } + offset >>= 1 + elementData = new Uint16Array(elementBuffer._elements.buffer) + } else if (ctx._extensions.oes_element_index_uint && type === gl.UNSIGNED_INT) { + if (offset % 4) { + ctx.setError(gl.INVALID_OPERATION) + return + } + offset >>= 2 + elementData = new Uint32Array(elementBuffer._elements.buffer) + } else if (type === gl.UNSIGNED_BYTE) { + elementData = elementBuffer._elements + } else { + ctx.setError(gl.INVALID_ENUM) + return + } + + let reducedCount = count + switch (mode) { + case gl.TRIANGLES: + if (count % 3) { + reducedCount -= (count % 3) + } + break + case gl.LINES: + if (count % 2) { + reducedCount -= (count % 2) + } + break + case gl.POINTS: + break + case gl.LINE_LOOP: + case gl.LINE_STRIP: + if (count < 2) { + ctx.setError(gl.INVALID_OPERATION) + return + } + break + case gl.TRIANGLE_FAN: + case gl.TRIANGLE_STRIP: + if (count < 3) { + ctx.setError(gl.INVALID_OPERATION) + return + } + break + default: + ctx.setError(gl.INVALID_ENUM) + return + } + + if (!ctx._framebufferOk()) { + return + } + + if (count === 0 || primCount === 0) { + this.checkInstancedVertexAttribState(0, 0) + return + } + + if ((count + offset) >>> 0 > elementData.length) { + ctx.setError(gl.INVALID_OPERATION) + return + } + + // Compute max index + let maxIndex = -1 + for (let i = offset; i < offset + count; ++i) { + maxIndex = Math.max(maxIndex, elementData[i]) + } + + if (maxIndex < 0) { + this.checkInstancedVertexAttribState(0, 0) + return + } + + if (this.checkInstancedVertexAttribState(maxIndex, primCount)) { + if (reducedCount > 0) { + this._drawElementsInstanced(mode, reducedCount, type, ioffset, primCount) + } + } + } + + vertexAttribDivisorANGLE (index, divisor) { + const { ctx } = this + index |= 0 + divisor |= 0 + if (divisor < 0 || + index < 0 || index >= ctx._vertexAttribs.length) { + ctx.setError(gl.INVALID_VALUE) + return + } + const attrib = ctx._vertexAttribs[index] + attrib._divisor = divisor + this._vertexAttribDivisor(index, divisor) + } + + checkInstancedVertexAttribState (maxIndex, primCount) { + const { ctx } = this + const program = ctx._activeProgram + if (!program) { + ctx.setError(gl.INVALID_OPERATION) + return false + } + + const attribs = ctx._vertexAttribs + let hasZero = false + for (let i = 0; i < attribs.length; ++i) { + const attrib = attribs[i] + if (attrib._isPointer) { + const buffer = attrib._pointerBuffer + if (program._attributes.indexOf(i) >= 0) { + if (!buffer) { + ctx.setError(gl.INVALID_OPERATION) + return false + } + let maxByte = 0 + if (attrib._divisor === 0) { + hasZero = true + maxByte = attrib._pointerStride * maxIndex + + attrib._pointerSize + + attrib._pointerOffset + } else { + maxByte = attrib._pointerStride * (Math.ceil(primCount / attrib._divisor) - 1) + + attrib._pointerSize + + attrib._pointerOffset + } + if (maxByte > buffer._size) { + ctx.setError(gl.INVALID_OPERATION) + return false + } + } + } + } + + if (!hasZero) { + ctx.setError(gl.INVALID_OPERATION) + return false + } + + return true + } +} + +function getANGLEInstancedArrays (ctx) { + return new ANGLEInstancedArrays(ctx) +} + +module.exports = { ANGLEInstancedArrays, getANGLEInstancedArrays } + +},{"../native-gl":30,"../utils":32}],20:[function(require,module,exports){ +class EXTBlendMinMax { + constructor () { + this.MIN_EXT = 0x8007 + this.MAX_EXT = 0x8008 + } +} + +function getEXTBlendMinMax (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('EXT_blend_minmax') >= 0) { + result = new EXTBlendMinMax() + } + + return result +} + +module.exports = { getEXTBlendMinMax, EXTBlendMinMax } + +},{}],21:[function(require,module,exports){ +class EXTTextureFilterAnisotropic { + constructor () { + this.TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE + this.MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF + } +} + +function getEXTTextureFilterAnisotropic (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('EXT_texture_filter_anisotropic') >= 0) { + result = new EXTTextureFilterAnisotropic() + } + + return result +} + +module.exports = { getEXTTextureFilterAnisotropic, EXTTextureFilterAnisotropic } + +},{}],22:[function(require,module,exports){ +class OESElementIndexUint {} + +function getOESElementIndexUint (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('OES_element_index_uint') >= 0) { + result = new OESElementIndexUint() + } + + return result +} + +module.exports = { getOESElementIndexUint, OESElementIndexUint } + +},{}],23:[function(require,module,exports){ +class OESStandardDerivatives { + constructor () { + this.FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B + } +} + +function getOESStandardDerivatives (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('OES_standard_derivatives') >= 0) { + result = new OESStandardDerivatives() + } + + return result +} + +module.exports = { getOESStandardDerivatives, OESStandardDerivatives } + +},{}],24:[function(require,module,exports){ +class OESTextureFloatLinear {} + +function getOESTextureFloatLinear (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('OES_texture_float_linear') >= 0) { + result = new OESTextureFloatLinear() + } + + return result +} + +module.exports = { getOESTextureFloatLinear, OESTextureFloatLinear } + +},{}],25:[function(require,module,exports){ +class OESTextureFloat {} + +function getOESTextureFloat (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('OES_texture_float') >= 0) { + result = new OESTextureFloat() + } + + return result +} + +module.exports = { getOESTextureFloat, OESTextureFloat } + +},{}],26:[function(require,module,exports){ +class STACKGLDestroyContext { + constructor (ctx) { + this.destroy = ctx.destroy.bind(ctx) + } +} + +function getSTACKGLDestroyContext (ctx) { + return new STACKGLDestroyContext(ctx) +} + +module.exports = { getSTACKGLDestroyContext, STACKGLDestroyContext } + +},{}],27:[function(require,module,exports){ +class STACKGLResizeDrawingBuffer { + constructor (ctx) { + this.resize = ctx.resize.bind(ctx) + } +} + +function getSTACKGLResizeDrawingBuffer (ctx) { + return new STACKGLResizeDrawingBuffer(ctx) +} + +module.exports = { getSTACKGLResizeDrawingBuffer, STACKGLResizeDrawingBuffer } + +},{}],28:[function(require,module,exports){ +const { gl } = require('../native-gl') + +class WebGLDrawBuffers { + constructor (ctx) { + this.ctx = ctx + const exts = ctx.getSupportedExtensions() + + if (exts && exts.indexOf('WEBGL_draw_buffers') >= 0) { + Object.assign(this, ctx.extWEBGL_draw_buffers()) + this._buffersState = [ctx.BACK] + this._maxDrawBuffers = ctx._getParameterDirect(this.MAX_DRAW_BUFFERS_WEBGL) + this._ALL_ATTACHMENTS = [] + this._ALL_COLOR_ATTACHMENTS = [] + const allColorAttachments = [ + this.COLOR_ATTACHMENT0_WEBGL, + this.COLOR_ATTACHMENT1_WEBGL, + this.COLOR_ATTACHMENT2_WEBGL, + this.COLOR_ATTACHMENT3_WEBGL, + this.COLOR_ATTACHMENT4_WEBGL, + this.COLOR_ATTACHMENT5_WEBGL, + this.COLOR_ATTACHMENT6_WEBGL, + this.COLOR_ATTACHMENT7_WEBGL, + this.COLOR_ATTACHMENT8_WEBGL, + this.COLOR_ATTACHMENT9_WEBGL, + this.COLOR_ATTACHMENT10_WEBGL, + this.COLOR_ATTACHMENT11_WEBGL, + this.COLOR_ATTACHMENT12_WEBGL, + this.COLOR_ATTACHMENT13_WEBGL, + this.COLOR_ATTACHMENT14_WEBGL, + this.COLOR_ATTACHMENT15_WEBGL + ] + while (this._ALL_ATTACHMENTS.length < this._maxDrawBuffers) { + const colorAttachment = allColorAttachments.shift() + this._ALL_ATTACHMENTS.push(colorAttachment) + this._ALL_COLOR_ATTACHMENTS.push(colorAttachment) + } + this._ALL_ATTACHMENTS.push( + gl.DEPTH_ATTACHMENT, + gl.STENCIL_ATTACHMENT, + gl.DEPTH_STENCIL_ATTACHMENT + ) + } + } + + drawBuffersWEBGL (buffers) { + const { ctx } = this + if (buffers.length < 1) { + ctx.setError(gl.INVALID_OPERATION) + return + } + if (buffers.length === 1 && buffers[0] === gl.BACK) { + this._buffersState = buffers + ctx.drawBuffersWEBGL([this.COLOR_ATTACHMENT0_WEBGL]) + return + } else if (!ctx._activeFramebuffer) { + if (buffers.length > 1) { + ctx.setError(gl.INVALID_OPERATION) + return + } + for (let i = 0; i < buffers.length; i++) { + if (buffers[i] > gl.NONE) { + ctx.setError(gl.INVALID_OPERATION) + return + } + } + } + this._buffersState = buffers + ctx.drawBuffersWEBGL(buffers) + } +} + +function getWebGLDrawBuffers (ctx) { + const exts = ctx.getSupportedExtensions() + + if (exts && exts.indexOf('WEBGL_draw_buffers') >= 0) { + return new WebGLDrawBuffers(ctx) + } else { + return null + } +} + +module.exports = { + getWebGLDrawBuffers, + WebGLDrawBuffers +} + +},{"../native-gl":30}],29:[function(require,module,exports){ +class Linkable { + constructor (_) { + this._ = _ + this._references = [] + this._refCount = 0 + this._pendingDelete = false + this._binding = 0 + } + + _link (b) { + this._references.push(b) + b._refCount += 1 + return true + } + + _unlink (b) { + let idx = this._references.indexOf(b) + if (idx < 0) { + return false + } + while (idx >= 0) { + this._references[idx] = this._references[this._references.length - 1] + this._references.pop() + b._refCount -= 1 + b._checkDelete() + idx = this._references.indexOf(b) + } + return true + } + + _linked (b) { + return this._references.indexOf(b) >= 0 + } + + _checkDelete () { + if (this._refCount <= 0 && + this._pendingDelete && + this._ !== 0) { + while (this._references.length > 0) { + this._unlink(this._references[0]) + } + this._performDelete() + this._ = 0 + } + } + + _performDelete () {} +} + +module.exports = { Linkable } + +},{}],30:[function(require,module,exports){ +(function (process){ +const NativeWebGL = require('bindings')('webgl') +const { WebGLRenderingContext: NativeWebGLRenderingContext } = NativeWebGL +process.on('exit', NativeWebGL.cleanup) + +const gl = NativeWebGLRenderingContext.prototype + +// from binding.gyp +delete gl['1.0.0'] + +// from binding.gyp +delete NativeWebGLRenderingContext['1.0.0'] + +module.exports = { gl, NativeWebGL, NativeWebGLRenderingContext } + +}).call(this,require('_process')) +},{"_process":169,"bindings":12}],31:[function(require,module,exports){ +const bits = require('bit-twiddle') +const { WebGLContextAttributes } = require('./webgl-context-attributes') +const { WebGLRenderingContext, wrapContext } = require('./webgl-rendering-context') +const { WebGLTextureUnit } = require('./webgl-texture-unit') +const { WebGLVertexAttribute } = require('./webgl-vertex-attribute') + +let CONTEXT_COUNTER = 0 + +function flag (options, name, dflt) { + if (!options || !(typeof options === 'object') || !(name in options)) { + return dflt + } + return !!options[name] +} + +function createContext (width, height, options) { + width = width | 0 + height = height | 0 + if (!(width > 0 && height > 0)) { + return null + } + + const contextAttributes = new WebGLContextAttributes( + flag(options, 'alpha', true), + flag(options, 'depth', true), + flag(options, 'stencil', false), + false, // flag(options, 'antialias', true), + flag(options, 'premultipliedAlpha', true), + flag(options, 'preserveDrawingBuffer', false), + flag(options, 'preferLowPowerToHighPerformance', false), + flag(options, 'failIfMajorPerformanceCaveat', false)) + + // Can only use premultipliedAlpha if alpha is set + contextAttributes.premultipliedAlpha = + contextAttributes.premultipliedAlpha && contextAttributes.alpha + + let ctx + try { + ctx = new WebGLRenderingContext( + 1, + 1, + contextAttributes.alpha, + contextAttributes.depth, + contextAttributes.stencil, + contextAttributes.antialias, + contextAttributes.premultipliedAlpha, + contextAttributes.preserveDrawingBuffer, + contextAttributes.preferLowPowerToHighPerformance, + contextAttributes.failIfMajorPerformanceCaveat) + } catch (e) {} + if (!ctx) { + return null + } + + ctx.drawingBufferWidth = width + ctx.drawingBufferHeight = height + + ctx._ = CONTEXT_COUNTER++ + + ctx._contextAttributes = contextAttributes + + ctx._extensions = {} + ctx._programs = {} + ctx._shaders = {} + ctx._buffers = {} + ctx._textures = {} + ctx._framebuffers = {} + ctx._renderbuffers = {} + + ctx._activeProgram = null + ctx._activeFramebuffer = null + ctx._activeArrayBuffer = null + ctx._activeElementArrayBuffer = null + ctx._activeRenderbuffer = null + ctx._checkStencil = false + ctx._stencilState = true + + // Initialize texture units + const numTextures = ctx.getParameter(ctx.MAX_COMBINED_TEXTURE_IMAGE_UNITS) + ctx._textureUnits = new Array(numTextures) + for (let i = 0; i < numTextures; ++i) { + ctx._textureUnits[i] = new WebGLTextureUnit(i) + } + ctx._activeTextureUnit = 0 + ctx.activeTexture(ctx.TEXTURE0) + + ctx._errorStack = [] + + // Initialize vertex attributes + const numAttribs = ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS) + ctx._vertexAttribs = new Array(numAttribs) + for (let i = 0; i < numAttribs; ++i) { + ctx._vertexAttribs[i] = new WebGLVertexAttribute(ctx, i) + } + + // Store limits + ctx._maxTextureSize = ctx.getParameter(ctx.MAX_TEXTURE_SIZE) + ctx._maxTextureLevel = bits.log2(bits.nextPow2(ctx._maxTextureSize)) + ctx._maxCubeMapSize = ctx.getParameter(ctx.MAX_CUBE_MAP_TEXTURE_SIZE) + ctx._maxCubeMapLevel = bits.log2(bits.nextPow2(ctx._maxCubeMapSize)) + + // Unpack alignment + ctx._unpackAlignment = 4 + ctx._packAlignment = 4 + + // Allocate framebuffer + ctx._allocateDrawingBuffer(width, height) + + const attrib0Buffer = ctx.createBuffer() + ctx._attrib0Buffer = attrib0Buffer + + // Initialize defaults + ctx.bindBuffer(ctx.ARRAY_BUFFER, null) + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null) + ctx.bindFramebuffer(ctx.FRAMEBUFFER, null) + ctx.bindRenderbuffer(ctx.RENDERBUFFER, null) + + // Set viewport and scissor + ctx.viewport(0, 0, width, height) + ctx.scissor(0, 0, width, height) + + // Clear buffers + ctx.clearDepth(1) + ctx.clearColor(0, 0, 0, 0) + ctx.clearStencil(0) + ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT) + + return wrapContext(ctx) +} + +module.exports = createContext + +},{"./webgl-context-attributes":35,"./webgl-rendering-context":40,"./webgl-texture-unit":43,"./webgl-vertex-attribute":46,"bit-twiddle":13}],32:[function(require,module,exports){ +(function (Buffer){ +const { gl } = require('./native-gl') + +const { WebGLUniformLocation } = require('./webgl-uniform-location') + +function bindPublics (props, wrapper, privateInstance, privateMethods) { + for (let i = 0; i < props.length; i++) { + const prop = props[i] + const value = privateInstance[prop] + if (typeof value === 'function') { + if (privateMethods.indexOf(prop) === -1) { + wrapper[prop] = value.bind(privateInstance) + } + } else { + if (prop[0] === '_' || + prop[0] === '0' || + prop[0] === '1') { + continue + } + wrapper[prop] = value + } + } +} + +function checkObject (object) { + return typeof object === 'object' || + (object === undefined) +} + +function checkUniform (program, location) { + return location instanceof WebGLUniformLocation && + location._program === program && + location._linkCount === program._linkCount +} + +function isTypedArray (data) { + return data instanceof Uint8Array || + data instanceof Uint8ClampedArray || + data instanceof Int8Array || + data instanceof Uint16Array || + data instanceof Int16Array || + data instanceof Uint32Array || + data instanceof Int32Array || + data instanceof Float32Array || + data instanceof Float64Array +} + +// Don't allow: ", $, `, @, \, ', \0 +function isValidString (str) { + // Remove comments first + const c = str.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '') + return !(/["$`@\\'\0]/.test(c)) +} + +function vertexCount (primitive, count) { + switch (primitive) { + case gl.TRIANGLES: + return count - (count % 3) + case gl.LINES: + return count - (count % 2) + case gl.LINE_LOOP: + case gl.POINTS: + return count + case gl.TRIANGLE_FAN: + case gl.LINE_STRIP: + if (count < 2) { + return 0 + } + return count + case gl.TRIANGLE_STRIP: + if (count < 3) { + return 0 + } + return count + default: + return -1 + } +} + +function typeSize (type) { + switch (type) { + case gl.UNSIGNED_BYTE: + case gl.BYTE: + return 1 + case gl.UNSIGNED_SHORT: + case gl.SHORT: + return 2 + case gl.UNSIGNED_INT: + case gl.INT: + case gl.FLOAT: + return 4 + } + return 0 +} + +function uniformTypeSize (type) { + switch (type) { + case gl.BOOL_VEC4: + case gl.INT_VEC4: + case gl.FLOAT_VEC4: + return 4 + + case gl.BOOL_VEC3: + case gl.INT_VEC3: + case gl.FLOAT_VEC3: + return 3 + + case gl.BOOL_VEC2: + case gl.INT_VEC2: + case gl.FLOAT_VEC2: + return 2 + + case gl.BOOL: + case gl.INT: + case gl.FLOAT: + case gl.SAMPLER_2D: + case gl.SAMPLER_CUBE: + return 1 + + default: + return 0 + } +} + +function unpackTypedArray (array) { + return (new Uint8Array(array.buffer)).subarray( + array.byteOffset, + array.byteLength + array.byteOffset) +} + +function extractImageData (pixels) { + if (typeof pixels === 'object' && typeof pixels.width !== 'undefined' && typeof pixels.height !== 'undefined') { + if (typeof pixels.data !== 'undefined') { + return pixels + } + + let context = null + + if (typeof pixels.getContext === 'function') { + context = pixels.getContext('2d') + } else if (typeof pixels.src !== 'undefined' && typeof document === 'object' && typeof document.createElement === 'function') { + const canvas = document.createElement('canvas') + + if (typeof canvas === 'object' && typeof canvas.getContext === 'function') { + context = canvas.getContext('2d') + + if (context !== null) { + context.drawImage(pixels, 0, 0) + } + } + } + + if (context !== null) { + return context.getImageData(0, 0, pixels.width, pixels.height) + } + } + + return null +} + +function formatSize (internalFormat) { + switch (internalFormat) { + case gl.ALPHA: + case gl.LUMINANCE: + return 1 + case gl.LUMINANCE_ALPHA: + return 2 + case gl.RGB: + return 3 + case gl.RGBA: + return 4 + } + return 0 +} + +function convertPixels (pixels) { + if (typeof pixels === 'object' && pixels !== null) { + if (pixels instanceof ArrayBuffer) { + return new Uint8Array(pixels) + } else if (pixels instanceof Uint8Array || + pixels instanceof Uint16Array || + pixels instanceof Uint8ClampedArray || + pixels instanceof Float32Array) { + return unpackTypedArray(pixels) + } else if (pixels instanceof Buffer) { + return new Uint8Array(pixels) + } + } + return null +} + +function checkFormat (format) { + return ( + format === gl.ALPHA || + format === gl.LUMINANCE_ALPHA || + format === gl.LUMINANCE || + format === gl.RGB || + format === gl.RGBA) +} + +function validCubeTarget (target) { + return target === gl.TEXTURE_CUBE_MAP_POSITIVE_X || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_X || + target === gl.TEXTURE_CUBE_MAP_POSITIVE_Y || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_Y || + target === gl.TEXTURE_CUBE_MAP_POSITIVE_Z || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_Z +} + +module.exports = { + bindPublics, + checkObject, + isTypedArray, + isValidString, + vertexCount, + typeSize, + uniformTypeSize, + unpackTypedArray, + extractImageData, + formatSize, + checkFormat, + checkUniform, + convertPixels, + validCubeTarget +} + +}).call(this,require("buffer").Buffer) +},{"./native-gl":30,"./webgl-uniform-location":45,"buffer":165}],33:[function(require,module,exports){ +class WebGLActiveInfo { + constructor (_) { + this.size = _.size + this.type = _.type + this.name = _.name + } +} +module.exports = { WebGLActiveInfo } + +},{}],34:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLBuffer extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._size = 0 + this._elements = new Uint8Array(0) + } + + _performDelete () { + const ctx = this._ctx + delete ctx._buffers[this._ | 0] + gl.deleteBuffer.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLBuffer } + +},{"./linkable":29,"./native-gl":30}],35:[function(require,module,exports){ +class WebGLContextAttributes { + constructor ( + alpha, + depth, + stencil, + antialias, + premultipliedAlpha, + preserveDrawingBuffer, + preferLowPowerToHighPerformance, + failIfMajorPerformanceCaveat) { + this.alpha = alpha + this.depth = depth + this.stencil = stencil + this.antialias = antialias + this.premultipliedAlpha = premultipliedAlpha + this.preserveDrawingBuffer = preserveDrawingBuffer + this.preferLowPowerToHighPerformance = preferLowPowerToHighPerformance + this.failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat + } +} + +module.exports = { WebGLContextAttributes } + +},{}],36:[function(require,module,exports){ +class WebGLDrawingBufferWrapper { + constructor (framebuffer, color, depthStencil) { + this._framebuffer = framebuffer + this._color = color + this._depthStencil = depthStencil + } +} + +module.exports = { WebGLDrawingBufferWrapper } + +},{}],37:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLFramebuffer extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._binding = 0 + + this._width = 0 + this._height = 0 + this._status = null + + this._attachments = {} + this._attachments[gl.COLOR_ATTACHMENT0] = null + this._attachments[gl.DEPTH_ATTACHMENT] = null + this._attachments[gl.STENCIL_ATTACHMENT] = null + this._attachments[gl.DEPTH_STENCIL_ATTACHMENT] = null + + this._attachmentLevel = {} + this._attachmentLevel[gl.COLOR_ATTACHMENT0] = 0 + this._attachmentLevel[gl.DEPTH_ATTACHMENT] = 0 + this._attachmentLevel[gl.STENCIL_ATTACHMENT] = 0 + this._attachmentLevel[gl.DEPTH_STENCIL_ATTACHMENT] = 0 + + this._attachmentFace = {} + this._attachmentFace[gl.COLOR_ATTACHMENT0] = 0 + this._attachmentFace[gl.DEPTH_ATTACHMENT] = 0 + this._attachmentFace[gl.STENCIL_ATTACHMENT] = 0 + this._attachmentFace[gl.DEPTH_STENCIL_ATTACHMENT] = 0 + + if (ctx._extensions.webgl_draw_buffers) { + const { webgl_draw_buffers } = ctx._extensions // eslint-disable-line + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT1_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT2_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT3_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT4_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT5_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT6_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT7_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT8_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT9_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT10_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT11_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT12_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT13_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT14_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT15_WEBGL] = null + this._attachments[gl.NONE] = null + this._attachments[gl.BACK] = null + + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT1_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT2_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT3_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT4_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT5_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT6_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT7_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT8_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT9_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT10_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT11_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT12_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT13_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT14_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT15_WEBGL] = 0 + this._attachmentLevel[gl.NONE] = null + this._attachmentLevel[gl.BACK] = null + + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT1_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT2_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT3_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT4_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT5_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT6_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT7_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT8_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT9_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT10_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT11_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT12_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT13_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT14_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT15_WEBGL] = 0 + this._attachmentFace[gl.NONE] = null + this._attachmentFace[gl.BACK] = null + } + } + + _clearAttachment (attachment) { + const object = this._attachments[attachment] + if (!object) { + return + } + this._attachments[attachment] = null + this._unlink(object) + } + + _setAttachment (object, attachment) { + const prevObject = this._attachments[attachment] + if (prevObject === object) { + return + } + + this._clearAttachment(attachment) + if (!object) { + return + } + + this._attachments[attachment] = object + + this._link(object) + } + + _performDelete () { + const ctx = this._ctx + delete ctx._framebuffers[this._ | 0] + gl.deleteFramebuffer.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLFramebuffer } + +},{"./linkable":29,"./native-gl":30}],38:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLProgram extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._linkCount = 0 + this._linkStatus = false + this._linkInfoLog = 'not linked' + this._attributes = [] + this._uniforms = [] + } + + _performDelete () { + const ctx = this._ctx + delete ctx._programs[this._ | 0] + gl.deleteProgram.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLProgram } + +},{"./linkable":29,"./native-gl":30}],39:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLRenderbuffer extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._binding = 0 + this._width = 0 + this._height = 0 + this._format = 0 + } + + _performDelete () { + const ctx = this._ctx + delete ctx._renderbuffers[this._ | 0] + gl.deleteRenderbuffer.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLRenderbuffer } + +},{"./linkable":29,"./native-gl":30}],40:[function(require,module,exports){ +const bits = require('bit-twiddle') +const tokenize = require('glsl-tokenizer/string') +const HEADLESS_VERSION = require('../../package.json').version +const { gl, NativeWebGLRenderingContext, NativeWebGL } = require('./native-gl') +const { getANGLEInstancedArrays } = require('./extensions/angle-instanced-arrays') +const { getOESElementIndexUint } = require('./extensions/oes-element-index-unit') +const { getOESStandardDerivatives } = require('./extensions/oes-standard-derivatives') +const { getOESTextureFloat } = require('./extensions/oes-texture-float') +const { getOESTextureFloatLinear } = require('./extensions/oes-texture-float-linear') +const { getSTACKGLDestroyContext } = require('./extensions/stackgl-destroy-context') +const { getSTACKGLResizeDrawingBuffer } = require('./extensions/stackgl-resize-drawing-buffer') +const { getWebGLDrawBuffers } = require('./extensions/webgl-draw-buffers') +const { getEXTBlendMinMax } = require('./extensions/ext-blend-minmax') +const { getEXTTextureFilterAnisotropic } = require('./extensions/ext-texture-filter-anisotropic') +const { + bindPublics, + checkObject, + checkUniform, + formatSize, + isValidString, + typeSize, + uniformTypeSize, + extractImageData, + vertexCount, + isTypedArray, + unpackTypedArray, + convertPixels, + checkFormat, + validCubeTarget +} = require('./utils') + +const { WebGLActiveInfo } = require('./webgl-active-info') +const { WebGLFramebuffer } = require('./webgl-framebuffer') +const { WebGLBuffer } = require('./webgl-buffer') +const { WebGLDrawingBufferWrapper } = require('./webgl-drawing-buffer-wrapper') +const { WebGLProgram } = require('./webgl-program') +const { WebGLRenderbuffer } = require('./webgl-renderbuffer') +const { WebGLShader } = require('./webgl-shader') +const { WebGLShaderPrecisionFormat } = require('./webgl-shader-precision-format') +const { WebGLTexture } = require('./webgl-texture') +const { WebGLUniformLocation } = require('./webgl-uniform-location') + +// These are defined by the WebGL spec +const MAX_UNIFORM_LENGTH = 256 +const MAX_ATTRIBUTE_LENGTH = 256 + +const DEFAULT_ATTACHMENTS = [ + gl.COLOR_ATTACHMENT0, + gl.DEPTH_ATTACHMENT, + gl.STENCIL_ATTACHMENT, + gl.DEPTH_STENCIL_ATTACHMENT +] + +const DEFAULT_COLOR_ATTACHMENTS = [gl.COLOR_ATTACHMENT0] + +const availableExtensions = { + angle_instanced_arrays: getANGLEInstancedArrays, + oes_element_index_uint: getOESElementIndexUint, + oes_texture_float: getOESTextureFloat, + oes_texture_float_linear: getOESTextureFloatLinear, + oes_standard_derivatives: getOESStandardDerivatives, + stackgl_destroy_context: getSTACKGLDestroyContext, + stackgl_resize_drawingbuffer: getSTACKGLResizeDrawingBuffer, + webgl_draw_buffers: getWebGLDrawBuffers, + ext_blend_minmax: getEXTBlendMinMax, + ext_texture_filter_anisotropic: getEXTTextureFilterAnisotropic +} + +const privateMethods = [ + 'resize', + 'destroy' +] + +function wrapContext (ctx) { + const wrapper = new WebGLRenderingContext() + bindPublics(Object.keys(ctx), wrapper, ctx, privateMethods) + bindPublics(Object.keys(ctx.constructor.prototype), wrapper, ctx, privateMethods) + bindPublics(Object.getOwnPropertyNames(ctx), wrapper, ctx, privateMethods) + bindPublics(Object.getOwnPropertyNames(ctx.constructor.prototype), wrapper, ctx, privateMethods) + + Object.defineProperties(wrapper, { + drawingBufferWidth: { + get () { return ctx.drawingBufferWidth }, + set (value) { ctx.drawingBufferWidth = value } + }, + drawingBufferHeight: { + get () { return ctx.drawingBufferHeight }, + set (value) { ctx.drawingBufferHeight = value } + } + }) + + return wrapper +} + +// We need to wrap some of the native WebGL functions to handle certain error codes and check input values +class WebGLRenderingContext extends NativeWebGLRenderingContext { + _checkDimensions ( + target, + width, + height, + level) { + if (level < 0 || + width < 0 || + height < 0) { + this.setError(gl.INVALID_VALUE) + return false + } + if (target === gl.TEXTURE_2D) { + if (width > this._maxTextureSize || + height > this._maxTextureSize || + level > this._maxTextureLevel) { + this.setError(gl.INVALID_VALUE) + return false + } + } else if (this._validCubeTarget(target)) { + if (width > this._maxCubeMapSize || + height > this._maxCubeMapSize || + level > this._maxCubeMapLevel) { + this.setError(gl.INVALID_VALUE) + return false + } + } else { + this.setError(gl.INVALID_ENUM) + return false + } + return true + } + + _checkLocation (location) { + if (!(location instanceof WebGLUniformLocation)) { + this.setError(gl.INVALID_VALUE) + return false + } else if (location._program._ctx !== this || + location._linkCount !== location._program._linkCount) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + + _checkLocationActive (location) { + if (!location) { + return false + } else if (!this._checkLocation(location)) { + return false + } else if (location._program !== this._activeProgram) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + + _checkOwns (object) { + return typeof object === 'object' && + object._ctx === this + } + + _checkShaderSource (shader) { + const source = shader._source + const tokens = tokenize(source) + + let errorStatus = false + const errorLog = [] + + for (let i = 0; i < tokens.length; ++i) { + const tok = tokens[i] + switch (tok.type) { + case 'ident': + if (!this._validGLSLIdentifier(tok.data)) { + errorStatus = true + errorLog.push(tok.line + ':' + tok.column + + ' invalid identifier - ' + tok.data) + } + break + case 'preprocessor': { + const bodyToks = tokenize(tok.data.match(/^\s*#\s*(.*)$/)[1]) + for (let j = 0; j < bodyToks.length; ++j) { + const btok = bodyToks[j] + if (btok.type === 'ident' || btok.type === undefined) { + if (!this._validGLSLIdentifier(btok.data)) { + errorStatus = true + errorLog.push(tok.line + ':' + btok.column + + ' invalid identifier - ' + btok.data) + } + } + } + break + } + case 'keyword': + switch (tok.data) { + case 'do': + errorStatus = true + errorLog.push(tok.line + ':' + tok.column + ' do not supported') + break + } + break + case 'builtin': + switch (tok.data) { + case 'dFdx': + case 'dFdy': + case 'fwidth': + if (!this._extensions.oes_standard_derivatives) { + errorStatus = true + errorLog.push(tok.line + ':' + tok.column + ' ' + tok.data + ' not supported') + } + break + } + } + } + + if (errorStatus) { + shader._compileInfo = errorLog.join('\n') + } + return !errorStatus + } + + _checkStencilState () { + if (!this._checkStencil) { + return this._stencilState + } + this._checkStencil = false + this._stencilState = true + if (this.getParameter(gl.STENCIL_WRITEMASK) !== + this.getParameter(gl.STENCIL_BACK_WRITEMASK) || + this.getParameter(gl.STENCIL_VALUE_MASK) !== + this.getParameter(gl.STENCIL_BACK_VALUE_MASK) || + this.getParameter(gl.STENCIL_REF) !== + this.getParameter(gl.STENCIL_BACK_REF)) { + this.setError(gl.INVALID_OPERATION) + this._stencilState = false + } + return this._stencilState + } + + _checkTextureTarget (target) { + const unit = this._getActiveTextureUnit() + let tex = null + if (target === gl.TEXTURE_2D) { + tex = unit._bind2D + } else if (target === gl.TEXTURE_CUBE_MAP) { + tex = unit._bindCube + } else { + this.setError(gl.INVALID_ENUM) + return false + } + if (!tex) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + + _checkWrapper (object, Wrapper) { + if (!this._checkValid(object, Wrapper)) { + this.setError(gl.INVALID_VALUE) + return false + } else if (!this._checkOwns(object)) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + + _checkValid (object, Type) { + return object instanceof Type && object._ !== 0 + } + + _checkVertexAttribState (maxIndex) { + const program = this._activeProgram + if (!program) { + this.setError(gl.INVALID_OPERATION) + return false + } + const attribs = this._vertexAttribs + for (let i = 0; i < attribs.length; ++i) { + const attrib = attribs[i] + if (attrib._isPointer) { + const buffer = attrib._pointerBuffer + if (!buffer) { + this.setError(gl.INVALID_OPERATION) + return false + } + if (program._attributes.indexOf(i) >= 0) { + let maxByte = 0 + if (attrib._divisor) { + maxByte = attrib._pointerSize + + attrib._pointerOffset + } else { + maxByte = attrib._pointerStride * maxIndex + + attrib._pointerSize + + attrib._pointerOffset + } + if (maxByte > buffer._size) { + this.setError(gl.INVALID_OPERATION) + return false + } + } + } + } + return true + } + + _checkVertexIndex (index) { + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return false + } + return true + } + + _computePixelSize (type, internalFormat) { + const pixelSize = formatSize(internalFormat) + if (pixelSize === 0) { + this.setError(gl.INVALID_ENUM) + return 0 + } + switch (type) { + case gl.UNSIGNED_BYTE: + return pixelSize + case gl.UNSIGNED_SHORT_5_6_5: + if (internalFormat !== gl.RGB) { + this.setError(gl.INVALID_OPERATION) + break + } + return 2 + case gl.UNSIGNED_SHORT_4_4_4_4: + case gl.UNSIGNED_SHORT_5_5_5_1: + if (internalFormat !== gl.RGBA) { + this.setError(gl.INVALID_OPERATION) + break + } + return 2 + case gl.FLOAT: + return 1 + } + this.setError(gl.INVALID_ENUM) + return 0 + } + + _computeRowStride (width, pixelSize) { + let rowStride = width * pixelSize + if (rowStride % this._unpackAlignment) { + rowStride += this._unpackAlignment - (rowStride % this._unpackAlignment) + } + return rowStride + } + + _fixupLink (program) { + if (!super.getProgramParameter(program._, gl.LINK_STATUS)) { + program._linkInfoLog = super.getProgramInfoLog(program) + return false + } + + // Record attribute attributeLocations + const numAttribs = this.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES) + const names = new Array(numAttribs) + program._attributes.length = numAttribs + for (let i = 0; i < numAttribs; ++i) { + names[i] = this.getActiveAttrib(program, i).name + program._attributes[i] = this.getAttribLocation(program, names[i]) | 0 + } + + // Check attribute names + for (let i = 0; i < names.length; ++i) { + if (names[i].length > MAX_ATTRIBUTE_LENGTH) { + program._linkInfoLog = 'attribute ' + names[i] + ' is too long' + return false + } + } + + for (let i = 0; i < numAttribs; ++i) { + super.bindAttribLocation( + program._ | 0, + program._attributes[i], + names[i]) + } + + super.linkProgram(program._ | 0) + + const numUniforms = this.getProgramParameter(program, gl.ACTIVE_UNIFORMS) + program._uniforms.length = numUniforms + for (let i = 0; i < numUniforms; ++i) { + program._uniforms[i] = this.getActiveUniform(program, i) + } + + // Check attribute and uniform name lengths + for (let i = 0; i < program._uniforms.length; ++i) { + if (program._uniforms[i].name.length > MAX_UNIFORM_LENGTH) { + program._linkInfoLog = 'uniform ' + program._uniforms[i].name + ' is too long' + return false + } + } + + program._linkInfoLog = '' + return true + } + + _framebufferOk () { + const framebuffer = this._activeFramebuffer + if (framebuffer && + this._preCheckFramebufferStatus(framebuffer) !== gl.FRAMEBUFFER_COMPLETE) { + this.setError(gl.INVALID_FRAMEBUFFER_OPERATION) + return false + } + return true + } + + _getActiveBuffer (target) { + if (target === gl.ARRAY_BUFFER) { + return this._activeArrayBuffer + } else if (target === gl.ELEMENT_ARRAY_BUFFER) { + return this._activeElementArrayBuffer + } + return null + } + + _getActiveTextureUnit () { + return this._textureUnits[this._activeTextureUnit] + } + + _getActiveTexture (target) { + const activeUnit = this._getActiveTextureUnit() + if (target === gl.TEXTURE_2D) { + return activeUnit._bind2D + } else if (target === gl.TEXTURE_CUBE_MAP) { + return activeUnit._bindCube + } + return null + } + + _getAttachments () { + return this._extensions.webgl_draw_buffers ? this._extensions.webgl_draw_buffers._ALL_ATTACHMENTS : DEFAULT_ATTACHMENTS + } + + _getColorAttachments () { + return this._extensions.webgl_draw_buffers ? this._extensions.webgl_draw_buffers._ALL_COLOR_ATTACHMENTS : DEFAULT_COLOR_ATTACHMENTS + } + + _getParameterDirect (pname) { + return super.getParameter(pname) + } + + _getTexImage (target) { + const unit = this._getActiveTextureUnit() + if (target === gl.TEXTURE_2D) { + return unit._bind2D + } else if (validCubeTarget(target)) { + return unit._bindCube + } + this.setError(gl.INVALID_ENUM) + return null + } + + _preCheckFramebufferStatus (framebuffer) { + const attachments = framebuffer._attachments + const width = [] + const height = [] + const depthAttachment = attachments[gl.DEPTH_ATTACHMENT] + const depthStencilAttachment = attachments[gl.DEPTH_STENCIL_ATTACHMENT] + const stencilAttachment = attachments[gl.STENCIL_ATTACHMENT] + + if ((depthStencilAttachment && (stencilAttachment || depthAttachment)) || + (stencilAttachment && depthAttachment)) { + return gl.FRAMEBUFFER_UNSUPPORTED + } + + const colorAttachments = this._getColorAttachments() + let colorAttachmentCount = 0 + for (const attachmentEnum in attachments) { + if (attachments[attachmentEnum] && colorAttachments.indexOf(attachmentEnum * 1) !== -1) { + colorAttachmentCount++ + } + } + if (colorAttachmentCount === 0) { + return gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + } + + if (depthStencilAttachment instanceof WebGLTexture) { + return gl.FRAMEBUFFER_UNSUPPORTED + } else if (depthStencilAttachment instanceof WebGLRenderbuffer) { + if (depthStencilAttachment._format !== gl.DEPTH_STENCIL) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + width.push(depthStencilAttachment._width) + height.push(depthStencilAttachment._height) + } + + if (depthAttachment instanceof WebGLTexture) { + return gl.FRAMEBUFFER_UNSUPPORTED + } else if (depthAttachment instanceof WebGLRenderbuffer) { + if (depthAttachment._format !== gl.DEPTH_COMPONENT16) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + width.push(depthAttachment._width) + height.push(depthAttachment._height) + } + + if (stencilAttachment instanceof WebGLTexture) { + return gl.FRAMEBUFFER_UNSUPPORTED + } else if (stencilAttachment instanceof WebGLRenderbuffer) { + if (stencilAttachment._format !== gl.STENCIL_INDEX8) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + width.push(stencilAttachment._width) + height.push(stencilAttachment._height) + } + + let colorAttached = false + for (let i = 0; i < colorAttachments.length; ++i) { + const colorAttachment = attachments[colorAttachments[i]] + if (colorAttachment instanceof WebGLTexture) { + if (colorAttachment._format !== gl.RGBA || + !(colorAttachment._type === gl.UNSIGNED_BYTE || colorAttachment._type === gl.FLOAT)) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + colorAttached = true + const level = framebuffer._attachmentLevel[gl.COLOR_ATTACHMENT0] + width.push(colorAttachment._levelWidth[level]) + height.push(colorAttachment._levelHeight[level]) + } else if (colorAttachment instanceof WebGLRenderbuffer) { + const format = colorAttachment._format + if (format !== gl.RGBA4 && + format !== gl.RGB565 && + format !== gl.RGB5_A1) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + colorAttached = true + width.push(colorAttachment._width) + height.push(colorAttachment._height) + } + } + + if (!colorAttached && + !stencilAttachment && + !depthAttachment && + !depthStencilAttachment) { + return gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + } + + if (width.length <= 0 || height.length <= 0) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + + for (let i = 1; i < width.length; ++i) { + if (width[i - 1] !== width[i] || + height[i - 1] !== height[i]) { + return gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS + } + } + + if (width[0] === 0 || height[0] === 0) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + + framebuffer._width = width[0] + framebuffer._height = height[0] + + return gl.FRAMEBUFFER_COMPLETE + } + + _isConstantBlendFunc (factor) { + return ( + factor === gl.CONSTANT_COLOR || + factor === gl.ONE_MINUS_CONSTANT_COLOR || + factor === gl.CONSTANT_ALPHA || + factor === gl.ONE_MINUS_CONSTANT_ALPHA) + } + + _isObject (object, method, Wrapper) { + if (!(object === null || object === undefined) && + !(object instanceof Wrapper)) { + throw new TypeError(method + '(' + Wrapper.name + ')') + } + if (this._checkValid(object, Wrapper) && this._checkOwns(object)) { + return true + } + return false + } + + _resizeDrawingBuffer (width, height) { + const prevFramebuffer = this._activeFramebuffer + const prevTexture = this._getActiveTexture(gl.TEXTURE_2D) + const prevRenderbuffer = this._activeRenderbuffer + + const contextAttributes = this._contextAttributes + + const drawingBuffer = this._drawingBuffer + super.bindFramebuffer(gl.FRAMEBUFFER, drawingBuffer._framebuffer) + const attachments = this._getAttachments() + // Clear all attachments + for (let i = 0; i < attachments.length; ++i) { + super.framebufferTexture2D( + gl.FRAMEBUFFER, + attachments[i], + gl.TEXTURE_2D, + 0, + 0) + } + + // Update color attachment + super.bindTexture(gl.TEXTURE_2D, drawingBuffer._color) + const colorFormat = contextAttributes.alpha ? gl.RGBA : gl.RGB + super.texImage2D( + gl.TEXTURE_2D, + 0, + colorFormat, + width, + height, + 0, + colorFormat, + gl.UNSIGNED_BYTE, + null) + super.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) + super.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) + super.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + drawingBuffer._color, + 0) + + // Update depth-stencil attachments if needed + let storage = 0 + let attachment = 0 + if (contextAttributes.depth && contextAttributes.stencil) { + storage = gl.DEPTH_STENCIL + attachment = gl.DEPTH_STENCIL_ATTACHMENT + } else if (contextAttributes.depth) { + storage = 0x81A7 + attachment = gl.DEPTH_ATTACHMENT + } else if (contextAttributes.stencil) { + storage = gl.STENCIL_INDEX8 + attachment = gl.STENCIL_ATTACHMENT + } + + if (storage) { + super.bindRenderbuffer( + gl.RENDERBUFFER, + drawingBuffer._depthStencil) + super.renderbufferStorage( + gl.RENDERBUFFER, + storage, + width, + height) + super.framebufferRenderbuffer( + gl.FRAMEBUFFER, + attachment, + gl.RENDERBUFFER, + drawingBuffer._depthStencil) + } + + // Restore previous binding state + this.bindFramebuffer(gl.FRAMEBUFFER, prevFramebuffer) + this.bindTexture(gl.TEXTURE_2D, prevTexture) + this.bindRenderbuffer(gl.RENDERBUFFER, prevRenderbuffer) + } + + _restoreError (lastError) { + const topError = this._errorStack.pop() + if (topError === gl.NO_ERROR) { + this.setError(lastError) + } else { + this.setError(topError) + } + } + + _saveError () { + this._errorStack.push(this.getError()) + } + + _switchActiveBuffer (active, buffer) { + if (active !== buffer) { + if (active) { + active._refCount -= 1 + active._checkDelete() + } + if (buffer) { + buffer._refCount += 1 + } + } + } + + _switchActiveProgram (active) { + if (active) { + active._refCount -= 1 + active._checkDelete() + } + } + + _tryDetachFramebuffer (framebuffer, renderbuffer) { + // FIXME: Does the texture get unbound from *all* framebuffers, or just the + // active FBO? + if (framebuffer && framebuffer._linked(renderbuffer)) { + const attachments = this._getAttachments() + const framebufferAttachments = Object.keys(framebuffer._attachments) + for (let i = 0; i < framebufferAttachments.length; ++i) { + if (framebuffer._attachments[attachments[i]] === renderbuffer) { + this.framebufferTexture2D( + gl.FRAMEBUFFER, + attachments[i] | 0, + gl.TEXTURE_2D, + null) + } + } + } + } + + _updateFramebufferAttachments (framebuffer) { + const prevStatus = framebuffer._status + const attachments = this._getAttachments() + framebuffer._status = this._preCheckFramebufferStatus(framebuffer) + if (framebuffer._status !== gl.FRAMEBUFFER_COMPLETE) { + if (prevStatus === gl.FRAMEBUFFER_COMPLETE) { + for (let i = 0; i < attachments.length; ++i) { + const attachmentEnum = attachments[i] + super.framebufferTexture2D( + gl.FRAMEBUFFER, + attachmentEnum, + framebuffer._attachmentFace[attachmentEnum], + 0, + framebuffer._attachmentLevel[attachmentEnum]) + } + } + return + } + + for (let i = 0; i < attachments.length; ++i) { + const attachmentEnum = attachments[i] + super.framebufferTexture2D( + gl.FRAMEBUFFER, + attachmentEnum, + framebuffer._attachmentFace[attachmentEnum], + 0, + framebuffer._attachmentLevel[attachmentEnum]) + } + + for (let i = 0; i < attachments.length; ++i) { + const attachmentEnum = attachments[i] + const attachment = framebuffer._attachments[attachmentEnum] + if (attachment instanceof WebGLTexture) { + super.framebufferTexture2D( + gl.FRAMEBUFFER, + attachmentEnum, + framebuffer._attachmentFace[attachmentEnum], + attachment._ | 0, + framebuffer._attachmentLevel[attachmentEnum]) + } else if (attachment instanceof WebGLRenderbuffer) { + super.framebufferRenderbuffer( + gl.FRAMEBUFFER, + attachmentEnum, + gl.RENDERBUFFER, + attachment._ | 0) + } + } + } + + _validBlendFunc (factor) { + return factor === gl.ZERO || + factor === gl.ONE || + factor === gl.SRC_COLOR || + factor === gl.ONE_MINUS_SRC_COLOR || + factor === gl.DST_COLOR || + factor === gl.ONE_MINUS_DST_COLOR || + factor === gl.SRC_ALPHA || + factor === gl.ONE_MINUS_SRC_ALPHA || + factor === gl.DST_ALPHA || + factor === gl.ONE_MINUS_DST_ALPHA || + factor === gl.SRC_ALPHA_SATURATE || + factor === gl.CONSTANT_COLOR || + factor === gl.ONE_MINUS_CONSTANT_COLOR || + factor === gl.CONSTANT_ALPHA || + factor === gl.ONE_MINUS_CONSTANT_ALPHA + } + + _validBlendMode (mode) { + return mode === gl.FUNC_ADD || + mode === gl.FUNC_SUBTRACT || + mode === gl.FUNC_REVERSE_SUBTRACT || + (this._extensions.ext_blend_minmax && ( + mode === this._extensions.ext_blend_minmax.MIN_EXT || + mode === this._extensions.ext_blend_minmax.MAX_EXT)) + } + + _validCubeTarget (target) { + return target === gl.TEXTURE_CUBE_MAP_POSITIVE_X || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_X || + target === gl.TEXTURE_CUBE_MAP_POSITIVE_Y || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_Y || + target === gl.TEXTURE_CUBE_MAP_POSITIVE_Z || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_Z + } + + _validFramebufferAttachment (attachment) { + switch (attachment) { + case gl.DEPTH_ATTACHMENT: + case gl.STENCIL_ATTACHMENT: + case gl.DEPTH_STENCIL_ATTACHMENT: + case gl.COLOR_ATTACHMENT0: + return true + } + + if (this._extensions.webgl_draw_buffers) { // eslint-disable-line + const { webgl_draw_buffers } = this._extensions; // eslint-disable-line + return attachment < (webgl_draw_buffers.COLOR_ATTACHMENT0_WEBGL + webgl_draw_buffers._maxDrawBuffers) // eslint-disable-line + } + + return false + } + + _validGLSLIdentifier (str) { + return !(str.indexOf('webgl_') === 0 || + str.indexOf('_webgl_') === 0 || + str.length > 256) + } + + _validTextureTarget (target) { + return target === gl.TEXTURE_2D || + target === gl.TEXTURE_CUBE_MAP + } + + _verifyTextureCompleteness (target, pname, param) { + const unit = this._getActiveTextureUnit() + let texture = null + if (target === gl.TEXTURE_2D) { + texture = unit._bind2D + } else if (this._validCubeTarget(target)) { + texture = unit._bindCube + } + + // oes_texture_float but not oes_texture_float_linear + if (this._extensions.oes_texture_float && !this._extensions.oes_texture_float_linear && texture && texture._type === gl.FLOAT && (pname === gl.TEXTURE_MAG_FILTER || pname === gl.TEXTURE_MIN_FILTER) && (param === gl.LINEAR || param === gl.LINEAR_MIPMAP_NEAREST || param === gl.NEAREST_MIPMAP_LINEAR || param === gl.LINEAR_MIPMAP_LINEAR)) { + texture._complete = false + this.bindTexture(target, texture) + return + } + + if (texture && texture._complete === false) { + texture._complete = true + this.bindTexture(target, texture) + } + } + + _wrapShader (type, source) { // eslint-disable-line + // the gl implementation seems to define `GL_OES_standard_derivatives` even when the extension is disabled + // this behaviour causes one conformance test ('GL_OES_standard_derivatives defined in shaders when extension is disabled') to fail + // by `undef`ing `GL_OES_standard_derivatives`, this appears to solve the issue + if (!this._extensions.oes_standard_derivatives && /#ifdef\s+GL_OES_standard_derivatives/.test(source)) { + source = '#undef GL_OES_standard_derivatives\n' + source + } + + return this._extensions.webgl_draw_buffers ? source : '#define gl_MaxDrawBuffers 1\n' + source // eslint-disable-line + } + + _beginAttrib0Hack () { + super.bindBuffer(gl.ARRAY_BUFFER, this._attrib0Buffer._) + super.bufferData( + gl.ARRAY_BUFFER, + this._vertexAttribs[0]._data, + gl.STREAM_DRAW) + super.enableVertexAttribArray(0) + super.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0) + super._vertexAttribDivisor(0, 1) + } + + _endAttrib0Hack () { + const attrib = this._vertexAttribs[0] + if (attrib._pointerBuffer) { + super.bindBuffer(gl.ARRAY_BUFFER, attrib._pointerBuffer._) + } else { + super.bindBuffer(gl.ARRAY_BUFFER, 0) + } + super.vertexAttribPointer( + 0, + attrib._inputSize, + attrib._pointerType, + attrib._pointerNormal, + attrib._inputStride, + attrib._pointerOffset) + super._vertexAttribDivisor(0, attrib._divisor) + super.disableVertexAttribArray(0) + if (this._activeArrayBuffer) { + super.bindBuffer(gl.ARRAY_BUFFER, this._activeArrayBuffer._) + } else { + super.bindBuffer(gl.ARRAY_BUFFER, 0) + } + } + + activeTexture (texture) { + texture |= 0 + const texNum = texture - gl.TEXTURE0 + if (texNum >= 0 && texNum < this._textureUnits.length) { + this._activeTextureUnit = texNum + return super.activeTexture(texture) + } + + this.setError(gl.INVALID_ENUM) + } + + attachShader (program, shader) { + if (!checkObject(program) || + !checkObject(shader)) { + throw new TypeError('attachShader(WebGLProgram, WebGLShader)') + } + if (!program || !shader) { + this.setError(gl.INVALID_VALUE) + return + } else if (program instanceof WebGLProgram && + shader instanceof WebGLShader && + this._checkOwns(program) && + this._checkOwns(shader)) { + if (!program._linked(shader)) { + this._saveError() + super.attachShader( + program._ | 0, + shader._ | 0) + const error = this.getError() + this._restoreError(error) + if (error === gl.NO_ERROR) { + program._link(shader) + } + return + } + } + this.setError(gl.INVALID_OPERATION) + } + + bindAttribLocation (program, index, name) { + if (!checkObject(program) || + typeof name !== 'string') { + throw new TypeError('bindAttribLocation(WebGLProgram, GLint, String)') + } + name += '' + if (!isValidString(name) || name.length > MAX_ATTRIBUTE_LENGTH) { + this.setError(gl.INVALID_VALUE) + } else if (/^_?webgl_a/.test(name)) { + this.setError(gl.INVALID_OPERATION) + } else if (this._checkWrapper(program, WebGLProgram)) { + return super.bindAttribLocation( + program._ | 0, + index | 0, + name) + } + } + + bindFramebuffer (target, framebuffer) { + if (!checkObject(framebuffer)) { + throw new TypeError('bindFramebuffer(GLenum, WebGLFramebuffer)') + } + if (target !== gl.FRAMEBUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + if (!framebuffer) { + super.bindFramebuffer( + gl.FRAMEBUFFER, + this._drawingBuffer._framebuffer) + } else if (framebuffer._pendingDelete) { + return + } else if (this._checkWrapper(framebuffer, WebGLFramebuffer)) { + super.bindFramebuffer( + gl.FRAMEBUFFER, + framebuffer._ | 0) + } else { + return + } + const activeFramebuffer = this._activeFramebuffer + if (activeFramebuffer !== framebuffer) { + if (activeFramebuffer) { + activeFramebuffer._refCount -= 1 + activeFramebuffer._checkDelete() + } + if (framebuffer) { + framebuffer._refCount += 1 + } + } + this._activeFramebuffer = framebuffer + if (framebuffer) { + this._updateFramebufferAttachments(framebuffer) + } + } + + bindBuffer (target, buffer) { + target |= 0 + if (!checkObject(buffer)) { + throw new TypeError('bindBuffer(GLenum, WebGLBuffer)') + } + if (target !== gl.ARRAY_BUFFER && + target !== gl.ELEMENT_ARRAY_BUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + if (!buffer) { + super.bindBuffer(target, 0) + } else if (buffer._pendingDelete) { + return + } else if (this._checkWrapper(buffer, WebGLBuffer)) { + if (buffer._binding && buffer._binding !== target) { + this.setError(gl.INVALID_OPERATION) + return + } + buffer._binding = target | 0 + + super.bindBuffer(target, buffer._ | 0) + } else { + return + } + + if (target === gl.ARRAY_BUFFER) { + this._switchActiveBuffer(this._activeArrayBuffer, buffer) + this._activeArrayBuffer = buffer + } else { + this._switchActiveBuffer(this._activeElementArrayBuffer, buffer) + this._activeElementArrayBuffer = buffer + } + } + + bindRenderbuffer (target, object) { + if (!checkObject(object)) { + throw new TypeError('bindRenderbuffer(GLenum, WebGLRenderbuffer)') + } + + if (target !== gl.RENDERBUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + if (!object) { + super.bindRenderbuffer( + target | 0, + 0) + } else if (object._pendingDelete) { + return + } else if (this._checkWrapper(object, WebGLRenderbuffer)) { + super.bindRenderbuffer( + target | 0, + object._ | 0) + } else { + return + } + const active = this._activeRenderbuffer + if (active !== object) { + if (active) { + active._refCount -= 1 + active._checkDelete() + } + if (object) { + object._refCount += 1 + } + } + this._activeRenderbuffer = object + } + + bindTexture (target, texture) { + target |= 0 + + if (!checkObject(texture)) { + throw new TypeError('bindTexture(GLenum, WebGLTexture)') + } + + if (!this._validTextureTarget(target)) { + this.setError(gl.INVALID_ENUM) + return + } + + // Get texture id + let textureId = 0 + if (!texture) { + texture = null + } else if (texture instanceof WebGLTexture && + texture._pendingDelete) { + // Special case: error codes for deleted textures don't get set for some dumb reason + return + } else if (this._checkWrapper(texture, WebGLTexture)) { + // Check binding mode of texture + if (texture._binding && texture._binding !== target) { + this.setError(gl.INVALID_OPERATION) + return + } + texture._binding = target + + if (texture._complete) { + textureId = texture._ | 0 + } + } else { + return + } + + this._saveError() + super.bindTexture( + target, + textureId) + const error = this.getError() + this._restoreError(error) + + if (error !== gl.NO_ERROR) { + return + } + + const activeUnit = this._getActiveTextureUnit() + const activeTex = this._getActiveTexture(target) + + // Update references + if (activeTex !== texture) { + if (activeTex) { + activeTex._refCount -= 1 + activeTex._checkDelete() + } + if (texture) { + texture._refCount += 1 + } + } + + if (target === gl.TEXTURE_2D) { + activeUnit._bind2D = texture + } else if (target === gl.TEXTURE_CUBE_MAP) { + activeUnit._bindCube = texture + } + } + + blendColor (red, green, blue, alpha) { + return super.blendColor(+red, +green, +blue, +alpha) + } + + blendEquation (mode) { + mode |= 0 + if (this._validBlendMode(mode)) { + return super.blendEquation(mode) + } + this.setError(gl.INVALID_ENUM) + } + + blendEquationSeparate (modeRGB, modeAlpha) { + modeRGB |= 0 + modeAlpha |= 0 + if (this._validBlendMode(modeRGB) && this._validBlendMode(modeAlpha)) { + return super.blendEquationSeparate(modeRGB, modeAlpha) + } + this.setError(gl.INVALID_ENUM) + } + + createBuffer () { + const id = super.createBuffer() + if (id <= 0) return null + const webGLBuffer = new WebGLBuffer(id, this) + this._buffers[id] = webGLBuffer + return webGLBuffer + } + + createFramebuffer () { + const id = super.createFramebuffer() + if (id <= 0) return null + const webGLFramebuffer = new WebGLFramebuffer(id, this) + this._framebuffers[id] = webGLFramebuffer + return webGLFramebuffer + } + + createProgram () { + const id = super.createProgram() + if (id <= 0) return null + const webGLProgram = new WebGLProgram(id, this) + this._programs[id] = webGLProgram + return webGLProgram + } + + createRenderbuffer () { + const id = super.createRenderbuffer() + if (id <= 0) return null + const webGLRenderbuffer = new WebGLRenderbuffer(id, this) + this._renderbuffers[id] = webGLRenderbuffer + return webGLRenderbuffer + } + + createTexture () { + const id = super.createTexture() + if (id <= 0) return null + const webGlTexture = new WebGLTexture(id, this) + this._textures[id] = webGlTexture + return webGlTexture + } + + getContextAttributes () { + return this._contextAttributes + } + + getExtension (name) { + const str = name.toLowerCase() + if (str in this._extensions) { + return this._extensions[str] + } + const ext = availableExtensions[str] ? availableExtensions[str](this) : null + if (ext) { + this._extensions[str] = ext + } + return ext + } + + getSupportedExtensions () { + const exts = [ + 'ANGLE_instanced_arrays', + 'STACKGL_resize_drawingbuffer', + 'STACKGL_destroy_context' + ] + + const supportedExts = super.getSupportedExtensions() + + if (supportedExts.indexOf('GL_OES_element_index_uint') >= 0) { + exts.push('OES_element_index_uint') + } + + if (supportedExts.indexOf('GL_OES_standard_derivatives') >= 0) { + exts.push('OES_standard_derivatives') + } + + if (supportedExts.indexOf('GL_OES_texture_float') >= 0) { + exts.push('OES_texture_float') + } + + if (supportedExts.indexOf('GL_OES_texture_float_linear') >= 0) { + exts.push('OES_texture_float_linear') + } + + if (supportedExts.indexOf('EXT_draw_buffers') >= 0) { + exts.push('WEBGL_draw_buffers') + } + + if (supportedExts.indexOf('EXT_blend_minmax') >= 0) { + exts.push('EXT_blend_minmax') + } + + if (supportedExts.indexOf('EXT_texture_filter_anisotropic') >= 0) { + exts.push('EXT_texture_filter_anisotropic') + } + + return exts + } + + setError (error) { + NativeWebGL.setError.call(this, error | 0) + } + + blendFunc (sfactor, dfactor) { + sfactor |= 0 + dfactor |= 0 + if (!this._validBlendFunc(sfactor) || + !this._validBlendFunc(dfactor)) { + this.setError(gl.INVALID_ENUM) + return + } + if (this._isConstantBlendFunc(sfactor) && this._isConstantBlendFunc(dfactor)) { + this.setError(gl.INVALID_OPERATION) + return + } + super.blendFunc(sfactor, dfactor) + } + + blendFuncSeparate ( + srcRGB, + dstRGB, + srcAlpha, + dstAlpha) { + srcRGB |= 0 + dstRGB |= 0 + srcAlpha |= 0 + dstAlpha |= 0 + + if (!(this._validBlendFunc(srcRGB) && + this._validBlendFunc(dstRGB) && + this._validBlendFunc(srcAlpha) && + this._validBlendFunc(dstAlpha))) { + this.setError(gl.INVALID_ENUM) + return + } + + if ((this._isConstantBlendFunc(srcRGB) && this._isConstantBlendFunc(dstRGB)) || + (this._isConstantBlendFunc(srcAlpha) && this._isConstantBlendFunc(dstAlpha))) { + this.setError(gl.INVALID_OPERATION) + return + } + + super.blendFuncSeparate( + srcRGB, + dstRGB, + srcAlpha, + dstAlpha) + } + + bufferData (target, data, usage) { + target |= 0 + usage |= 0 + if (usage !== gl.STREAM_DRAW && + usage !== gl.STATIC_DRAW && + usage !== gl.DYNAMIC_DRAW) { + this.setError(gl.INVALID_ENUM) + return + } + + if (target !== gl.ARRAY_BUFFER && + target !== gl.ELEMENT_ARRAY_BUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + const active = this._getActiveBuffer(target) + if (!active) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (typeof data === 'object') { + let u8Data = null + if (isTypedArray(data)) { + u8Data = unpackTypedArray(data) + } else if (data instanceof ArrayBuffer) { + u8Data = new Uint8Array(data) + } else { + this.setError(gl.INVALID_VALUE) + return + } + + this._saveError() + super.bufferData( + target, + u8Data, + usage) + const error = this.getError() + this._restoreError(error) + if (error !== gl.NO_ERROR) { + return + } + + active._size = u8Data.length + if (target === gl.ELEMENT_ARRAY_BUFFER) { + active._elements = new Uint8Array(u8Data) + } + } else if (typeof data === 'number') { + const size = data | 0 + if (size < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + this._saveError() + super.bufferData( + target, + size, + usage) + const error = this.getError() + this._restoreError(error) + if (error !== gl.NO_ERROR) { + return + } + + active._size = size + if (target === gl.ELEMENT_ARRAY_BUFFER) { + active._elements = new Uint8Array(size) + } + } else { + this.setError(gl.INVALID_VALUE) + } + } + + bufferSubData (target, offset, data) { + target |= 0 + offset |= 0 + + if (target !== gl.ARRAY_BUFFER && + target !== gl.ELEMENT_ARRAY_BUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + if (data === null) { + return + } + + if (!data || typeof data !== 'object') { + this.setError(gl.INVALID_VALUE) + return + } + + const active = this._getActiveBuffer(target) + if (!active) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (offset < 0 || offset >= active._size) { + this.setError(gl.INVALID_VALUE) + return + } + + let u8Data = null + if (isTypedArray(data)) { + u8Data = unpackTypedArray(data) + } else if (data instanceof ArrayBuffer) { + u8Data = new Uint8Array(data) + } else { + this.setError(gl.INVALID_VALUE) + return + } + + if (offset + u8Data.length > active._size) { + this.setError(gl.INVALID_VALUE) + return + } + + if (target === gl.ELEMENT_ARRAY_BUFFER) { + active._elements.set(u8Data, offset) + } + + super.bufferSubData( + target, + offset, + u8Data) + } + + checkFramebufferStatus (target) { + if (target !== gl.FRAMEBUFFER) { + this.setError(gl.INVALID_ENUM) + return 0 + } + + const framebuffer = this._activeFramebuffer + if (!framebuffer) { + return gl.FRAMEBUFFER_COMPLETE + } + + return this._preCheckFramebufferStatus(framebuffer) + } + + clear (mask) { + if (!this._framebufferOk()) { + return + } + return super.clear(mask | 0) + } + + clearColor (red, green, blue, alpha) { + return super.clearColor(+red, +green, +blue, +alpha) + } + + clearDepth (depth) { + return super.clearDepth(+depth) + } + + clearStencil (s) { + this._checkStencil = false + return super.clearStencil(s | 0) + } + + colorMask (red, green, blue, alpha) { + return super.colorMask(!!red, !!green, !!blue, !!alpha) + } + + compileShader (shader) { + if (!checkObject(shader)) { + throw new TypeError('compileShader(WebGLShader)') + } + if (this._checkWrapper(shader, WebGLShader) && + this._checkShaderSource(shader)) { + const prevError = this.getError() + super.compileShader(shader._ | 0) + const error = this.getError() + shader._compileStatus = !!super.getShaderParameter( + shader._ | 0, + gl.COMPILE_STATUS) + shader._compileInfo = super.getShaderInfoLog(shader._ | 0) + this.getError() + this.setError(prevError || error) + } + } + + copyTexImage2D ( + target, + level, + internalFormat, + x, y, width, height, + border) { + target |= 0 + level |= 0 + internalFormat |= 0 + x |= 0 + y |= 0 + width |= 0 + height |= 0 + border |= 0 + + const texture = this._getTexImage(target) + if (!texture) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (internalFormat !== gl.RGBA && + internalFormat !== gl.RGB && + internalFormat !== gl.ALPHA && + internalFormat !== gl.LUMINANCE && + internalFormat !== gl.LUMINANCE_ALPHA) { + this.setError(gl.INVALID_ENUM) + return + } + + if (level < 0 || width < 0 || height < 0 || border !== 0) { + this.setError(gl.INVALID_VALUE) + return + } + + if (level > 0 && !(bits.isPow2(width) && bits.isPow2(height))) { + this.setError(gl.INVALID_VALUE) + return + } + + this._saveError() + super.copyTexImage2D( + target, + level, + internalFormat, + x, + y, + width, + height, + border) + const error = this.getError() + this._restoreError(error) + + if (error === gl.NO_ERROR) { + texture._levelWidth[level] = width + texture._levelHeight[level] = height + texture._format = gl.RGBA + texture._type = gl.UNSIGNED_BYTE + } + } + + copyTexSubImage2D ( + target, + level, + xoffset, yoffset, + x, y, width, height) { + target |= 0 + level |= 0 + xoffset |= 0 + yoffset |= 0 + x |= 0 + y |= 0 + width |= 0 + height |= 0 + + const texture = this._getTexImage(target) + if (!texture) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (width < 0 || height < 0 || xoffset < 0 || yoffset < 0 || level < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + super.copyTexSubImage2D( + target, + level, + xoffset, + yoffset, + x, + y, + width, + height) + } + + cullFace (mode) { + return super.cullFace(mode | 0) + } + + createShader (type) { + type |= 0 + if (type !== gl.FRAGMENT_SHADER && + type !== gl.VERTEX_SHADER) { + this.setError(gl.INVALID_ENUM) + return null + } + const id = super.createShader(type) + if (id < 0) { + return null + } + const result = new WebGLShader(id, this, type) + this._shaders[id] = result + return result + } + + deleteProgram (object) { + return this._deleteLinkable('deleteProgram', object, WebGLProgram) + } + + deleteShader (object) { + return this._deleteLinkable('deleteShader', object, WebGLShader) + } + + _deleteLinkable (name, object, Type) { + if (!checkObject(object)) { + throw new TypeError(name + '(' + Type.name + ')') + } + if (object instanceof Type && + this._checkOwns(object)) { + object._pendingDelete = true + object._checkDelete() + return + } + this.setError(gl.INVALID_OPERATION) + } + + deleteBuffer (buffer) { + if (!checkObject(buffer) || + (buffer !== null && !(buffer instanceof WebGLBuffer))) { + throw new TypeError('deleteBuffer(WebGLBuffer)') + } + + if (!(buffer instanceof WebGLBuffer && + this._checkOwns(buffer))) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (this._activeArrayBuffer === buffer) { + this.bindBuffer(gl.ARRAY_BUFFER, null) + } + if (this._activeElementArrayBuffer === buffer) { + this.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null) + } + + for (let i = 0; i < this._vertexAttribs.length; ++i) { + const attrib = this._vertexAttribs[i] + if (attrib._pointerBuffer === buffer) { + attrib._pointerBuffer = null + attrib._pointerStride = 0 + attrib._pointerOffset = 0 + attrib._pointerSize = 4 + buffer._refCount -= 1 + } + } + + buffer._pendingDelete = true + buffer._checkDelete() + } + + deleteFramebuffer (framebuffer) { + if (!checkObject(framebuffer)) { + throw new TypeError('deleteFramebuffer(WebGLFramebuffer)') + } + + if (!(framebuffer instanceof WebGLFramebuffer && + this._checkOwns(framebuffer))) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (this._activeFramebuffer === framebuffer) { + this.bindFramebuffer(gl.FRAMEBUFFER, null) + } + + framebuffer._pendingDelete = true + framebuffer._checkDelete() + } + + // Need to handle textures and render buffers as a special case: + // When a texture gets deleted, we need to do the following extra steps: + // 1. Is it bound to the current texture unit? + // If so, then unbind it + // 2. Is it attached to the active fbo? + // If so, then detach it + // + // For renderbuffers only need to do second step + // + // After this, proceed with the usual deletion algorithm + // + deleteRenderbuffer (renderbuffer) { + if (!checkObject(renderbuffer)) { + throw new TypeError('deleteRenderbuffer(WebGLRenderbuffer)') + } + + if (!(renderbuffer instanceof WebGLRenderbuffer && + this._checkOwns(renderbuffer))) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (this._activeRenderbuffer === renderbuffer) { + this.bindRenderbuffer(gl.RENDERBUFFER, null) + } + + const activeFramebuffer = this._activeFramebuffer + + this._tryDetachFramebuffer(activeFramebuffer, renderbuffer) + + renderbuffer._pendingDelete = true + renderbuffer._checkDelete() + } + + deleteTexture (texture) { + if (!checkObject(texture)) { + throw new TypeError('deleteTexture(WebGLTexture)') + } + + if (texture instanceof WebGLTexture) { + if (!this._checkOwns(texture)) { + this.setError(gl.INVALID_OPERATION) + return + } + } else { + return + } + + // Unbind from all texture units + const curActive = this._activeTextureUnit + + for (let i = 0; i < this._textureUnits.length; ++i) { + const unit = this._textureUnits[i] + if (unit._bind2D === texture) { + this.activeTexture(gl.TEXTURE0 + i) + this.bindTexture(gl.TEXTURE_2D, null) + } else if (unit._bindCube === texture) { + this.activeTexture(gl.TEXTURE0 + i) + this.bindTexture(gl.TEXTURE_CUBE_MAP, null) + } + } + this.activeTexture(gl.TEXTURE0 + curActive) + + // FIXME: Does the texture get unbound from *all* framebuffers, or just the + // active FBO? + const ctx = this + const activeFramebuffer = this._activeFramebuffer + function tryDetach (framebuffer) { + if (framebuffer && framebuffer._linked(texture)) { + const attachments = ctx._getAttachments() + for (let i = 0; i < attachments.length; ++i) { + const attachment = attachments[i] + if (framebuffer._attachments[attachment] === texture) { + ctx.framebufferTexture2D( + gl.FRAMEBUFFER, + attachment, + gl.TEXTURE_2D, + null) + } + } + } + } + + tryDetach(activeFramebuffer) + + // Mark texture for deletion + texture._pendingDelete = true + texture._checkDelete() + } + + depthFunc (func) { + func |= 0 + switch (func) { + case gl.NEVER: + case gl.LESS: + case gl.EQUAL: + case gl.LEQUAL: + case gl.GREATER: + case gl.NOTEQUAL: + case gl.GEQUAL: + case gl.ALWAYS: + return super.depthFunc(func) + default: + this.setError(gl.INVALID_ENUM) + } + } + + depthMask (flag) { + return super.depthMask(!!flag) + } + + depthRange (zNear, zFar) { + zNear = +zNear + zFar = +zFar + if (zNear <= zFar) { + return super.depthRange(zNear, zFar) + } + this.setError(gl.INVALID_OPERATION) + } + + destroy () { + super.destroy() + } + + detachShader (program, shader) { + if (!checkObject(program) || + !checkObject(shader)) { + throw new TypeError('detachShader(WebGLProgram, WebGLShader)') + } + if (this._checkWrapper(program, WebGLProgram) && + this._checkWrapper(shader, WebGLShader)) { + if (program._linked(shader)) { + super.detachShader(program._, shader._) + program._unlink(shader) + } else { + this.setError(gl.INVALID_OPERATION) + } + } + } + + disable (cap) { + cap |= 0 + super.disable(cap) + if (cap === gl.TEXTURE_2D || + cap === gl.TEXTURE_CUBE_MAP) { + const active = this._getActiveTextureUnit() + if (active._mode === cap) { + active._mode = 0 + } + } + } + + disableVertexAttribArray (index) { + index |= 0 + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return + } + super.disableVertexAttribArray(index) + this._vertexAttribs[index]._isPointer = false + } + + drawArrays (mode, first, count) { + mode |= 0 + first |= 0 + count |= 0 + + if (first < 0 || count < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + if (!this._checkStencilState()) { + return + } + + const reducedCount = vertexCount(mode, count) + if (reducedCount < 0) { + this.setError(gl.INVALID_ENUM) + return + } + + if (!this._framebufferOk()) { + return + } + + if (count === 0) { + return + } + + let maxIndex = first + if (count > 0) { + maxIndex = (count + first - 1) >>> 0 + } + if (this._checkVertexAttribState(maxIndex)) { + if ( + this._vertexAttribs[0]._isPointer || ( + this._extensions.webgl_draw_buffers && + this._extensions.webgl_draw_buffers._buffersState && + this._extensions.webgl_draw_buffers._buffersState.length > 0 + ) + ) { + return super.drawArrays(mode, first, reducedCount) + } else { + this._beginAttrib0Hack() + super._drawArraysInstanced(mode, first, reducedCount, 1) + this._endAttrib0Hack() + } + } + } + + drawElements (mode, count, type, ioffset) { + mode |= 0 + count |= 0 + type |= 0 + ioffset |= 0 + + if (count < 0 || ioffset < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + if (!this._checkStencilState()) { + return + } + + const elementBuffer = this._activeElementArrayBuffer + if (!elementBuffer) { + this.setError(gl.INVALID_OPERATION) + return + } + + // Unpack element data + let elementData = null + let offset = ioffset + if (type === gl.UNSIGNED_SHORT) { + if (offset % 2) { + this.setError(gl.INVALID_OPERATION) + return + } + offset >>= 1 + elementData = new Uint16Array(elementBuffer._elements.buffer) + } else if (this._extensions.oes_element_index_uint && type === gl.UNSIGNED_INT) { + if (offset % 4) { + this.setError(gl.INVALID_OPERATION) + return + } + offset >>= 2 + elementData = new Uint32Array(elementBuffer._elements.buffer) + } else if (type === gl.UNSIGNED_BYTE) { + elementData = elementBuffer._elements + } else { + this.setError(gl.INVALID_ENUM) + return + } + + let reducedCount = count + switch (mode) { + case gl.TRIANGLES: + if (count % 3) { + reducedCount -= (count % 3) + } + break + case gl.LINES: + if (count % 2) { + reducedCount -= (count % 2) + } + break + case gl.POINTS: + break + case gl.LINE_LOOP: + case gl.LINE_STRIP: + if (count < 2) { + this.setError(gl.INVALID_OPERATION) + return + } + break + case gl.TRIANGLE_FAN: + case gl.TRIANGLE_STRIP: + if (count < 3) { + this.setError(gl.INVALID_OPERATION) + return + } + break + default: + this.setError(gl.INVALID_ENUM) + return + } + + if (!this._framebufferOk()) { + return + } + + if (count === 0) { + this._checkVertexAttribState(0) + return + } + + if ((count + offset) >>> 0 > elementData.length) { + this.setError(gl.INVALID_OPERATION) + return + } + + // Compute max index + let maxIndex = -1 + for (let i = offset; i < offset + count; ++i) { + maxIndex = Math.max(maxIndex, elementData[i]) + } + + if (maxIndex < 0) { + this._checkVertexAttribState(0) + return + } + + if (this._checkVertexAttribState(maxIndex)) { + if (reducedCount > 0) { + if (this._vertexAttribs[0]._isPointer) { + return super.drawElements(mode, reducedCount, type, ioffset) + } else { + this._beginAttrib0Hack() + super._drawElementsInstanced(mode, reducedCount, type, ioffset, 1) + this._endAttrib0Hack() + } + } + } + } + + enable (cap) { + cap |= 0 + super.enable(cap) + } + + enableVertexAttribArray (index) { + index |= 0 + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return + } + + super.enableVertexAttribArray(index) + + this._vertexAttribs[index]._isPointer = true + } + + finish () { + return super.finish() + } + + flush () { + return super.flush() + } + + framebufferRenderbuffer ( + target, + attachment, + renderbufferTarget, + renderbuffer) { + target = target | 0 + attachment = attachment | 0 + renderbufferTarget = renderbufferTarget | 0 + + if (!checkObject(renderbuffer)) { + throw new TypeError('framebufferRenderbuffer(GLenum, GLenum, GLenum, WebGLRenderbuffer)') + } + + if (target !== gl.FRAMEBUFFER || + !this._validFramebufferAttachment(attachment) || + renderbufferTarget !== gl.RENDERBUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + const framebuffer = this._activeFramebuffer + if (!framebuffer) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (renderbuffer && !this._checkWrapper(renderbuffer, WebGLRenderbuffer)) { + return + } + + framebuffer._setAttachment(renderbuffer, attachment) + this._updateFramebufferAttachments(framebuffer) + } + + framebufferTexture2D ( + target, + attachment, + textarget, + texture, + level) { + target |= 0 + attachment |= 0 + textarget |= 0 + level |= 0 + if (!checkObject(texture)) { + throw new TypeError('framebufferTexture2D(GLenum, GLenum, GLenum, WebGLTexture, GLint)') + } + + // Check parameters are ok + if (target !== gl.FRAMEBUFFER || + !this._validFramebufferAttachment(attachment)) { + this.setError(gl.INVALID_ENUM) + return + } + + if (level !== 0) { + this.setError(gl.INVALID_VALUE) + return + } + + // Check object ownership + if (texture && !this._checkWrapper(texture, WebGLTexture)) { + return + } + + // Check texture target is ok + if (textarget === gl.TEXTURE_2D) { + if (texture && texture._binding !== gl.TEXTURE_2D) { + this.setError(gl.INVALID_OPERATION) + return + } + } else if (this._validCubeTarget(textarget)) { + if (texture && texture._binding !== gl.TEXTURE_CUBE_MAP) { + this.setError(gl.INVALID_OPERATION) + return + } + } else { + this.setError(gl.INVALID_ENUM) + return + } + + // Check a framebuffer is actually bound + const framebuffer = this._activeFramebuffer + if (!framebuffer) { + this.setError(gl.INVALID_OPERATION) + return + } + + framebuffer._attachmentLevel[attachment] = level + framebuffer._attachmentFace[attachment] = textarget + framebuffer._setAttachment(texture, attachment) + this._updateFramebufferAttachments(framebuffer) + } + + frontFace (mode) { + return super.frontFace(mode | 0) + } + + generateMipmap (target) { + return super.generateMipmap(target | 0) | 0 + } + + getActiveAttrib (program, index) { + if (!checkObject(program)) { + throw new TypeError('getActiveAttrib(WebGLProgram)') + } else if (!program) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(program, WebGLProgram)) { + const info = super.getActiveAttrib(program._ | 0, index | 0) + if (info) { + return new WebGLActiveInfo(info) + } + } + return null + } + + getActiveUniform (program, index) { + if (!checkObject(program)) { + throw new TypeError('getActiveUniform(WebGLProgram, GLint)') + } else if (!program) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(program, WebGLProgram)) { + const info = super.getActiveUniform(program._ | 0, index | 0) + if (info) { + return new WebGLActiveInfo(info) + } + } + return null + } + + getAttachedShaders (program) { + if (!checkObject(program) || + (typeof program === 'object' && + program !== null && + !(program instanceof WebGLProgram))) { + throw new TypeError('getAttachedShaders(WebGLProgram)') + } + if (!program) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(program, WebGLProgram)) { + const shaderArray = super.getAttachedShaders(program._ | 0) + if (!shaderArray) { + return null + } + const unboxedShaders = new Array(shaderArray.length) + for (let i = 0; i < shaderArray.length; ++i) { + unboxedShaders[i] = this._shaders[shaderArray[i]] + } + return unboxedShaders + } + return null + } + + getAttribLocation (program, name) { + if (!checkObject(program)) { + throw new TypeError('getAttribLocation(WebGLProgram, String)') + } + name += '' + if (!isValidString(name) || name.length > MAX_ATTRIBUTE_LENGTH) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(program, WebGLProgram)) { + return super.getAttribLocation(program._ | 0, name + '') + } + return -1 + } + + getParameter (pname) { + pname |= 0 + switch (pname) { + case gl.ARRAY_BUFFER_BINDING: + return this._activeArrayBuffer + case gl.ELEMENT_ARRAY_BUFFER_BINDING: + return this._activeElementArrayBuffer + case gl.CURRENT_PROGRAM: + return this._activeProgram + case gl.FRAMEBUFFER_BINDING: + return this._activeFramebuffer + case gl.RENDERBUFFER_BINDING: + return this._activeRenderbuffer + case gl.TEXTURE_BINDING_2D: + return this._getActiveTextureUnit()._bind2D + case gl.TEXTURE_BINDING_CUBE_MAP: + return this._getActiveTextureUnit()._bindCube + case gl.VERSION: + return 'WebGL 1.0 stack-gl ' + HEADLESS_VERSION + case gl.VENDOR: + return 'stack-gl' + case gl.RENDERER: + return 'ANGLE' + case gl.SHADING_LANGUAGE_VERSION: + return 'WebGL GLSL ES 1.0 stack-gl' + + case gl.COMPRESSED_TEXTURE_FORMATS: + return new Uint32Array(0) + + // Int arrays + case gl.MAX_VIEWPORT_DIMS: + case gl.SCISSOR_BOX: + case gl.VIEWPORT: + return new Int32Array(super.getParameter(pname)) + + // Float arrays + case gl.ALIASED_LINE_WIDTH_RANGE: + case gl.ALIASED_POINT_SIZE_RANGE: + case gl.DEPTH_RANGE: + case gl.BLEND_COLOR: + case gl.COLOR_CLEAR_VALUE: + return new Float32Array(super.getParameter(pname)) + + case gl.COLOR_WRITEMASK: + return super.getParameter(pname) + + case gl.DEPTH_CLEAR_VALUE: + case gl.LINE_WIDTH: + case gl.POLYGON_OFFSET_FACTOR: + case gl.POLYGON_OFFSET_UNITS: + case gl.SAMPLE_COVERAGE_VALUE: + return +super.getParameter(pname) + + case gl.BLEND: + case gl.CULL_FACE: + case gl.DEPTH_TEST: + case gl.DEPTH_WRITEMASK: + case gl.DITHER: + case gl.POLYGON_OFFSET_FILL: + case gl.SAMPLE_COVERAGE_INVERT: + case gl.SCISSOR_TEST: + case gl.STENCIL_TEST: + case gl.UNPACK_FLIP_Y_WEBGL: + case gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL: + return !!super.getParameter(pname) + + case gl.ACTIVE_TEXTURE: + case gl.ALPHA_BITS: + case gl.BLEND_DST_ALPHA: + case gl.BLEND_DST_RGB: + case gl.BLEND_EQUATION_ALPHA: + case gl.BLEND_EQUATION_RGB: + case gl.BLEND_SRC_ALPHA: + case gl.BLEND_SRC_RGB: + case gl.BLUE_BITS: + case gl.CULL_FACE_MODE: + case gl.DEPTH_BITS: + case gl.DEPTH_FUNC: + case gl.FRONT_FACE: + case gl.GENERATE_MIPMAP_HINT: + case gl.GREEN_BITS: + case gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS: + case gl.MAX_CUBE_MAP_TEXTURE_SIZE: + case gl.MAX_FRAGMENT_UNIFORM_VECTORS: + case gl.MAX_RENDERBUFFER_SIZE: + case gl.MAX_TEXTURE_IMAGE_UNITS: + case gl.MAX_TEXTURE_SIZE: + case gl.MAX_VARYING_VECTORS: + case gl.MAX_VERTEX_ATTRIBS: + case gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS: + case gl.MAX_VERTEX_UNIFORM_VECTORS: + case gl.PACK_ALIGNMENT: + case gl.RED_BITS: + case gl.SAMPLE_BUFFERS: + case gl.SAMPLES: + case gl.STENCIL_BACK_FAIL: + case gl.STENCIL_BACK_FUNC: + case gl.STENCIL_BACK_PASS_DEPTH_FAIL: + case gl.STENCIL_BACK_PASS_DEPTH_PASS: + case gl.STENCIL_BACK_REF: + case gl.STENCIL_BACK_VALUE_MASK: + case gl.STENCIL_BACK_WRITEMASK: + case gl.STENCIL_BITS: + case gl.STENCIL_CLEAR_VALUE: + case gl.STENCIL_FAIL: + case gl.STENCIL_FUNC: + case gl.STENCIL_PASS_DEPTH_FAIL: + case gl.STENCIL_PASS_DEPTH_PASS: + case gl.STENCIL_REF: + case gl.STENCIL_VALUE_MASK: + case gl.STENCIL_WRITEMASK: + case gl.SUBPIXEL_BITS: + case gl.UNPACK_ALIGNMENT: + case gl.UNPACK_COLORSPACE_CONVERSION_WEBGL: + return super.getParameter(pname) | 0 + + case gl.IMPLEMENTATION_COLOR_READ_FORMAT: + case gl.IMPLEMENTATION_COLOR_READ_TYPE: + return super.getParameter(pname) + + default: + if (this._extensions.webgl_draw_buffers) { + const ext = this._extensions.webgl_draw_buffers + switch (pname) { + case ext.DRAW_BUFFER0_WEBGL: + case ext.DRAW_BUFFER1_WEBGL: + case ext.DRAW_BUFFER2_WEBGL: + case ext.DRAW_BUFFER3_WEBGL: + case ext.DRAW_BUFFER4_WEBGL: + case ext.DRAW_BUFFER5_WEBGL: + case ext.DRAW_BUFFER6_WEBGL: + case ext.DRAW_BUFFER7_WEBGL: + case ext.DRAW_BUFFER8_WEBGL: + case ext.DRAW_BUFFER9_WEBGL: + case ext.DRAW_BUFFER10_WEBGL: + case ext.DRAW_BUFFER11_WEBGL: + case ext.DRAW_BUFFER12_WEBGL: + case ext.DRAW_BUFFER13_WEBGL: + case ext.DRAW_BUFFER14_WEBGL: + case ext.DRAW_BUFFER15_WEBGL: + if (ext._buffersState.length === 1 && ext._buffersState[0] === gl.BACK) { + return gl.BACK + } + return super.getParameter(pname) + case ext.MAX_DRAW_BUFFERS_WEBGL: + case ext.MAX_COLOR_ATTACHMENTS_WEBGL: + return super.getParameter(pname) + } + } + + if (this._extensions.oes_standard_derivatives && pname === this._extensions.oes_standard_derivatives.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) { + return super.getParameter(pname) + } + + if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT) { + return super.getParameter(pname) + } + + this.setError(gl.INVALID_ENUM) + return null + } + } + + getShaderPrecisionFormat ( + shaderType, + precisionType) { + shaderType |= 0 + precisionType |= 0 + + if (!(shaderType === gl.FRAGMENT_SHADER || + shaderType === gl.VERTEX_SHADER) || + !(precisionType === gl.LOW_FLOAT || + precisionType === gl.MEDIUM_FLOAT || + precisionType === gl.HIGH_FLOAT || + precisionType === gl.LOW_INT || + precisionType === gl.MEDIUM_INT || + precisionType === gl.HIGH_INT)) { + this.setError(gl.INVALID_ENUM) + return + } + + const format = super.getShaderPrecisionFormat(shaderType, precisionType) + if (!format) { + return null + } + + return new WebGLShaderPrecisionFormat(format) + } + + getBufferParameter (target, pname) { + target |= 0 + pname |= 0 + if (target !== gl.ARRAY_BUFFER && + target !== gl.ELEMENT_ARRAY_BUFFER) { + this.setError(gl.INVALID_ENUM) + return null + } + + switch (pname) { + case gl.BUFFER_SIZE: + case gl.BUFFER_USAGE: + return super.getBufferParameter(target | 0, pname | 0) + default: + this.setError(gl.INVALID_ENUM) + return null + } + } + + getError () { + return super.getError() + } + + getFramebufferAttachmentParameter (target, attachment, pname) { + target |= 0 + attachment |= 0 + pname |= 0 + + if (target !== gl.FRAMEBUFFER || + !this._validFramebufferAttachment(attachment)) { + this.setError(gl.INVALID_ENUM) + return null + } + + const framebuffer = this._activeFramebuffer + if (!framebuffer) { + this.setError(gl.INVALID_OPERATION) + return null + } + + const object = framebuffer._attachments[attachment] + if (object === null) { + if (pname === gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) { + return gl.NONE + } + } else if (object instanceof WebGLTexture) { + switch (pname) { + case gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + return object + case gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + return gl.TEXTURE + case gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + return framebuffer._attachmentLevel[attachment] + case gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: { + const face = framebuffer._attachmentFace[attachment] + if (face === gl.TEXTURE_2D) { + return 0 + } + return face + } + } + } else if (object instanceof WebGLRenderbuffer) { + switch (pname) { + case gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + return object + case gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + return gl.RENDERBUFFER + } + } + + this.setError(gl.INVALID_ENUM) + return null + } + + getProgramParameter (program, pname) { + pname |= 0 + if (!checkObject(program)) { + throw new TypeError('getProgramParameter(WebGLProgram, GLenum)') + } else if (this._checkWrapper(program, WebGLProgram)) { + switch (pname) { + case gl.DELETE_STATUS: + return program._pendingDelete + + case gl.LINK_STATUS: + return program._linkStatus + + case gl.VALIDATE_STATUS: + return !!super.getProgramParameter(program._, pname) + + case gl.ATTACHED_SHADERS: + case gl.ACTIVE_ATTRIBUTES: + case gl.ACTIVE_UNIFORMS: + return super.getProgramParameter(program._, pname) + } + this.setError(gl.INVALID_ENUM) + } + return null + } + + getProgramInfoLog (program) { + if (!checkObject(program)) { + throw new TypeError('getProgramInfoLog(WebGLProgram)') + } else if (this._checkWrapper(program, WebGLProgram)) { + return program._linkInfoLog + } + return null + } + + getRenderbufferParameter (target, pname) { + target |= 0 + pname |= 0 + if (target !== gl.RENDERBUFFER) { + this.setError(gl.INVALID_ENUM) + return null + } + const renderbuffer = this._activeRenderbuffer + if (!renderbuffer) { + this.setError(gl.INVALID_OPERATION) + return null + } + switch (pname) { + case gl.RENDERBUFFER_INTERNAL_FORMAT: + return renderbuffer._format + case gl.RENDERBUFFER_WIDTH: + return renderbuffer._width + case gl.RENDERBUFFER_HEIGHT: + return renderbuffer._height + case gl.RENDERBUFFER_SIZE: + case gl.RENDERBUFFER_RED_SIZE: + case gl.RENDERBUFFER_GREEN_SIZE: + case gl.RENDERBUFFER_BLUE_SIZE: + case gl.RENDERBUFFER_ALPHA_SIZE: + case gl.RENDERBUFFER_DEPTH_SIZE: + case gl.RENDERBUFFER_STENCIL_SIZE: + return super.getRenderbufferParameter(target, pname) + } + this.setError(gl.INVALID_ENUM) + return null + } + + getShaderParameter (shader, pname) { + pname |= 0 + if (!checkObject(shader)) { + throw new TypeError('getShaderParameter(WebGLShader, GLenum)') + } else if (this._checkWrapper(shader, WebGLShader)) { + switch (pname) { + case gl.DELETE_STATUS: + return shader._pendingDelete + case gl.COMPILE_STATUS: + return shader._compileStatus + case gl.SHADER_TYPE: + return shader._type + } + this.setError(gl.INVALID_ENUM) + } + return null + } + + getShaderInfoLog (shader) { + if (!checkObject(shader)) { + throw new TypeError('getShaderInfoLog(WebGLShader)') + } else if (this._checkWrapper(shader, WebGLShader)) { + return shader._compileInfo + } + return null + } + + getShaderSource (shader) { + if (!checkObject(shader)) { + throw new TypeError('Input to getShaderSource must be an object') + } else if (this._checkWrapper(shader, WebGLShader)) { + return shader._source + } + return null + } + + getTexParameter (target, pname) { + target |= 0 + pname |= 0 + + if (!this._checkTextureTarget(target)) { + return null + } + + const unit = this._getActiveTextureUnit() + if ((target === gl.TEXTURE_2D && !unit._bind2D) || + (target === gl.TEXTURE_CUBE_MAP && !unit._bindCube)) { + this.setError(gl.INVALID_OPERATION) + return null + } + + switch (pname) { + case gl.TEXTURE_MAG_FILTER: + case gl.TEXTURE_MIN_FILTER: + case gl.TEXTURE_WRAP_S: + case gl.TEXTURE_WRAP_T: + return super.getTexParameter(target, pname) + } + + if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) { + return super.getTexParameter(target, pname) + } + + this.setError(gl.INVALID_ENUM) + return null + } + + getUniform (program, location) { + if (!checkObject(program) || + !checkObject(location)) { + throw new TypeError('getUniform(WebGLProgram, WebGLUniformLocation)') + } else if (!program) { + this.setError(gl.INVALID_VALUE) + return null + } else if (!location) { + return null + } else if (this._checkWrapper(program, WebGLProgram)) { + if (!checkUniform(program, location)) { + this.setError(gl.INVALID_OPERATION) + return null + } + const data = super.getUniform(program._ | 0, location._ | 0) + if (!data) { + return null + } + switch (location._activeInfo.type) { + case gl.FLOAT: + return data[0] + case gl.FLOAT_VEC2: + return new Float32Array(data.slice(0, 2)) + case gl.FLOAT_VEC3: + return new Float32Array(data.slice(0, 3)) + case gl.FLOAT_VEC4: + return new Float32Array(data.slice(0, 4)) + case gl.INT: + return data[0] | 0 + case gl.INT_VEC2: + return new Int32Array(data.slice(0, 2)) + case gl.INT_VEC3: + return new Int32Array(data.slice(0, 3)) + case gl.INT_VEC4: + return new Int32Array(data.slice(0, 4)) + case gl.BOOL: + return !!data[0] + case gl.BOOL_VEC2: + return [!!data[0], !!data[1]] + case gl.BOOL_VEC3: + return [!!data[0], !!data[1], !!data[2]] + case gl.BOOL_VEC4: + return [!!data[0], !!data[1], !!data[2], !!data[3]] + case gl.FLOAT_MAT2: + return new Float32Array(data.slice(0, 4)) + case gl.FLOAT_MAT3: + return new Float32Array(data.slice(0, 9)) + case gl.FLOAT_MAT4: + return new Float32Array(data.slice(0, 16)) + case gl.SAMPLER_2D: + case gl.SAMPLER_CUBE: + return data[0] | 0 + default: + return null + } + } + return null + } + + getUniformLocation (program, name) { + if (!checkObject(program)) { + throw new TypeError('getUniformLocation(WebGLProgram, String)') + } + + name += '' + if (!isValidString(name)) { + this.setError(gl.INVALID_VALUE) + return + } + + if (this._checkWrapper(program, WebGLProgram)) { + const loc = super.getUniformLocation(program._ | 0, name) + if (loc >= 0) { + let searchName = name + if (/\[\d+\]$/.test(name)) { + searchName = name.replace(/\[\d+\]$/, '[0]') + } + + let info = null + for (let i = 0; i < program._uniforms.length; ++i) { + const infoItem = program._uniforms[i] + if (infoItem.name === searchName) { + info = { + size: infoItem.size, + type: infoItem.type, + name: infoItem.name + } + } + } + if (!info) { + return null + } + + const result = new WebGLUniformLocation( + loc, + program, + info) + + // handle array case + if (/\[0\]$/.test(name)) { + const baseName = name.replace(/\[0\]$/, '') + const arrayLocs = [] + + // if (offset < 0 || offset >= info.size) { + // return null + // } + + this._saveError() + for (let i = 0; this.getError() === gl.NO_ERROR; ++i) { + const xloc = super.getUniformLocation( + program._ | 0, + baseName + '[' + i + ']') + if (this.getError() !== gl.NO_ERROR || xloc < 0) { + break + } + arrayLocs.push(xloc) + } + this._restoreError(gl.NO_ERROR) + + result._array = arrayLocs + } else if (/\[(\d+)\]$/.test(name)) { + const offset = +(/\[(\d+)\]$/.exec(name))[1] + if (offset < 0 || offset >= info.size) { + return null + } + } + return result + } + } + return null + } + + getVertexAttrib (index, pname) { + index |= 0 + pname |= 0 + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return null + } + const attrib = this._vertexAttribs[index] + + const extInstancing = this._extensions.angle_instanced_arrays + if (extInstancing) { + if (pname === extInstancing.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE) { + return attrib._divisor + } + } + + switch (pname) { + case gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + return attrib._pointerBuffer + case gl.VERTEX_ATTRIB_ARRAY_ENABLED: + return attrib._isPointer + case gl.VERTEX_ATTRIB_ARRAY_SIZE: + return attrib._inputSize + case gl.VERTEX_ATTRIB_ARRAY_STRIDE: + return attrib._inputStride + case gl.VERTEX_ATTRIB_ARRAY_TYPE: + return attrib._pointerType + case gl.VERTEX_ATTRIB_ARRAY_NORMALIZED: + return attrib._pointerNormal + case gl.CURRENT_VERTEX_ATTRIB: + return new Float32Array(attrib._data) + default: + this.setError(gl.INVALID_ENUM) + return null + } + } + + getVertexAttribOffset (index, pname) { + index |= 0 + pname |= 0 + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return null + } + if (pname === gl.VERTEX_ATTRIB_ARRAY_POINTER) { + return this._vertexAttribs[index]._pointerOffset + } else { + this.setError(gl.INVALID_ENUM) + return null + } + } + + hint (target, mode) { + target |= 0 + mode |= 0 + + if (!( + target === gl.GENERATE_MIPMAP_HINT || + ( + this._extensions.oes_standard_derivatives && target === this._extensions.oes_standard_derivatives.FRAGMENT_SHADER_DERIVATIVE_HINT_OES + ) + )) { + this.setError(gl.INVALID_ENUM) + return + } + + if (mode !== gl.FASTEST && + mode !== gl.NICEST && + mode !== gl.DONT_CARE) { + this.setError(gl.INVALID_ENUM) + return + } + + return super.hint(target, mode) + } + + isBuffer (object) { + if (!this._isObject(object, 'isBuffer', WebGLBuffer)) return false + return super.isBuffer(object._ | 0) + } + + isFramebuffer (object) { + if (!this._isObject(object, 'isFramebuffer', WebGLFramebuffer)) return false + return super.isFramebuffer(object._ | 0) + } + + isProgram (object) { + if (!this._isObject(object, 'isProgram', WebGLProgram)) return false + return super.isProgram(object._ | 0) + } + + isRenderbuffer (object) { + if (!this._isObject(object, 'isRenderbuffer', WebGLRenderbuffer)) return false + return super.isRenderbuffer(object._ | 0) + } + + isShader (object) { + if (!this._isObject(object, 'isShader', WebGLShader)) return false + return super.isShader(object._ | 0) + } + + isTexture (object) { + if (!this._isObject(object, 'isTexture', WebGLTexture)) return false + return super.isTexture(object._ | 0) + } + + isEnabled (cap) { + return super.isEnabled(cap | 0) + } + + lineWidth (width) { + if (isNaN(width)) { + this.setError(gl.INVALID_VALUE) + return + } + return super.lineWidth(+width) + } + + linkProgram (program) { + if (!checkObject(program)) { + throw new TypeError('linkProgram(WebGLProgram)') + } + if (this._checkWrapper(program, WebGLProgram)) { + program._linkCount += 1 + program._attributes = [] + const prevError = this.getError() + super.linkProgram(program._ | 0) + const error = this.getError() + if (error === gl.NO_ERROR) { + program._linkStatus = this._fixupLink(program) + } + this.getError() + this.setError(prevError || error) + } + } + + pixelStorei (pname, param) { + pname |= 0 + param |= 0 + if (pname === gl.UNPACK_ALIGNMENT) { + if (param === 1 || + param === 2 || + param === 4 || + param === 8) { + this._unpackAlignment = param + } else { + this.setError(gl.INVALID_VALUE) + return + } + } else if (pname === gl.PACK_ALIGNMENT) { + if (param === 1 || + param === 2 || + param === 4 || + param === 8) { + this._packAlignment = param + } else { + this.setError(gl.INVALID_VALUE) + return + } + } else if (pname === gl.UNPACK_COLORSPACE_CONVERSION_WEBGL) { + if (!(param === gl.NONE || param === gl.BROWSER_DEFAULT_WEBGL)) { + this.setError(gl.INVALID_VALUE) + return + } + } + return super.pixelStorei(pname, param) + } + + polygonOffset (factor, units) { + return super.polygonOffset(+factor, +units) + } + + readPixels (x, y, width, height, format, type, pixels) { + x |= 0 + y |= 0 + width |= 0 + height |= 0 + + if (this._extensions.oes_texture_float && type === gl.FLOAT && format === gl.RGBA) { + } else if (format === gl.RGB || + format === gl.ALPHA || + type !== gl.UNSIGNED_BYTE) { + this.setError(gl.INVALID_OPERATION) + return + } else if (format !== gl.RGBA) { + this.setError(gl.INVALID_ENUM) + return + } else if ( + width < 0 || + height < 0 || + !(pixels instanceof Uint8Array)) { + this.setError(gl.INVALID_VALUE) + return + } + + if (!this._framebufferOk()) { + return + } + + let rowStride = width * 4 + if (rowStride % this._packAlignment !== 0) { + rowStride += this._packAlignment - (rowStride % this._packAlignment) + } + + const imageSize = rowStride * (height - 1) + width * 4 + if (imageSize <= 0) { + return + } + if (pixels.length < imageSize) { + this.setError(gl.INVALID_VALUE) + return + } + + // Handle reading outside the window + let viewWidth = this.drawingBufferWidth + let viewHeight = this.drawingBufferHeight + + if (this._activeFramebuffer) { + viewWidth = this._activeFramebuffer._width + viewHeight = this._activeFramebuffer._height + } + + const pixelData = unpackTypedArray(pixels) + + if (x >= viewWidth || x + width <= 0 || + y >= viewHeight || y + height <= 0) { + for (let i = 0; i < pixelData.length; ++i) { + pixelData[i] = 0 + } + } else if (x < 0 || x + width > viewWidth || + y < 0 || y + height > viewHeight) { + for (let i = 0; i < pixelData.length; ++i) { + pixelData[i] = 0 + } + + let nx = x + let nWidth = width + if (x < 0) { + nWidth += x + nx = 0 + } + if (nx + width > viewWidth) { + nWidth = viewWidth - nx + } + let ny = y + let nHeight = height + if (y < 0) { + nHeight += y + ny = 0 + } + if (ny + height > viewHeight) { + nHeight = viewHeight - ny + } + + let nRowStride = nWidth * 4 + if (nRowStride % this._packAlignment !== 0) { + nRowStride += this._packAlignment - (nRowStride % this._packAlignment) + } + + if (nWidth > 0 && nHeight > 0) { + const subPixels = new Uint8Array(nRowStride * nHeight) + super.readPixels( + nx, + ny, + nWidth, + nHeight, + format, + type, + subPixels) + + const offset = 4 * (nx - x) + (ny - y) * rowStride + for (let j = 0; j < nHeight; ++j) { + for (let i = 0; i < nWidth; ++i) { + for (let k = 0; k < 4; ++k) { + pixelData[offset + j * rowStride + 4 * i + k] = + subPixels[j * nRowStride + 4 * i + k] + } + } + } + } + } else { + super.readPixels( + x, + y, + width, + height, + format, + type, + pixelData) + } + } + + renderbufferStorage ( + target, + internalFormat, + width, + height) { + target |= 0 + internalFormat |= 0 + width |= 0 + height |= 0 + + if (target !== gl.RENDERBUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + const renderbuffer = this._activeRenderbuffer + if (!renderbuffer) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (internalFormat !== gl.RGBA4 && + internalFormat !== gl.RGB565 && + internalFormat !== gl.RGB5_A1 && + internalFormat !== gl.DEPTH_COMPONENT16 && + internalFormat !== gl.STENCIL_INDEX && + internalFormat !== gl.STENCIL_INDEX8 && + internalFormat !== gl.DEPTH_STENCIL) { + this.setError(gl.INVALID_ENUM) + return + } + + this._saveError() + super.renderbufferStorage( + target, + internalFormat, + width, + height) + const error = this.getError() + this._restoreError(error) + if (error !== gl.NO_ERROR) { + return + } + + renderbuffer._width = width + renderbuffer._height = height + renderbuffer._format = internalFormat + + const activeFramebuffer = this._activeFramebuffer + if (activeFramebuffer) { + let needsUpdate = false + const attachments = this._getAttachments() + for (let i = 0; i < attachments.length; ++i) { + if (activeFramebuffer._attachments[attachments[i]] === renderbuffer) { + needsUpdate = true + break + } + } + if (needsUpdate) { + this._updateFramebufferAttachments(this._activeFramebuffer) + } + } + } + + resize (width, height) { + width = width | 0 + height = height | 0 + if (!(width > 0 && height > 0)) { + throw new Error('Invalid surface dimensions') + } else if (width !== this.drawingBufferWidth || + height !== this.drawingBufferHeight) { + this._resizeDrawingBuffer(width, height) + this.drawingBufferWidth = width + this.drawingBufferHeight = height + } + } + + sampleCoverage (value, invert) { + return super.sampleCoverage(+value, !!invert) + } + + scissor (x, y, width, height) { + return super.scissor(x | 0, y | 0, width | 0, height | 0) + } + + shaderSource (shader, source) { + if (!checkObject(shader)) { + throw new TypeError('shaderSource(WebGLShader, String)') + } + if (!shader || (!source && typeof source !== 'string')) { + this.setError(gl.INVALID_VALUE) + return + } + source += '' + if (!isValidString(source)) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(shader, WebGLShader)) { + super.shaderSource(shader._ | 0, this._wrapShader(shader._type, source)) // eslint-disable-line + shader._source = source + } + } + + stencilFunc (func, ref, mask) { + this._checkStencil = true + return super.stencilFunc(func | 0, ref | 0, mask | 0) + } + + stencilFuncSeparate (face, func, ref, mask) { + this._checkStencil = true + return super.stencilFuncSeparate(face | 0, func | 0, ref | 0, mask | 0) + } + + stencilMask (mask) { + this._checkStencil = true + return super.stencilMask(mask | 0) + } + + stencilMaskSeparate (face, mask) { + this._checkStencil = true + return super.stencilMaskSeparate(face | 0, mask | 0) + } + + stencilOp (fail, zfail, zpass) { + this._checkStencil = true + return super.stencilOp(fail | 0, zfail | 0, zpass | 0) + } + + stencilOpSeparate (face, fail, zfail, zpass) { + this._checkStencil = true + return super.stencilOpSeparate(face | 0, fail | 0, zfail | 0, zpass | 0) + } + + texImage2D ( + target, + level, + internalFormat, + width, + height, + border, + format, + type, + pixels) { + if (arguments.length === 6) { + pixels = border + type = height + format = width + + pixels = extractImageData(pixels) + + if (pixels == null) { + throw new TypeError('texImage2D(GLenum, GLint, GLenum, GLint, GLenum, GLenum, ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement)') + } + + width = pixels.width + height = pixels.height + pixels = pixels.data + } + + target |= 0 + level |= 0 + internalFormat |= 0 + width |= 0 + height |= 0 + border |= 0 + format |= 0 + type |= 0 + + if (typeof pixels !== 'object' && pixels !== undefined) { + throw new TypeError('texImage2D(GLenum, GLint, GLenum, GLint, GLint, GLint, GLenum, GLenum, Uint8Array)') + } + + if (!checkFormat(format) || !checkFormat(internalFormat)) { + this.setError(gl.INVALID_ENUM) + return + } + + if (type === gl.FLOAT && !this._extensions.oes_texture_float) { + this.setError(gl.INVALID_ENUM) + return + } + + const texture = this._getTexImage(target) + if (!texture || format !== internalFormat) { + this.setError(gl.INVALID_OPERATION) + return + } + + const pixelSize = this._computePixelSize(type, format) + if (pixelSize === 0) { + return + } + + if (!this._checkDimensions( + target, + width, + height, + level)) { + return + } + + const data = convertPixels(pixels) + const rowStride = this._computeRowStride(width, pixelSize) + const imageSize = rowStride * height + + if (data && data.length < imageSize) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (border !== 0 || + (validCubeTarget(target) && width !== height)) { + this.setError(gl.INVALID_VALUE) + return + } + // Need to check for out of memory error + this._saveError() + super.texImage2D( + target, + level, + internalFormat, + width, + height, + border, + format, + type, + data) + const error = this.getError() + this._restoreError(error) + if (error !== gl.NO_ERROR) { + return + } + + // Save width and height at level + texture._levelWidth[level] = width + texture._levelHeight[level] = height + texture._format = format + texture._type = type + + const activeFramebuffer = this._activeFramebuffer + if (activeFramebuffer) { + let needsUpdate = false + const attachments = this._getAttachments() + for (let i = 0; i < attachments.length; ++i) { + if (activeFramebuffer._attachments[attachments[i]] === texture) { + needsUpdate = true + break + } + } + if (needsUpdate) { + this._updateFramebufferAttachments(this._activeFramebuffer) + } + } + } + + texSubImage2D ( + target, + level, + xoffset, + yoffset, + width, + height, + format, + type, + pixels) { + if (arguments.length === 7) { + pixels = format + type = height + format = width + + pixels = extractImageData(pixels) + + if (pixels == null) { + throw new TypeError('texSubImage2D(GLenum, GLint, GLint, GLint, GLenum, GLenum, ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement)') + } + + width = pixels.width + height = pixels.height + pixels = pixels.data + } + + if (typeof pixels !== 'object') { + throw new TypeError('texSubImage2D(GLenum, GLint, GLint, GLint, GLint, GLint, GLenum, GLenum, Uint8Array)') + } + + target |= 0 + level |= 0 + xoffset |= 0 + yoffset |= 0 + width |= 0 + height |= 0 + format |= 0 + type |= 0 + + const texture = this._getTexImage(target) + if (!texture) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (type === gl.FLOAT && !this._extensions.oes_texture_float) { + this.setError(gl.INVALID_ENUM) + return + } + + const pixelSize = this._computePixelSize(type, format) + if (pixelSize === 0) { + return + } + + if (!this._checkDimensions( + target, + width, + height, + level)) { + return + } + + if (xoffset < 0 || yoffset < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + const data = convertPixels(pixels) + const rowStride = this._computeRowStride(width, pixelSize) + const imageSize = rowStride * height + + if (!data || data.length < imageSize) { + this.setError(gl.INVALID_OPERATION) + return + } + + super.texSubImage2D( + target, + level, + xoffset, + yoffset, + width, + height, + format, + type, + data) + } + + texParameterf (target, pname, param) { + target |= 0 + pname |= 0 + param = +param + + if (this._checkTextureTarget(target)) { + this._verifyTextureCompleteness(target, pname, param) + switch (pname) { + case gl.TEXTURE_MIN_FILTER: + case gl.TEXTURE_MAG_FILTER: + case gl.TEXTURE_WRAP_S: + case gl.TEXTURE_WRAP_T: + return super.texParameterf(target, pname, param) + } + + if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) { + return super.texParameterf(target, pname, param) + } + + this.setError(gl.INVALID_ENUM) + } + } + + texParameteri (target, pname, param) { + target |= 0 + pname |= 0 + param |= 0 + + if (this._checkTextureTarget(target)) { + this._verifyTextureCompleteness(target, pname, param) + switch (pname) { + case gl.TEXTURE_MIN_FILTER: + case gl.TEXTURE_MAG_FILTER: + case gl.TEXTURE_WRAP_S: + case gl.TEXTURE_WRAP_T: + return super.texParameteri(target, pname, param) + } + + if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) { + return super.texParameteri(target, pname, param) + } + + this.setError(gl.INVALID_ENUM) + } + } + + useProgram (program) { + if (!checkObject(program)) { + throw new TypeError('useProgram(WebGLProgram)') + } else if (!program) { + this._switchActiveProgram(this._activeProgram) + this._activeProgram = null + return super.useProgram(0) + } else if (this._checkWrapper(program, WebGLProgram)) { + if (this._activeProgram !== program) { + this._switchActiveProgram(this._activeProgram) + this._activeProgram = program + program._refCount += 1 + } + return super.useProgram(program._ | 0) + } + } + + validateProgram (program) { + if (this._checkWrapper(program, WebGLProgram)) { + super.validateProgram(program._ | 0) + const error = this.getError() + if (error === gl.NO_ERROR) { + program._linkInfoLog = super.getProgramInfoLog(program._ | 0) + } + this.getError() + this.setError(error) + } + } + + vertexAttribPointer ( + index, + size, + type, + normalized, + stride, + offset) { + if (stride < 0 || offset < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + index |= 0 + size |= 0 + type |= 0 + normalized = !!normalized + stride |= 0 + offset |= 0 + + if (stride < 0 || + offset < 0 || + index < 0 || index >= this._vertexAttribs.length || + !(size === 1 || size === 2 || size === 3 || size === 4)) { + this.setError(gl.INVALID_VALUE) + return + } + + if (this._activeArrayBuffer === null) { + this.setError(gl.INVALID_OPERATION) + return + } + + // fixed, int and unsigned int aren't allowed in WebGL + const byteSize = typeSize(type) + if (byteSize === 0 || + type === gl.INT || + type === gl.UNSIGNED_INT) { + this.setError(gl.INVALID_ENUM) + return + } + + if (stride > 255 || stride < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + // stride and offset must be multiples of size + if ((stride % byteSize) !== 0 || + (offset % byteSize) !== 0) { + this.setError(gl.INVALID_OPERATION) + return + } + + // Call vertex attrib pointer + super.vertexAttribPointer(index, size, type, normalized, stride, offset) + + // Save attribute pointer state + const attrib = this._vertexAttribs[index] + + if (attrib._pointerBuffer && + attrib._pointerBuffer !== this._activeArrayBuffer) { + attrib._pointerBuffer._refCount -= 1 + attrib._pointerBuffer._checkDelete() + } + + this._activeArrayBuffer._refCount += 1 + attrib._pointerBuffer = this._activeArrayBuffer + attrib._pointerSize = size * byteSize + attrib._pointerOffset = offset + attrib._pointerStride = stride || (size * byteSize) + attrib._pointerType = type + attrib._pointerNormal = normalized + attrib._inputStride = stride + attrib._inputSize = size + } + + viewport (x, y, width, height) { + return super.viewport(x | 0, y | 0, width | 0, height | 0) + } + + _allocateDrawingBuffer (width, height) { + this._drawingBuffer = new WebGLDrawingBufferWrapper( + super.createFramebuffer(), + super.createTexture(), + super.createRenderbuffer()) + + this._resizeDrawingBuffer(width, height) + } + + isContextLost () { + return false + } + + compressedTexImage2D () { + // TODO not yet implemented + } + + compressedTexSubImage2D () { + // TODO not yet implemented + } + + _checkUniformValid (location, v0, name, count, type) { + if (!checkObject(location)) { + throw new TypeError(`${name}(WebGLUniformLocation, ...)`) + } else if (!location) { + return false + } else if (this._checkLocationActive(location)) { + const utype = location._activeInfo.type + if (utype === gl.SAMPLER_2D || utype === gl.SAMPLER_CUBE) { + if (count !== 1) { + this.setError(gl.INVALID_VALUE) + return + } + if (type !== 'i') { + this.setError(gl.INVALID_OPERATION) + return + } + if (v0 < 0 || v0 >= this._textureUnits.length) { + this.setError(gl.INVALID_VALUE) + return false + } + } + if (uniformTypeSize(utype) > count) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + return false + } + + _checkUniformValueValid (location, value, name, count, type) { + if (!checkObject(location) || + !checkObject(value)) { + throw new TypeError(`${name}v(WebGLUniformLocation, Array)`) + } else if (!location) { + return false + } else if (!this._checkLocationActive(location)) { + return false + } else if (typeof value !== 'object' || !value || typeof value.length !== 'number') { + throw new TypeError(`Second argument to ${name} must be array`) + } else if (uniformTypeSize(location._activeInfo.type) > count) { + this.setError(gl.INVALID_OPERATION) + return false + } else if (value.length >= count && value.length % count === 0) { + if (location._array) { + return true + } else if (value.length === count) { + return true + } else { + this.setError(gl.INVALID_OPERATION) + return false + } + } + this.setError(gl.INVALID_VALUE) + return false + } + + uniform1f (location, v0) { + if (!this._checkUniformValid(location, v0, 'uniform1f', 1, 'f')) return + super.uniform1f(location._ | 0, v0) + } + + uniform1fv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform1fv', 1, 'f')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && i < value.length; ++i) { + const loc = locs[i] + super.uniform1f(loc, value[i]) + } + return + } + super.uniform1f(location._ | 0, value[0]) + } + + uniform1i (location, v0) { + if (!this._checkUniformValid(location, v0, 'uniform1i', 1, 'i')) return + super.uniform1i(location._ | 0, v0) + } + + uniform1iv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform1iv', 1, 'i')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && i < value.length; ++i) { + const loc = locs[i] + super.uniform1i(loc, value[i]) + } + return + } + this.uniform1i(location, value[0]) + } + + uniform2f (location, v0, v1) { + if (!this._checkUniformValid(location, v0, 'uniform2f', 2, 'f')) return + super.uniform2f(location._ | 0, v0, v1) + } + + uniform2fv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform2fv', 2, 'f')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 2 * i < value.length; ++i) { + const loc = locs[i] + super.uniform2f(loc, value[2 * i], value[(2 * i) + 1]) + } + return + } + super.uniform2f(location._ | 0, value[0], value[1]) + } + + uniform2i (location, v0, v1) { + if (!this._checkUniformValid(location, v0, 'uniform2i', 2, 'i')) return + super.uniform2i(location._ | 0, v0, v1) + } + + uniform2iv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform2iv', 2, 'i')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 2 * i < value.length; ++i) { + const loc = locs[i] + super.uniform2i(loc, value[2 * i], value[2 * i + 1]) + } + return + } + this.uniform2i(location, value[0], value[1]) + } + + uniform3f (location, v0, v1, v2) { + if (!this._checkUniformValid(location, v0, 'uniform3f', 3, 'f')) return + super.uniform3f(location._ | 0, v0, v1, v2) + } + + uniform3fv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform3fv', 3, 'f')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 3 * i < value.length; ++i) { + const loc = locs[i] + super.uniform3f(loc, value[3 * i], value[3 * i + 1], value[3 * i + 2]) + } + return + } + super.uniform3f(location._ | 0, value[0], value[1], value[2]) + } + + uniform3i (location, v0, v1, v2) { + if (!this._checkUniformValid(location, v0, 'uniform3i', 3, 'i')) return + super.uniform3i(location._ | 0, v0, v1, v2) + } + + uniform3iv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform3iv', 3, 'i')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 3 * i < value.length; ++i) { + const loc = locs[i] + super.uniform3i(loc, value[3 * i], value[3 * i + 1], value[3 * i + 2]) + } + return + } + this.uniform3i(location, value[0], value[1], value[2]) + } + + uniform4f (location, v0, v1, v2, v3) { + if (!this._checkUniformValid(location, v0, 'uniform4f', 4, 'f')) return + super.uniform4f(location._ | 0, v0, v1, v2, v3) + } + + uniform4fv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform4fv', 4, 'f')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 4 * i < value.length; ++i) { + const loc = locs[i] + super.uniform4f(loc, value[4 * i], value[4 * i + 1], value[4 * i + 2], value[4 * i + 3]) + } + return + } + super.uniform4f(location._ | 0, value[0], value[1], value[2], value[3]) + } + + uniform4i (location, v0, v1, v2, v3) { + if (!this._checkUniformValid(location, v0, 'uniform4i', 4, 'i')) return + super.uniform4i(location._ | 0, v0, v1, v2, v3) + } + + uniform4iv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform4iv', 4, 'i')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 4 * i < value.length; ++i) { + const loc = locs[i] + super.uniform4i(loc, value[4 * i], value[4 * i + 1], value[4 * i + 2], value[4 * i + 3]) + } + return + } + this.uniform4i(location, value[0], value[1], value[2], value[3]) + } + + _checkUniformMatrix (location, transpose, value, name, count) { + if (!checkObject(location) || + typeof value !== 'object') { + throw new TypeError(name + '(WebGLUniformLocation, Boolean, Array)') + } else if (!!transpose || + typeof value !== 'object' || + value === null || + !value.length || + value.length % count * count !== 0) { + this.setError(gl.INVALID_VALUE) + return false + } + if (!location) { + return false + } + if (!this._checkLocationActive(location)) { + return false + } + + if (value.length === count * count) { + return true + } else if (location._array) { + return true + } + this.setError(gl.INVALID_VALUE) + return false + } + + uniformMatrix2fv (location, transpose, value) { + if (!this._checkUniformMatrix(location, transpose, value, 'uniformMatrix2fv', 2)) return + const data = new Float32Array(value) + super.uniformMatrix2fv( + location._ | 0, + !!transpose, + data) + } + + uniformMatrix3fv (location, transpose, value) { + if (!this._checkUniformMatrix(location, transpose, value, 'uniformMatrix3fv', 3)) return + const data = new Float32Array(value) + super.uniformMatrix3fv( + location._ | 0, + !!transpose, + data) + } + + uniformMatrix4fv (location, transpose, value) { + if (!this._checkUniformMatrix(location, transpose, value, 'uniformMatrix4fv', 4)) return + const data = new Float32Array(value) + super.uniformMatrix4fv( + location._ | 0, + !!transpose, + data) + } + + vertexAttrib1f (index, v0) { + index |= 0 + if (!this._checkVertexIndex(index)) return + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[1] = data[2] = 0 + data[0] = v0 + return super.vertexAttrib1f(index | 0, +v0) + } + + vertexAttrib2f (index, v0, v1) { + index |= 0 + if (!this._checkVertexIndex(index)) return + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = 0 + data[1] = v1 + data[0] = v0 + return super.vertexAttrib2f(index | 0, +v0, +v1) + } + + vertexAttrib3f (index, v0, v1, v2) { + index |= 0 + if (!this._checkVertexIndex(index)) return + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = v2 + data[1] = v1 + data[0] = v0 + return super.vertexAttrib3f(index | 0, +v0, +v1, +v2) + } + + vertexAttrib4f (index, v0, v1, v2, v3) { + index |= 0 + if (!this._checkVertexIndex(index)) return + const data = this._vertexAttribs[index]._data + data[3] = v3 + data[2] = v2 + data[1] = v1 + data[0] = v0 + return super.vertexAttrib4f(index | 0, +v0, +v1, +v2, +v3) + } + + vertexAttrib1fv (index, value) { + if (typeof value !== 'object' || value === null || value.length < 1) { + this.setError(gl.INVALID_OPERATION) + return + } + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = 0 + data[1] = 0 + data[0] = value[0] + return super.vertexAttrib1f(index | 0, +value[0]) + } + + vertexAttrib2fv (index, value) { + if (typeof value !== 'object' || value === null || value.length < 2) { + this.setError(gl.INVALID_OPERATION) + return + } + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = 0 + data[1] = value[1] + data[0] = value[0] + return super.vertexAttrib2f(index | 0, +value[0], +value[1]) + } + + vertexAttrib3fv (index, value) { + if (typeof value !== 'object' || value === null || value.length < 3) { + this.setError(gl.INVALID_OPERATION) + return + } + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = value[2] + data[1] = value[1] + data[0] = value[0] + return super.vertexAttrib3f(index | 0, +value[0], +value[1], +value[2]) + } + + vertexAttrib4fv (index, value) { + if (typeof value !== 'object' || value === null || value.length < 4) { + this.setError(gl.INVALID_OPERATION) + return + } + const data = this._vertexAttribs[index]._data + data[3] = value[3] + data[2] = value[2] + data[1] = value[1] + data[0] = value[0] + return super.vertexAttrib4f(index | 0, +value[0], +value[1], +value[2], +value[3]) + } +} + +module.exports = { WebGLRenderingContext, wrapContext } + +},{"../../package.json":17,"./extensions/angle-instanced-arrays":19,"./extensions/ext-blend-minmax":20,"./extensions/ext-texture-filter-anisotropic":21,"./extensions/oes-element-index-unit":22,"./extensions/oes-standard-derivatives":23,"./extensions/oes-texture-float":25,"./extensions/oes-texture-float-linear":24,"./extensions/stackgl-destroy-context":26,"./extensions/stackgl-resize-drawing-buffer":27,"./extensions/webgl-draw-buffers":28,"./native-gl":30,"./utils":32,"./webgl-active-info":33,"./webgl-buffer":34,"./webgl-drawing-buffer-wrapper":36,"./webgl-framebuffer":37,"./webgl-program":38,"./webgl-renderbuffer":39,"./webgl-shader":42,"./webgl-shader-precision-format":41,"./webgl-texture":44,"./webgl-uniform-location":45,"bit-twiddle":13,"glsl-tokenizer/string":53}],41:[function(require,module,exports){ +class WebGLShaderPrecisionFormat { + constructor (_) { + this.rangeMin = _.rangeMin + this.rangeMax = _.rangeMax + this.precision = _.precision + } +} + +module.exports = { WebGLShaderPrecisionFormat } + +},{}],42:[function(require,module,exports){ +const { gl } = require('./native-gl') +const { Linkable } = require('./linkable') + +class WebGLShader extends Linkable { + constructor (_, ctx, type) { + super(_) + this._type = type + this._ctx = ctx + this._source = '' + this._compileStatus = false + this._compileInfo = '' + } + + _performDelete () { + const ctx = this._ctx + delete ctx._shaders[this._ | 0] + gl.deleteShader.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLShader } + +},{"./linkable":29,"./native-gl":30}],43:[function(require,module,exports){ +class WebGLTextureUnit { + constructor (ctx, idx) { + this._ctx = ctx + this._idx = idx + this._mode = 0 + this._bind2D = null + this._bindCube = null + } +} + +module.exports = { WebGLTextureUnit } + +},{}],44:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLTexture extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._binding = 0 + this._levelWidth = new Int32Array(32) + this._levelHeight = new Int32Array(32) + this._format = 0 + this._type = 0 + this._complete = true + } + + _performDelete () { + const ctx = this._ctx + delete ctx._textures[this._ | 0] + gl.deleteTexture.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLTexture } + +},{"./linkable":29,"./native-gl":30}],45:[function(require,module,exports){ +class WebGLUniformLocation { + constructor (_, program, info) { + this._ = _ + this._program = program + this._linkCount = program._linkCount + this._activeInfo = info + this._array = null + } +} + +module.exports = { WebGLUniformLocation } + +},{}],46:[function(require,module,exports){ +const { gl } = require('./native-gl') + +class WebGLVertexAttribute { + constructor (ctx, idx) { + this._ctx = ctx + this._idx = idx + this._isPointer = false + this._pointerBuffer = null + this._pointerOffset = 0 + this._pointerSize = 0 + this._pointerStride = 0 + this._pointerType = gl.FLOAT + this._pointerNormal = false + this._divisor = 0 + this._inputSize = 4 + this._inputStride = 0 + this._data = new Float32Array([0, 0, 0, 1]) + } +} + +module.exports = { WebGLVertexAttribute } + +},{"./native-gl":30}],47:[function(require,module,exports){ +module.exports = tokenize + +var literals100 = require('./lib/literals') + , operators = require('./lib/operators') + , builtins100 = require('./lib/builtins') + , literals300es = require('./lib/literals-300es') + , builtins300es = require('./lib/builtins-300es') + +var NORMAL = 999 // <-- never emitted + , TOKEN = 9999 // <-- never emitted + , BLOCK_COMMENT = 0 + , LINE_COMMENT = 1 + , PREPROCESSOR = 2 + , OPERATOR = 3 + , INTEGER = 4 + , FLOAT = 5 + , IDENT = 6 + , BUILTIN = 7 + , KEYWORD = 8 + , WHITESPACE = 9 + , EOF = 10 + , HEX = 11 + +var map = [ + 'block-comment' + , 'line-comment' + , 'preprocessor' + , 'operator' + , 'integer' + , 'float' + , 'ident' + , 'builtin' + , 'keyword' + , 'whitespace' + , 'eof' + , 'integer' +] + +function tokenize(opt) { + var i = 0 + , total = 0 + , mode = NORMAL + , c + , last + , content = [] + , tokens = [] + , token_idx = 0 + , token_offs = 0 + , line = 1 + , col = 0 + , start = 0 + , isnum = false + , isoperator = false + , input = '' + , len + + opt = opt || {} + var allBuiltins = builtins100 + var allLiterals = literals100 + if (opt.version === '300 es') { + allBuiltins = builtins300es + allLiterals = literals300es + } + + // cache by name + var builtinsDict = {}, literalsDict = {} + for (var i = 0; i < allBuiltins.length; i++) { + builtinsDict[allBuiltins[i]] = true + } + for (var i = 0; i < allLiterals.length; i++) { + literalsDict[allLiterals[i]] = true + } + + return function(data) { + tokens = [] + if (data !== null) return write(data) + return end() + } + + function token(data) { + if (data.length) { + tokens.push({ + type: map[mode] + , data: data + , position: start + , line: line + , column: col + }) + } + } + + function write(chunk) { + i = 0 + + if (chunk.toString) chunk = chunk.toString() + + input += chunk.replace(/\r\n/g, '\n') + len = input.length + + + var last + + while(c = input[i], i < len) { + last = i + + switch(mode) { + case BLOCK_COMMENT: i = block_comment(); break + case LINE_COMMENT: i = line_comment(); break + case PREPROCESSOR: i = preprocessor(); break + case OPERATOR: i = operator(); break + case INTEGER: i = integer(); break + case HEX: i = hex(); break + case FLOAT: i = decimal(); break + case TOKEN: i = readtoken(); break + case WHITESPACE: i = whitespace(); break + case NORMAL: i = normal(); break + } + + if(last !== i) { + switch(input[last]) { + case '\n': col = 0; ++line; break + default: ++col; break + } + } + } + + total += i + input = input.slice(i) + return tokens + } + + function end(chunk) { + if(content.length) { + token(content.join('')) + } + + mode = EOF + token('(eof)') + return tokens + } + + function normal() { + content = content.length ? [] : content + + if(last === '/' && c === '*') { + start = total + i - 1 + mode = BLOCK_COMMENT + last = c + return i + 1 + } + + if(last === '/' && c === '/') { + start = total + i - 1 + mode = LINE_COMMENT + last = c + return i + 1 + } + + if(c === '#') { + mode = PREPROCESSOR + start = total + i + return i + } + + if(/\s/.test(c)) { + mode = WHITESPACE + start = total + i + return i + } + + isnum = /\d/.test(c) + isoperator = /[^\w_]/.test(c) + + start = total + i + mode = isnum ? INTEGER : isoperator ? OPERATOR : TOKEN + return i + } + + function whitespace() { + if(/[^\s]/g.test(c)) { + token(content.join('')) + mode = NORMAL + return i + } + content.push(c) + last = c + return i + 1 + } + + function preprocessor() { + if((c === '\r' || c === '\n') && last !== '\\') { + token(content.join('')) + mode = NORMAL + return i + } + content.push(c) + last = c + return i + 1 + } + + function line_comment() { + return preprocessor() + } + + function block_comment() { + if(c === '/' && last === '*') { + content.push(c) + token(content.join('')) + mode = NORMAL + return i + 1 + } + + content.push(c) + last = c + return i + 1 + } + + function operator() { + if(last === '.' && /\d/.test(c)) { + mode = FLOAT + return i + } + + if(last === '/' && c === '*') { + mode = BLOCK_COMMENT + return i + } + + if(last === '/' && c === '/') { + mode = LINE_COMMENT + return i + } + + if(c === '.' && content.length) { + while(determine_operator(content)); + + mode = FLOAT + return i + } + + if(c === ';' || c === ')' || c === '(') { + if(content.length) while(determine_operator(content)); + token(c) + mode = NORMAL + return i + 1 + } + + var is_composite_operator = content.length === 2 && c !== '=' + if(/[\w_\d\s]/.test(c) || is_composite_operator) { + while(determine_operator(content)); + mode = NORMAL + return i + } + + content.push(c) + last = c + return i + 1 + } + + function determine_operator(buf) { + var j = 0 + , idx + , res + + do { + idx = operators.indexOf(buf.slice(0, buf.length + j).join('')) + res = operators[idx] + + if(idx === -1) { + if(j-- + buf.length > 0) continue + res = buf.slice(0, 1).join('') + } + + token(res) + + start += res.length + content = content.slice(res.length) + return content.length + } while(1) + } + + function hex() { + if(/[^a-fA-F0-9]/.test(c)) { + token(content.join('')) + mode = NORMAL + return i + } + + content.push(c) + last = c + return i + 1 + } + + function integer() { + if(c === '.') { + content.push(c) + mode = FLOAT + last = c + return i + 1 + } + + if(/[eE]/.test(c)) { + content.push(c) + mode = FLOAT + last = c + return i + 1 + } + + if(c === 'x' && content.length === 1 && content[0] === '0') { + mode = HEX + content.push(c) + last = c + return i + 1 + } + + if(/[^\d]/.test(c)) { + token(content.join('')) + mode = NORMAL + return i + } + + content.push(c) + last = c + return i + 1 + } + + function decimal() { + if(c === 'f') { + content.push(c) + last = c + i += 1 + } + + if(/[eE]/.test(c)) { + content.push(c) + last = c + return i + 1 + } + + if ((c === '-' || c === '+') && /[eE]/.test(last)) { + content.push(c) + last = c + return i + 1 + } + + if(/[^\d]/.test(c)) { + token(content.join('')) + mode = NORMAL + return i + } + + content.push(c) + last = c + return i + 1 + } + + function readtoken() { + if(/[^\d\w_]/.test(c)) { + var contentstr = content.join('') + if(literalsDict[contentstr]) { + mode = KEYWORD + } else if(builtinsDict[contentstr]) { + mode = BUILTIN + } else { + mode = IDENT + } + token(content.join('')) + mode = NORMAL + return i + } + content.push(c) + last = c + return i + 1 + } +} + +},{"./lib/builtins":49,"./lib/builtins-300es":48,"./lib/literals":51,"./lib/literals-300es":50,"./lib/operators":52}],48:[function(require,module,exports){ +// 300es builtins/reserved words that were previously valid in v100 +var v100 = require('./builtins') + +// The texture2D|Cube functions have been removed +// And the gl_ features are updated +v100 = v100.slice().filter(function (b) { + return !/^(gl\_|texture)/.test(b) +}) + +module.exports = v100.concat([ + // the updated gl_ constants + 'gl_VertexID' + , 'gl_InstanceID' + , 'gl_Position' + , 'gl_PointSize' + , 'gl_FragCoord' + , 'gl_FrontFacing' + , 'gl_FragDepth' + , 'gl_PointCoord' + , 'gl_MaxVertexAttribs' + , 'gl_MaxVertexUniformVectors' + , 'gl_MaxVertexOutputVectors' + , 'gl_MaxFragmentInputVectors' + , 'gl_MaxVertexTextureImageUnits' + , 'gl_MaxCombinedTextureImageUnits' + , 'gl_MaxTextureImageUnits' + , 'gl_MaxFragmentUniformVectors' + , 'gl_MaxDrawBuffers' + , 'gl_MinProgramTexelOffset' + , 'gl_MaxProgramTexelOffset' + , 'gl_DepthRangeParameters' + , 'gl_DepthRange' + + // other builtins + , 'trunc' + , 'round' + , 'roundEven' + , 'isnan' + , 'isinf' + , 'floatBitsToInt' + , 'floatBitsToUint' + , 'intBitsToFloat' + , 'uintBitsToFloat' + , 'packSnorm2x16' + , 'unpackSnorm2x16' + , 'packUnorm2x16' + , 'unpackUnorm2x16' + , 'packHalf2x16' + , 'unpackHalf2x16' + , 'outerProduct' + , 'transpose' + , 'determinant' + , 'inverse' + , 'texture' + , 'textureSize' + , 'textureProj' + , 'textureLod' + , 'textureOffset' + , 'texelFetch' + , 'texelFetchOffset' + , 'textureProjOffset' + , 'textureLodOffset' + , 'textureProjLod' + , 'textureProjLodOffset' + , 'textureGrad' + , 'textureGradOffset' + , 'textureProjGrad' + , 'textureProjGradOffset' +]) + +},{"./builtins":49}],49:[function(require,module,exports){ +module.exports = [ + // Keep this list sorted + 'abs' + , 'acos' + , 'all' + , 'any' + , 'asin' + , 'atan' + , 'ceil' + , 'clamp' + , 'cos' + , 'cross' + , 'dFdx' + , 'dFdy' + , 'degrees' + , 'distance' + , 'dot' + , 'equal' + , 'exp' + , 'exp2' + , 'faceforward' + , 'floor' + , 'fract' + , 'gl_BackColor' + , 'gl_BackLightModelProduct' + , 'gl_BackLightProduct' + , 'gl_BackMaterial' + , 'gl_BackSecondaryColor' + , 'gl_ClipPlane' + , 'gl_ClipVertex' + , 'gl_Color' + , 'gl_DepthRange' + , 'gl_DepthRangeParameters' + , 'gl_EyePlaneQ' + , 'gl_EyePlaneR' + , 'gl_EyePlaneS' + , 'gl_EyePlaneT' + , 'gl_Fog' + , 'gl_FogCoord' + , 'gl_FogFragCoord' + , 'gl_FogParameters' + , 'gl_FragColor' + , 'gl_FragCoord' + , 'gl_FragData' + , 'gl_FragDepth' + , 'gl_FragDepthEXT' + , 'gl_FrontColor' + , 'gl_FrontFacing' + , 'gl_FrontLightModelProduct' + , 'gl_FrontLightProduct' + , 'gl_FrontMaterial' + , 'gl_FrontSecondaryColor' + , 'gl_LightModel' + , 'gl_LightModelParameters' + , 'gl_LightModelProducts' + , 'gl_LightProducts' + , 'gl_LightSource' + , 'gl_LightSourceParameters' + , 'gl_MaterialParameters' + , 'gl_MaxClipPlanes' + , 'gl_MaxCombinedTextureImageUnits' + , 'gl_MaxDrawBuffers' + , 'gl_MaxFragmentUniformComponents' + , 'gl_MaxLights' + , 'gl_MaxTextureCoords' + , 'gl_MaxTextureImageUnits' + , 'gl_MaxTextureUnits' + , 'gl_MaxVaryingFloats' + , 'gl_MaxVertexAttribs' + , 'gl_MaxVertexTextureImageUnits' + , 'gl_MaxVertexUniformComponents' + , 'gl_ModelViewMatrix' + , 'gl_ModelViewMatrixInverse' + , 'gl_ModelViewMatrixInverseTranspose' + , 'gl_ModelViewMatrixTranspose' + , 'gl_ModelViewProjectionMatrix' + , 'gl_ModelViewProjectionMatrixInverse' + , 'gl_ModelViewProjectionMatrixInverseTranspose' + , 'gl_ModelViewProjectionMatrixTranspose' + , 'gl_MultiTexCoord0' + , 'gl_MultiTexCoord1' + , 'gl_MultiTexCoord2' + , 'gl_MultiTexCoord3' + , 'gl_MultiTexCoord4' + , 'gl_MultiTexCoord5' + , 'gl_MultiTexCoord6' + , 'gl_MultiTexCoord7' + , 'gl_Normal' + , 'gl_NormalMatrix' + , 'gl_NormalScale' + , 'gl_ObjectPlaneQ' + , 'gl_ObjectPlaneR' + , 'gl_ObjectPlaneS' + , 'gl_ObjectPlaneT' + , 'gl_Point' + , 'gl_PointCoord' + , 'gl_PointParameters' + , 'gl_PointSize' + , 'gl_Position' + , 'gl_ProjectionMatrix' + , 'gl_ProjectionMatrixInverse' + , 'gl_ProjectionMatrixInverseTranspose' + , 'gl_ProjectionMatrixTranspose' + , 'gl_SecondaryColor' + , 'gl_TexCoord' + , 'gl_TextureEnvColor' + , 'gl_TextureMatrix' + , 'gl_TextureMatrixInverse' + , 'gl_TextureMatrixInverseTranspose' + , 'gl_TextureMatrixTranspose' + , 'gl_Vertex' + , 'greaterThan' + , 'greaterThanEqual' + , 'inversesqrt' + , 'length' + , 'lessThan' + , 'lessThanEqual' + , 'log' + , 'log2' + , 'matrixCompMult' + , 'max' + , 'min' + , 'mix' + , 'mod' + , 'normalize' + , 'not' + , 'notEqual' + , 'pow' + , 'radians' + , 'reflect' + , 'refract' + , 'sign' + , 'sin' + , 'smoothstep' + , 'sqrt' + , 'step' + , 'tan' + , 'texture2D' + , 'texture2DLod' + , 'texture2DProj' + , 'texture2DProjLod' + , 'textureCube' + , 'textureCubeLod' + , 'texture2DLodEXT' + , 'texture2DProjLodEXT' + , 'textureCubeLodEXT' + , 'texture2DGradEXT' + , 'texture2DProjGradEXT' + , 'textureCubeGradEXT' +] + +},{}],50:[function(require,module,exports){ +var v100 = require('./literals') + +module.exports = v100.slice().concat([ + 'layout' + , 'centroid' + , 'smooth' + , 'case' + , 'mat2x2' + , 'mat2x3' + , 'mat2x4' + , 'mat3x2' + , 'mat3x3' + , 'mat3x4' + , 'mat4x2' + , 'mat4x3' + , 'mat4x4' + , 'uvec2' + , 'uvec3' + , 'uvec4' + , 'samplerCubeShadow' + , 'sampler2DArray' + , 'sampler2DArrayShadow' + , 'isampler2D' + , 'isampler3D' + , 'isamplerCube' + , 'isampler2DArray' + , 'usampler2D' + , 'usampler3D' + , 'usamplerCube' + , 'usampler2DArray' + , 'coherent' + , 'restrict' + , 'readonly' + , 'writeonly' + , 'resource' + , 'atomic_uint' + , 'noperspective' + , 'patch' + , 'sample' + , 'subroutine' + , 'common' + , 'partition' + , 'active' + , 'filter' + , 'image1D' + , 'image2D' + , 'image3D' + , 'imageCube' + , 'iimage1D' + , 'iimage2D' + , 'iimage3D' + , 'iimageCube' + , 'uimage1D' + , 'uimage2D' + , 'uimage3D' + , 'uimageCube' + , 'image1DArray' + , 'image2DArray' + , 'iimage1DArray' + , 'iimage2DArray' + , 'uimage1DArray' + , 'uimage2DArray' + , 'image1DShadow' + , 'image2DShadow' + , 'image1DArrayShadow' + , 'image2DArrayShadow' + , 'imageBuffer' + , 'iimageBuffer' + , 'uimageBuffer' + , 'sampler1DArray' + , 'sampler1DArrayShadow' + , 'isampler1D' + , 'isampler1DArray' + , 'usampler1D' + , 'usampler1DArray' + , 'isampler2DRect' + , 'usampler2DRect' + , 'samplerBuffer' + , 'isamplerBuffer' + , 'usamplerBuffer' + , 'sampler2DMS' + , 'isampler2DMS' + , 'usampler2DMS' + , 'sampler2DMSArray' + , 'isampler2DMSArray' + , 'usampler2DMSArray' +]) + +},{"./literals":51}],51:[function(require,module,exports){ +module.exports = [ + // current + 'precision' + , 'highp' + , 'mediump' + , 'lowp' + , 'attribute' + , 'const' + , 'uniform' + , 'varying' + , 'break' + , 'continue' + , 'do' + , 'for' + , 'while' + , 'if' + , 'else' + , 'in' + , 'out' + , 'inout' + , 'float' + , 'int' + , 'uint' + , 'void' + , 'bool' + , 'true' + , 'false' + , 'discard' + , 'return' + , 'mat2' + , 'mat3' + , 'mat4' + , 'vec2' + , 'vec3' + , 'vec4' + , 'ivec2' + , 'ivec3' + , 'ivec4' + , 'bvec2' + , 'bvec3' + , 'bvec4' + , 'sampler1D' + , 'sampler2D' + , 'sampler3D' + , 'samplerCube' + , 'sampler1DShadow' + , 'sampler2DShadow' + , 'struct' + + // future + , 'asm' + , 'class' + , 'union' + , 'enum' + , 'typedef' + , 'template' + , 'this' + , 'packed' + , 'goto' + , 'switch' + , 'default' + , 'inline' + , 'noinline' + , 'volatile' + , 'public' + , 'static' + , 'extern' + , 'external' + , 'interface' + , 'long' + , 'short' + , 'double' + , 'half' + , 'fixed' + , 'unsigned' + , 'input' + , 'output' + , 'hvec2' + , 'hvec3' + , 'hvec4' + , 'dvec2' + , 'dvec3' + , 'dvec4' + , 'fvec2' + , 'fvec3' + , 'fvec4' + , 'sampler2DRect' + , 'sampler3DRect' + , 'sampler2DRectShadow' + , 'sizeof' + , 'cast' + , 'namespace' + , 'using' +] + +},{}],52:[function(require,module,exports){ +module.exports = [ + '<<=' + , '>>=' + , '++' + , '--' + , '<<' + , '>>' + , '<=' + , '>=' + , '==' + , '!=' + , '&&' + , '||' + , '+=' + , '-=' + , '*=' + , '/=' + , '%=' + , '&=' + , '^^' + , '^=' + , '|=' + , '(' + , ')' + , '[' + , ']' + , '.' + , '!' + , '~' + , '*' + , '/' + , '%' + , '+' + , '-' + , '<' + , '>' + , '&' + , '^' + , '|' + , '?' + , ':' + , '=' + , ',' + , ';' + , '{' + , '}' +] + +},{}],53:[function(require,module,exports){ +var tokenize = require('./index') + +module.exports = tokenizeString + +function tokenizeString(str, opt) { + var generator = tokenize(opt) + var tokens = [] + + tokens = tokens.concat(generator(str)) + tokens = tokens.concat(generator(null)) + + return tokens +} + +},{"./index":47}],54:[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); + } + 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); + } + } +} + +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 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.destroy = () => {}; + kernel.validateSettings = () => {}; + if (kernel.graphical && kernel.output) { + setupGraphical(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; + // cpu is not flipped by default + 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; + }; + + // these are added for api compatibility, but have no affect + const mockMethod = () => kernel; + const methods = [ + 'setWarnVarUsage', + 'setArgumentTypes', + 'setTactic', + 'setOptimizeFloatMemory', + 'setDebug', + 'setLoopMaxIterations', + 'setConstantTypes', + 'setFunctions', + 'setNativeFunctions', + 'setInjectedNative', + 'setPipeline', + 'setPrecision', + 'setOutputToTexture', + 'setImmutable', + 'setStrictIntegers', + 'setDynamicOutput', + 'setHardcodeConstants', + 'setDynamicArguments', + 'setUseLegacyEncoder', + 'setWarnVarUsage', + 'addSubKernel', + ]; + for (let i = 0; i < methods.length; i++) { + kernel[methods[i]] = mockMethod; + } + 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 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) { + // 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; +} + +module.exports = { + gpuMock +}; + +},{}],55:[function(require,module,exports){ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = global || self, factory(global.acorn = {})); +}(this, (function (exports) { 'use strict'; + + // Reserved word lists for various dialects of the language + + 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" + }; + + // And the keywords + + 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, + "5module": ecma5AndLessKeywords + " export import", + 6: ecma5AndLessKeywords + " const class extends export import super" + }; + + var keywordRelationalOperator = /^in(stanceof)?$/; + + // ## Character categories + + // Big ugly regular expressions that match characters in the + // whitespace, identifier, and identifier-start categories. These + // are only applied when a character is found to actually have a + // code point above 128. + // Generated by `bin/generate-identifier-regex.js`. + 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-\u08c7\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\u0d04-\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\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\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-\u1cf3\u1cf5\u1cf6\u1cfa\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-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\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-\uab69\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\u0b55-\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\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\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\u1abf\u1ac0\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\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\ua82c\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; + + // These are a run-length and offset encoded representation of the + // >0xffff code points that are a valid part of identifiers. The + // offset starts at 0x10000, and each pair of numbers represents an + // offset to the next range, and then a size of the range. They were + // generated by bin/generate-identifier-regex.js + + // eslint-disable-next-line comma-spacing + 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,349,41,7,1,79,28,11,0,9,21,107,20,28,22,13,52,76,44,33,24,27,35,30,0,3,0,9,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,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,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,190,0,80,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,74,6,0,67,12,65,1,2,0,29,6135,9,1237,43,8,8952,286,50,2,18,3,9,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,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,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,42717,35,4148,12,221,3,5761,15,7472,3104,541,1507,4938]; + + // eslint-disable-next-line comma-spacing + 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,370,1,154,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,2,11,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,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,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,1014,0,2,54,8,3,82,0,12,1,19628,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,262,6,10,9,419,13,1495,6,110,6,6,9,4759,9,787719,239]; + + // This has a complexity linear to the value of the code. The + // assumption is that looking up astral identifier characters is + // rare. + 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 } + } + } + + // Test whether a given character code starts an identifier. + + 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) + } + + // Test whether a given character is part of an identifier. + + 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) + } + + // ## Token types + + // The assignment of fine-grained, information-carrying type objects + // allows the tokenizer to store the information it has about a + // token in a way that is very cheap for the parser to look up. + + // All token type variables start with an underscore, to make them + // easy to recognize. + + // The `beforeExpr` property is used to disambiguate between regular + // expressions and divisions. It is set on all token types that can + // be followed by an expression (thus, a slash after them would be a + // regular expression). + // + // The `startsExpr` property is used to check if the token ends a + // `yield` expression. It is set on all token types that either can + // directly start an expression (like a quotation mark) or can + // continue an expression (like the body of a string). + // + // `isLoop` marks a keyword as starting a loop, which is important + // to know when parsing a label, in order to allow or disallow + // continue jumps to that label. + + 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}, startsExpr = {startsExpr: true}; + + // Map keyword names to token types. + + var keywords$1 = {}; + + // Succinct definitions of keyword token types + 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"), + + // Punctuation token types. + 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), + questionDot: new TokenType("?."), + 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}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + 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}), + coalesce: binop("??", 1), + + // Keyword token types. + _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", startsExpr), + _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}) + }; + + // Matches a whole line break (where CRLF is considered a single + // line break). Used to count lines. + + 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\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + + var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + + var ref = Object.prototype; + var hasOwnProperty = ref.hasOwnProperty; + var toString = ref.toString; + + // Checks if an object has a property. + + function has(obj, propName) { + return hasOwnProperty.call(obj, propName) + } + + var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" + ); }); + + function wordsRegexp(words) { + return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") + } + + // These are used when `options.locations` is on, for the + // `startLoc` and `endLoc` properties. + + 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; } + }; + + // The `getLineInfo` function is mostly useful when the + // `locations` option is off (for performance reasons) and you + // want to find the line/column position for a given character + // offset. `input` should be the code string that the offset refers + // into. + + 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) + } + } + } + + // A second optional argument can be given to further configure + // the parser process. These options are recognized: + + var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must be + // either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10 + // (2019). This influences support for strict mode, the set of + // reserved words, and support for new syntax features. The default + // is 10. + ecmaVersion: 10, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // the position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, await identifiers are allowed to appear at the top-level scope, + // but they are still not allowed in non-async functions. + allowAwaitOutsideFunction: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false + }; + + // Interpret and default an options object + + 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); + } + } + + // Each scope gets a bitset that may contain these flags + var + SCOPE_TOP = 1, + SCOPE_FUNCTION = 2, + SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION, + SCOPE_ASYNC = 4, + SCOPE_GENERATOR = 8, + SCOPE_ARROW = 16, + SCOPE_SIMPLE_CATCH = 32, + SCOPE_SUPER = 64, + SCOPE_DIRECT_SUPER = 128; + + function functionFlags(async, generator) { + return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) + } + + // Used in checkLVal and declareName to determine the type of a binding + var + BIND_NONE = 0, // Not a binding + BIND_VAR = 1, // Var-style binding + BIND_LEXICAL = 2, // Let- or const-style binding + BIND_FUNCTION = 3, // Function declaration + BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding + BIND_OUTSIDE = 5; // Special case for function names as bound inside the function + + var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); + var reserved = ""; + if (options.allowReserved !== true) { + for (var v = options.ecmaVersion;; v--) + { if (reserved = reservedWords[v]) { break } } + if (options.sourceType === "module") { reserved += " await"; } + } + this.reservedWords = wordsRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = wordsRegexp(reservedStrict); + this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; + + // Set up token state + + // The current position of the tokenizer in the input. + 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; + } + + // Properties of the current token: + // Its type + this.type = types.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; + + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; + // Labels in scope. + this.labels = []; + // Thus-far undefined exports. + this.undefinedExports = {}; + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } + + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterScope(SCOPE_TOP); + + // For RegExp validation + this.regexpState = null; + }; + + var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true } }; + + Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) + }; + + prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; + prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 }; + prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 }; + prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 }; + prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; + prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; + + // Switch to a getter for 7.0.0. + Parser.prototype.inNonArrowFunction = function inNonArrowFunction () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 }; + + Parser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls + }; + + Parser.parse = function parse (input, options) { + return new this(options, input).parse() + }; + + Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { + var parser = new this(options, input, pos); + parser.nextToken(); + return parser.parseExpression() + }; + + Parser.tokenizer = function tokenizer (input, options) { + return new this(options, input) + }; + + Object.defineProperties( Parser.prototype, prototypeAccessors ); + + var pp = Parser.prototype; + + // ## Parser utilities + + var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; + pp.strictDirective = function(start) { + for (;;) { + // Try to find string literal. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + var match = literal.exec(this.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { + skipWhiteSpace.lastIndex = start + match[0].length; + var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; + var next = this.input.charAt(end); + return next === ";" || next === "}" || + (lineBreak.test(spaceAfter[0]) && + !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) + } + start += match[0].length; + + // Skip semicolon, if any. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + if (this.input[start] === ";") + { start++; } + } + }; + + // Predicate that tests whether the next token is of the given + // type, and if yes, consumes it as a side effect. + + pp.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false + } + }; + + // Tests whether parsed token is a contextual keyword. + + pp.isContextual = function(name) { + return this.type === types.name && this.value === name && !this.containsEsc + }; + + // Consumes contextual keyword if possible. + + pp.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true + }; + + // Asserts that following token is given contextual keyword. + + pp.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } + }; + + // Test whether a semicolon can be inserted at the current position. + + 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 + } + }; + + // Consume a semicolon, or, failing that, see if we are allowed to + // pretend that there is a semicolon at this position. + + 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 + } + }; + + // Expect a token of a given type. If found, consume it, otherwise, + // raise an unexpected token error. + + pp.expect = function(type) { + this.eat(type) || this.unexpected(); + }; + + // Raise an unexpected token error. + + 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; + + // ### Statement parsing + + // Parse a program. Initializes the parser, reads any number of + // statements, and wraps them in a Program node. Optionally takes a + // `program` argument. If present, the statements will be appended + // to its body instead of creating a new node. + + pp$1.parseTopLevel = function(node) { + var exports = {}; + if (!node.body) { node.body = []; } + while (this.type !== types.eof) { + var stmt = this.parseStatement(null, true, exports); + node.body.push(stmt); + } + if (this.inModule) + { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) + { + var name = list[i]; + + this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); + } } + this.adaptDirectivePrologue(node.body); + this.next(); + node.sourceType = this.options.sourceType; + return this.finishNode(node, "Program") + }; + + var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; + + pp$1.isLet = function(context) { + 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); + // For ambiguous cases, determine if a LexicalDeclaration (or only a + // Statement) is allowed here. If context is not empty then only a Statement + // is allowed. However, `let [` is an explicit negative lookahead for + // ExpressionStatement, so special-case it first. + if (nextCh === 91) { return true } // '[' + if (context) { return false } + + if (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 + }; + + // check 'async [no LineTerminator here] function' + // - 'async /*foo*/ function' is OK. + // - 'async /*\n*/ function' is invalid. + 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))) + }; + + // Parse a single statement. + // + // If expecting a statement and finding a slash operator, parse a + // regular expression literal. This is to handle cases like + // `if (foo) /blah/.exec(foo)`, where looking at the previous token + // does not help. + + pp$1.parseStatement = function(context, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; + + if (this.isLet(context)) { + starttype = types._var; + kind = "let"; + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + 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: + // Function as sole body of either an if statement or a labeled statement + // works, but not when it is part of a labeled statement that is the sole + // body of an if statement. + if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false, !context) + case types._class: + if (context) { 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 (context && 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(true, node) + case types.semi: return this.parseEmptyStatement(node) + case types._export: + case types._import: + if (this.options.ecmaVersion > 10 && starttype === types._import) { + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 40 || nextCh === 46) // '(' or '.' + { return this.parseExpressionStatement(node, this.parseExpression()) } + } + + 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) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (context) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true, !context) + } + + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) + { return this.parseLabeledStatement(node, maybeName, expr, context) } + else { return this.parseExpressionStatement(node, expr) } + } + }; + + pp$1.parseBreakContinueStatement = function(node, keyword) { + 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(); + } + + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this.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("do"); + 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") + }; + + // Disambiguating between a `for` and a `for`/`in` or `for`/`of` + // loop is non-trivial. Basically, we have to parse the init `var` + // statement or expression, disallowing the `in` operator (see + // the second parameter to `parseExpression`), and then check + // whether the next token is `in` or `of`. When there is no init + // part (semicolon immediately after the opening parenthesis), it + // is a regular `for` loop. + + 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.enterScope(0); + 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) { + 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 { + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + + pp$1.parseFunctionStatement = function(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) + }; + + pp$1.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(types._else) ? this.parseStatement("if") : 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(); + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + 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) { + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types.braceL); + this.labels.push(switchLabel); + this.enterScope(0); + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + var cur; + for (var sawDefault = false; this.type !== types.braceR;) { + if (this.type === types._case || this.type === types._default) { + var isCase = this.type === types._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this.expect(types.colon); + } else { + if (!cur) { this.unexpected(); } + cur.consequent.push(this.parseStatement(null)); + } + } + this.exitScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + 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") + }; + + // Reused empty array added for node fields that are always empty. + + 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(); + var simple = clause.param.type === "Identifier"; + this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); + this.expect(types.parenR); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterScope(0); + } + clause.body = this.parseBlock(false); + this.exitScope(); + 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("while"); + 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("with"); + return this.finishNode(node, "WithStatement") + }; + + pp$1.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") + }; + + pp$1.parseLabeledStatement = function(node, maybeName, expr, context) { + for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; + + if (label.name === maybeName) + { this.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.labels[i]; + if (label$1.statementStart === node.start) { + // Update information about previous labels on this node + label$1.statementStart = this.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + 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") + }; + + // Parse a semicolon-enclosed block of statements, handling `"use + // strict"` declarations when `allowStrict` is true (used for + // function bodies). + + pp$1.parseBlock = function(createNewLexicalScope, node, exitStrict) { + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; + if ( node === void 0 ) node = this.startNode(); + + node.body = []; + this.expect(types.braceL); + if (createNewLexicalScope) { this.enterScope(0); } + while (this.type !== types.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + if (exitStrict) { this.strict = false; } + this.next(); + if (createNewLexicalScope) { this.exitScope(); } + return this.finishNode(node, "BlockStatement") + }; + + // Parse a regular `for` loop. The disambiguation code in + // `parseStatement` will already have parsed the init statement or + // expression. + + 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); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, "ForStatement") + }; + + // Parse a `for`/`in` and `for`/`of` loop, which are almost + // same from parser's perspective. + + pp$1.parseForIn = function(node, init) { + var isForIn = this.type === types._in; + this.next(); + + if ( + init.type === "VariableDeclaration" && + init.declarations[0].init != null && + ( + !isForIn || + this.options.ecmaVersion < 8 || + this.strict || + init.kind !== "var" || + init.declarations[0].id.type !== "Identifier" + ) + ) { + this.raise( + init.start, + ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") + ); + } else if (init.type === "AssignmentPattern") { + this.raise(init.start, "Invalid left-hand side in for-loop"); + } + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") + }; + + // Parse a list of variable declarations. + + pp$1.parseVar = function(node, isFor, kind) { + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this.startNode(); + this.parseVarId(decl, kind); + if (this.eat(types.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else if (kind === "const" && !(this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { + this.unexpected(); + } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types._in || this.isContextual("of")))) { + this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(types.comma)) { break } + } + return node + }; + + pp$1.parseVarId = function(decl, kind) { + decl.id = this.parseBindingAtom(); + this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); + }; + + var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; + + // Parse a function declaration or literal (depending on the + // `statement & FUNC_STATEMENT`). + + // Remove `allowExpressionBody` for 7.0.0, as it is only called with false + pp$1.parseFunction = function(node, statement, allowExpressionBody, isAsync) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { + if (this.type === types.star && (statement & FUNC_HANGING_STATEMENT)) + { this.unexpected(); } + node.generator = this.eat(types.star); + } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + if (statement & FUNC_STATEMENT) { + node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types.name ? null : this.parseIdent(); + if (node.id && !(statement & FUNC_HANGING_STATEMENT)) + // If it is a regular function declaration in sloppy mode, then it is + // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding + // mode depends on properties of the current scope (see + // treatFunctionsAsVar). + { this.checkLVal(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } + } + + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(node.async, node.generator)); + + if (!(statement & FUNC_STATEMENT)) + { node.id = this.type === types.name ? this.parseIdent() : null; } + + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") + }; + + pp$1.parseFunctionParams = function(node) { + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + }; + + // Parse a class declaration or literal (depending on the + // `isStatement` parameter). + + pp$1.parseClass = function(node, isStatement) { + this.next(); + + // ecma-262 14.6 Class Definitions + // A class definition is always strict mode code. + var oldStrict = this.strict; + this.strict = true; + + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types.braceL); + while (this.type !== types.braceR) { + var element = this.parseClassElement(node.superClass !== null); + if (element) { + classBody.body.push(element); + if (element.type === "MethodDefinition" && element.kind === "constructor") { + if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } + } + } + this.strict = oldStrict; + this.next(); + node.body = this.finishNode(classBody, "ClassBody"); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; + + pp$1.parseClassElement = function(constructorAllowsSuper) { + 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; + var allowsDirectSuper = false; + 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"; + allowsDirectSuper = constructorAllowsSuper; + } 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(method, isGenerator, isAsync, allowsDirectSuper); + 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(method, isGenerator, isAsync, allowsDirectSuper) { + method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + return this.finishNode(method, "MethodDefinition") + }; + + pp$1.parseClassId = function(node, isStatement) { + if (this.type === types.name) { + node.id = this.parseIdent(); + if (isStatement) + { this.checkLVal(node.id, BIND_LEXICAL, false); } + } else { + if (isStatement === true) + { this.unexpected(); } + node.id = null; + } + }; + + pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; + }; + + // Parses module export declaration. + + pp$1.parseExport = function(node, exports) { + this.next(); + // export * from '...' + if (this.eat(types.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseIdent(true); + this.checkExport(exports, node.exported.name, this.lastTokStart); + } else { + node.exported = null; + } + } + 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)) { // export 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, FUNC_STATEMENT | FUNC_NULLABLE_ID, 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") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(null); + 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 { // export { x, y as z } [from '...'] + 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) { + // check for keywords used as local names + var spec = list[i]; + + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(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 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.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.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) { + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; + + this.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() + }; + + // Parses a comma-separated list of module exports. + + pp$1.parseExportSpecifiers = function(exports) { + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node = this.startNode(); + node.local = this.parseIdent(true); + node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local; + this.checkExport(exports, node.exported.name, node.exported.start); + nodes.push(this.finishNode(node, "ExportSpecifier")); + } + return nodes + }; + + // Parses import declaration. + + pp$1.parseImport = function(node) { + this.next(); + // import '...' + 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") + }; + + // Parses a comma-separated list of module imports. + + pp$1.parseImportSpecifiers = function() { + var nodes = [], first = true; + if (this.type === types.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLVal(node.local, BIND_LEXICAL); + 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, BIND_LEXICAL); + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + return nodes + } + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node$2 = this.startNode(); + node$2.imported = this.parseIdent(true); + if (this.eatContextual("as")) { + node$2.local = this.parseIdent(); + } else { + this.checkUnreserved(node$2.imported); + node$2.local = node$2.imported; + } + this.checkLVal(node$2.local, BIND_LEXICAL); + nodes.push(this.finishNode(node$2, "ImportSpecifier")); + } + return nodes + }; + + // Set `ExpressionStatement#directive` property for directive prologues. + 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" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) + }; + + var pp$2 = Parser.prototype; + + // Convert existing expression atom to assignable pattern + // if possible. + + pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Cannot 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.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this.raise(prop.argument.start, "Unexpected token"); + } + } + break + + case "Property": + // AssignmentProperty has type === "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); + // falls through to AssignmentPattern + + case "AssignmentPattern": + break + + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding, refDestructuringErrors); + break + + case "ChainExpression": + this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (!isBinding) { break } + + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node + }; + + // Convert list of expression atoms to binding list. + + pp$2.toAssignableList = function(exprList, isBinding) { + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this.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 + }; + + // Parses spread element. + + 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(); + + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types.name) + { this.unexpected(); } + + node.argument = this.parseBindingAtom(); + + return this.finishNode(node, "RestElement") + }; + + // Parses lvalue (assignable) atom. + + 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 elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this.expect(types.comma); } + if (allowEmpty && this.type === types.comma) { + elts.push(null); + } else if (allowTrailingComma && this.afterTrailingComma(close)) { + break + } else if (this.type === types.ellipsis) { + var rest = this.parseRestBinding(); + this.parseBindingListItem(rest); + elts.push(rest); + if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } + this.expect(close); + break + } else { + var elem = this.parseMaybeDefault(this.start, this.startLoc); + this.parseBindingListItem(elem); + elts.push(elem); + } + } + return elts + }; + + pp$2.parseBindingListItem = function(param) { + return param + }; + + // Parses assignment pattern around given atom if possible. + + 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") + }; + + // Verify that a node is an lval — something that can be assigned + // to. + // bindingType can be either: + // 'var' indicating that the lval creates a 'var' binding + // 'let' indicating that the lval creates a lexical ('let' or 'const') binding + // 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references + + pp$2.checkLVal = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "Identifier": + if (bindingType === BIND_LEXICAL && expr.name === "let") + { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } + 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 !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + break + + case "ChainExpression": + this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); + 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.checkLVal(prop, bindingType, checkClashes); + } + break + + case "Property": + // AssignmentProperty has type === "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.checkLVal(elem, bindingType, checkClashes); } + } + 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"); + } + }; + + // A recursive descent parser operates by defining functions for all + + var pp$3 = Parser.prototype; + + // Check if property name clashes with already added. + // Object/class getters and setters are not allowed to clash — + // either with each other or with an init property — and in + // strict mode, init properties are also not allowed to be repeated. + + 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) { + if (refDestructuringErrors.doubleProto < 0) + { refDestructuringErrors.doubleProto = key.start; } + // Backwards-compat kludge. Can be removed in version 6.0 + } else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } + } + propHash.proto = true; + } + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; + } 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; + }; + + // ### Expression parsing + + // These nest, from the most general expression type at the top to + // 'atomic', nondivisible expression types at the bottom. Most of + // the functions will simply let the function(s) below them parse, + // and, *if* the syntactic construct they handle is present, wrap + // the AST node that the inner parser gave them in another node. + + // Parse a full expression. The optional arguments are used to + // forbid the `in` operator (in for loops initalization expressions) + // and provide reference for storing '=' operator inside shorthand + // property assignment in contexts where both object expression + // and object pattern might appear (so it's possible to raise + // delayed syntax error at correct position). + + pp$3.parseExpression = function(noIn, refDestructuringErrors) { + 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.parseMaybeAssign(noIn, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") + } + return expr + }; + + // Parse an assignment expression. This includes applications of + // operators like `+=`. + + pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.isContextual("yield")) { + if (this.inGenerator) { return this.parseYield(noIn) } + // The tokenizer will assume an expression is allowed after + // `yield`, but this isn't that kind of yield + else { this.exprAllowed = false; } + } + + 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) { + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; + } + if (refDestructuringErrors.shorthandAssign >= node.left.start) + { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly + 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 + }; + + // Parse a ternary conditional (`?:`) operator. + + 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 + }; + + // Start the precedence parser. + + 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) + }; + + // Parse binary operators with the operator precedence parsing + // algorithm. `left` is the left-hand side of the operator. + // `minPrec` provides context that allows the function to stop and + // defer further parser to one of its callers when it encounters an + // operator that has a lower precedence than the set it is parsing. + + 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 coalesce = this.type === types.coalesce; + if (coalesce) { + // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. + // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. + prec = types.logicalAND.binop; + } + 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 || coalesce); + if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) { + this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); + } + 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") + }; + + // Parse unary operators, both prefix and postfix. + + pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + 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 { + expr = this.parseExprSubscripts(refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.operator = this.value; + node$1.prefix = false; + node$1.argument = expr; + this.checkLVal(expr); + this.next(); + expr = this.finishNode(node$1, "UpdateExpression"); + } + } + + if (!sawUnary && this.eat(types.starstar)) + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } + else + { return expr } + }; + + // Parse call, dot, and `[]`-subscript expressions. + + pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors); + if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") + { 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 maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && + this.potentialArrowAt === base.start; + var optionalChained = false; + + while (true) { + var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained); + + if (element.optional) { optionalChained = true; } + if (element === base || element.type === "ArrowFunctionExpression") { + if (optionalChained) { + var chainNode = this.startNodeAt(startPos, startLoc); + chainNode.expression = element; + element = this.finishNode(chainNode, "ChainExpression"); + } + return element + } + + base = element; + } + }; + + pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optional = optionalSupported && this.eat(types.questionDot); + if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } + + var computed = this.eat(types.bracketL); + if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) { + var node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never"); + node.computed = !!computed; + if (computed) { this.expect(types.bracketR); } + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (!noCalls && this.eat(types.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + if (this.awaitIdentPos > 0) + { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true) + } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + if (optionalSupported) { + node$1.optional = optional; + } + base = this.finishNode(node$1, "CallExpression"); + } else if (this.type === types.backQuote) { + if (optional || optionalChained) { + this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); + } + var node$2 = this.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this.parseTemplate({isTagged: true}); + base = this.finishNode(node$2, "TaggedTemplateExpression"); + } + return base + }; + + // Parse an atomic expression — either a single token that is an + // expression, an expression started by a keyword like `function` or + // `new`, or an expression wrapped in punctuation like `()`, `[]`, + // or `{}`. + + pp$3.parseExprAtom = function(refDestructuringErrors) { + // If a division operator appears in an expression position, the + // tokenizer got confused, and we force it to read a regexp instead. + if (this.type === types.slash) { this.readRegexp(); } + + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types._super: + if (!this.allowSuper) + { this.raise(this.start, "'super' keyword outside a method"); } + node = this.startNode(); + this.next(); + if (this.type === types.parenL && !this.allowDirectSuper) + { this.raise(node.start, "super() call outside constructor of a subclass"); } + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super ( Arguments ) + 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(false); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) + { return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, 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(false); + 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, 0) + + case types._class: + return this.parseClass(this.startNode(), false) + + case types._new: + return this.parseNew() + + case types.backQuote: + return this.parseTemplate() + + case types._import: + if (this.options.ecmaVersion >= 11) { + return this.parseExprImport() + } else { + return this.unexpected() + } + + default: + this.unexpected(); + } + }; + + pp$3.parseExprImport = function() { + var node = this.startNode(); + + // Consume `import` as an identifier for `import.meta`. + // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } + var meta = this.parseIdent(true); + + switch (this.type) { + case types.parenL: + return this.parseDynamicImport(node) + case types.dot: + node.meta = meta; + return this.parseImportMeta(node) + default: + this.unexpected(); + } + }; + + pp$3.parseDynamicImport = function(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + // Verify ending. + if (!this.eat(types.parenR)) { + var errorPos = this.start; + if (this.eat(types.comma) && this.eat(types.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } + } + + return this.finishNode(node, "ImportExpression") + }; + + pp$3.parseImportMeta = function(node) { + this.next(); // skip `.` + + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + + if (node.property.name !== "meta") + { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } + if (this.options.sourceType !== "module") + { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } + + return this.finishNode(node, "MetaProperty") + }; + + pp$3.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); } + 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 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; + // Do not save awaitIdentPos to allow checking awaits nested in parameters + while (this.type !== types.parenR) { + first ? first = false : this.expect(types.comma); + if (allowTrailingComma && this.afterTrailingComma(types.parenR, true)) { + lastIsComma = true; + break + } else if (this.type === types.ellipsis) { + spreadStart = this.start; + exprList.push(this.parseParenItem(this.parseRestBinding())); + if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } + break + } else { + exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.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 (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) + }; + + // New's precedence is slightly tricky. It must allow its argument to + // be a `[]` or dot subscript expression, but not a call — at least, + // not without wrapping it in parentheses. Thus, it uses the noCalls + // argument to parseSubscripts to prevent it from consuming the + // argument list. + + var empty$1 = []; + + pp$3.parseNew = function() { + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } + 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") + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } + if (!this.inNonArrowFunction()) + { this.raiseRecoverable(node.start, "'new.target' can only be used in functions"); } + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types._import; + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + if (isImport && node.callee.type === "ImportExpression") { + this.raise(startPos, "Cannot use new with import()"); + } + 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") + }; + + // Parse template expression. + + 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) { + 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.type === types.eof) { this.raise(this.pos, "Unterminated template literal"); } + this.expect(types.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(types.braceR); + node.quasis.push(curElt = this.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)) + }; + + // Parse an object literal or binding pattern. + + pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var prop = this.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this.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") + } + // To disallow parenthesized identifier via `this.toAssignable()`. + if (this.type === types.parenL && refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0) { + refDestructuringErrors.parenthesizedAssign = this.start; + } + if (refDestructuringErrors.parenthesizedBind < 0) { + refDestructuringErrors.parenthesizedBind = this.start; + } + } + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + 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 && this.type !== types.eq)) { + 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") { + if (isGenerator || isAsync) { this.unexpected(); } + this.checkUnreserved(prop.key); + if (prop.key.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = startPos; } + 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; + } + 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; + } + } + return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") + }; + + // Initialize empty function node. + + pp$3.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } + if (this.options.ecmaVersion >= 8) { node.async = false; } + }; + + // Parse object or class method. + + pp$3.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { + var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); + + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false, true); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "FunctionExpression") + }; + + // Parse arrow function expression with given parameters. + + pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "ArrowFunctionExpression") + }; + + // Parse function body and check parameters. + + pp$3.parseFunctionBody = function(node, isArrowFunction, isMethod) { + 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 this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } + + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); } + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitScope(); + }; + + 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 + }; + + // Checks function params for various disallowed patterns such as using "eval" + // or "arguments" and duplicate parameters. + + pp$3.checkParams = function(node, allowDuplicates) { + var nameHash = {}; + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + this.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash); + } + }; + + // Parses a comma-separated list of expressions, and returns them as + // an array. `close` is the token type that ends the list, and + // `allowEmpty` can be turned on to allow subsequent commas with + // nothing in between them to be parsed as `null` (which is needed + // for array literals). + + pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this.expect(types.comma); + if (allowTrailingComma && this.afterTrailingComma(close)) { break } + } else { first = false; } + + var elt = (void 0); + if (allowEmpty && this.type === types.comma) + { elt = null; } + else if (this.type === types.ellipsis) { + elt = this.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this.type === types.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this.start; } + } else { + elt = this.parseMaybeAssign(false, refDestructuringErrors); + } + 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, "Cannot use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } + if (this.keywords.test(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, "Cannot use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } + }; + + // Parse the next token as an identifier. If `liberal` is true (used + // when parsing properties), it will also convert keywords into + // identifiers. + + pp$3.parseIdent = function(liberal, isBinding) { + var node = this.startNode(); + if (this.type === types.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; + + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } + } else { + this.unexpected(); + } + this.next(!!liberal); + this.finishNode(node, "Identifier"); + if (!liberal) { + this.checkUnreserved(node); + if (node.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = node.start; } + } + return node + }; + + // Parses yield expression inside generator. + + pp$3.parseYield = function(noIn) { + 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(noIn); + } + 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, false); + return this.finishNode(node, "AwaitExpression") + }; + + var pp$4 = Parser.prototype; + + // This function is used to raise exceptions on parse errors. It + // takes an offset integer (into the current `input`) to indicate + // the location of the error, attaches the position to the end + // of the error message, and then raises a `SyntaxError` with that + // message. + + 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 Scope = function Scope(flags) { + this.flags = flags; + // A list of var-declared names in the current lexical scope + this.var = []; + // A list of lexically-declared names in the current lexical scope + this.lexical = []; + // A list of lexically-declared FunctionDeclaration names in the current lexical scope + this.functions = []; + }; + + // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. + + pp$5.enterScope = function(flags) { + this.scopeStack.push(new Scope(flags)); + }; + + pp$5.exitScope = function() { + this.scopeStack.pop(); + }; + + // The spec says: + // > At the top level of a function, or script, function declarations are + // > treated like var declarations rather than like lexical declarations. + pp$5.treatFunctionsAsVarInScope = function(scope) { + return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) + }; + + pp$5.declareName = function(name, bindingType, pos) { + var redeclared = false; + if (bindingType === BIND_LEXICAL) { + var scope = this.currentScope(); + redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; + scope.lexical.push(name); + if (this.inModule && (scope.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + } else if (bindingType === BIND_SIMPLE_CATCH) { + var scope$1 = this.currentScope(); + scope$1.lexical.push(name); + } else if (bindingType === BIND_FUNCTION) { + var scope$2 = this.currentScope(); + if (this.treatFunctionsAsVar) + { redeclared = scope$2.lexical.indexOf(name) > -1; } + else + { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } + scope$2.functions.push(name); + } else { + for (var i = this.scopeStack.length - 1; i >= 0; --i) { + var scope$3 = this.scopeStack[i]; + if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || + !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { + redeclared = true; + break + } + scope$3.var.push(name); + if (this.inModule && (scope$3.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + if (scope$3.flags & SCOPE_VAR) { break } + } + } + if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } + }; + + pp$5.checkLocalExport = function(id) { + // scope.functions must be empty as Module code is always strict. + if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && + this.scopeStack[0].var.indexOf(id.name) === -1) { + this.undefinedExports[id.name] = id; + } + }; + + pp$5.currentScope = function() { + return this.scopeStack[this.scopeStack.length - 1] + }; + + pp$5.currentVarScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & SCOPE_VAR) { return scope } + } + }; + + // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. + pp$5.currentThisScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope } + } + }; + + 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]; } + }; + + // Start an AST node, attaching a start offset. + + 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) + }; + + // Finish an AST node, adding `type` and `end` properties. + + 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) + }; + + // Finish node at given position + + pp$6.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) + }; + + // The algorithm used to determine whether a regexp can appear at a + + 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 } + + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + 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._const || prevType === types.name) + { return false } + return !this.exprAllowed + }; + + pp$7.inGeneratorContext = function() { + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this.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; } + }; + + // Token-specific context update code + + 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; + }; + + 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() { + // tokExprAllowed stays unchanged + }; + + types._function.updateContext = types._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && + !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && + !((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; } + 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; + }; + + // This file contains Unicode properties extracted from the ECMAScript + // specification. The lists are extracted like so: + // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) + + // #table-binary-unicode-properties + var ecma9BinaryProperties = "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"; + var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; + var ecma11BinaryProperties = ecma10BinaryProperties; + var unicodeBinaryProperties = { + 9: ecma9BinaryProperties, + 10: ecma10BinaryProperties, + 11: ecma11BinaryProperties + }; + + // #table-unicode-general-category-values + var unicodeGeneralCategoryValues = "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"; + + // #table-unicode-script-values + var ecma9ScriptValues = "Adlam Adlm Ahom 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 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 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 Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa 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 Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; + var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; + var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; + var unicodeScriptValues = { + 9: ecma9ScriptValues, + 10: ecma10ScriptValues, + 11: ecma11ScriptValues + }; + + var data = {}; + function buildUnicodeData(ecmaVersion) { + var d = data[ecmaVersion] = { + binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), + nonBinary: { + General_Category: wordsRegexp(unicodeGeneralCategoryValues), + Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) + } + }; + d.nonBinary.Script_Extensions = d.nonBinary.Script; + + d.nonBinary.gc = d.nonBinary.General_Category; + d.nonBinary.sc = d.nonBinary.Script; + d.nonBinary.scx = d.nonBinary.Script_Extensions; + } + buildUnicodeData(9); + buildUnicodeData(10); + buildUnicodeData(11); + + var pp$8 = Parser.prototype; + + var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); + this.unicodeProperties = data[parser.options.ecmaVersion >= 11 ? 11 : parser.options.ecmaVersion]; + 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)); + }; + + // If u flag is given, this returns the code point at the index (it combines a surrogate pair). + // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). + RegExpValidationState.prototype.at = function at (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 + } + var c = s.charCodeAt(i); + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c + } + var next = s.charCodeAt(i + 1); + return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c + }; + + RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return l + } + var c = s.charCodeAt(i), next; + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { + return i + 1 + } + return i + 2 + }; + + RegExpValidationState.prototype.current = function current (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.pos, forceU) + }; + + RegExpValidationState.prototype.lookahead = function lookahead (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.nextIndex(this.pos, forceU), forceU) + }; + + RegExpValidationState.prototype.advance = function advance (forceU) { + if ( forceU === void 0 ) forceU = false; + + this.pos = this.nextIndex(this.pos, forceU); + }; + + RegExpValidationState.prototype.eat = function eat (ch, forceU) { + if ( forceU === void 0 ) forceU = false; + + if (this.current(forceU) === ch) { + this.advance(forceU); + return true + } + return false + }; + + function codePointToString(ch) { + if (ch <= 0xFFFF) { return String.fromCharCode(ch) } + ch -= 0x10000; + return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) + } + + /** + * Validate the flags part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$8.validateRegExpFlags = function(state) { + 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.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this.raise(state.start, "Duplicate regular expression flag"); + } + } + }; + + /** + * Validate the pattern part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$8.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + + // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of + // parsing contains a |GroupName|, reparse with the goal symbol + // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* + // exception if _P_ did not conform to the grammar, if any elements of _P_ + // were not matched by the parse, or if any Early Error conditions exist. + if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + state.switchN = true; + this.regexp_pattern(state); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern + pp$8.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) { + // Make the same messages as V8. + if (state.eat(0x29 /* ) */)) { + state.raise("Unmatched ')'"); + } + if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) { + state.raise("Lone quantifier brackets"); + } + } + 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"); + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction + pp$8.regexp_disjunction = function(state) { + this.regexp_alternative(state); + while (state.eat(0x7C /* | */)) { + this.regexp_alternative(state); + } + + // Make the same message as V8. + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B /* { */)) { + state.raise("Lone quantifier brackets"); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative + pp$8.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) + { } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term + pp$8.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + // Handle `QuantifiableAssertion Quantifier` alternative. + // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion + // is a QuantifiableAssertion. + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + // Make the same message as V8. + if (state.switchU) { + state.raise("Invalid quantifier"); + } + } + return true + } + + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion + pp$8.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + + // ^, $ + if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { + return true + } + + // \b \B + if (state.eat(0x5C /* \ */)) { + if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { + return true + } + state.pos = start; + } + + // Lookahead / Lookbehind + 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 + } + } + + state.pos = start; + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier + pp$8.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F /* ? */); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix + pp$8.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A /* * */) || + state.eat(0x2B /* + */) || + state.eat(0x3F /* ? */) || + this.regexp_eatBracedQuantifier(state, noError) + ) + }; + pp$8.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 /* } */)) { + // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true + } + } + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom + pp$8.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$8.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$8.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; + } + return false + }; + pp$8.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 + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom + pp$8.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) + ) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier + pp$8.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter + pp$8.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 /* } */ + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter + // But eat eager. + pp$8.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); + } + return state.pos !== start + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter + pp$8.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 + }; + + // GroupSpecifier :: + // [empty] + // `?` GroupName + pp$8.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"); + } + }; + + // GroupName :: + // `<` RegExpIdentifierName `>` + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$8.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 + }; + + // RegExpIdentifierName :: + // RegExpIdentifierStart + // RegExpIdentifierName RegExpIdentifierPart + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$8.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + } + return true + } + return false + }; + + // RegExpIdentifierStart :: + // UnicodeIDStart + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + pp$8.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + 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 /* _ */ + } + + // RegExpIdentifierPart :: + // UnicodeIDContinue + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + // + // + pp$8.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + 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 /* */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape + pp$8.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) { + // Make the same message as V8. + if (state.current() === 0x63 /* c */) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); + } + return false + }; + pp$8.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape + if (n > state.maxBackReference) { + state.maxBackReference = n; + } + return true + } + if (n <= state.numCapturingParens) { + return true + } + state.pos = start; + } + return false + }; + pp$8.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B /* k */)) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true + } + state.raise("Invalid named reference"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape + pp$8.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, false) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) + }; + pp$8.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 /* c */)) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$8.regexp_eatZero = function(state) { + if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape + pp$8.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 /* t */) { + state.lastIntValue = 0x09; /* \t */ + state.advance(); + return true + } + if (ch === 0x6E /* n */) { + state.lastIntValue = 0x0A; /* \n */ + state.advance(); + return true + } + if (ch === 0x76 /* v */) { + state.lastIntValue = 0x0B; /* \v */ + state.advance(); + return true + } + if (ch === 0x66 /* f */) { + state.lastIntValue = 0x0C; /* \f */ + state.advance(); + return true + } + if (ch === 0x72 /* r */) { + state.lastIntValue = 0x0D; /* \r */ + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter + pp$8.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 /* A */ && ch <= 0x5A /* Z */) || + (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence + pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) { + if ( forceU === void 0 ) forceU = false; + + var start = state.pos; + var switchU = forceU || state.switchU; + + if (state.eat(0x75 /* u */)) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && 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 ( + switchU && + state.eat(0x7B /* { */) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D /* } */) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (switchU) { + state.raise("Invalid unicode escape"); + } + state.pos = start; + } + + return false + }; + function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape + pp$8.regexp_eatIdentityEscape = function(state) { + if (state.switchU) { + if (this.regexp_eatSyntaxCharacter(state)) { + return true + } + if (state.eat(0x2F /* / */)) { + state.lastIntValue = 0x2F; /* / */ + return true + } + return false + } + + var ch = state.current(); + if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape + pp$8.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape + pp$8.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 /* P */ || ch === 0x70 /* p */) + ) { + 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 /* d */ || + ch === 0x44 /* D */ || + ch === 0x73 /* s */ || + ch === 0x53 /* S */ || + ch === 0x77 /* w */ || + ch === 0x57 /* W */ + ) + } + + // UnicodePropertyValueExpression :: + // UnicodePropertyName `=` UnicodePropertyValue + // LoneUnicodePropertyNameOrValue + pp$8.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; + + // UnicodePropertyName `=` UnicodePropertyValue + 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; + + // LoneUnicodePropertyNameOrValue + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); + return true + } + return false + }; + pp$8.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!has(state.unicodeProperties.nonBinary, name)) + { state.raise("Invalid property name"); } + if (!state.unicodeProperties.nonBinary[name].test(value)) + { state.raise("Invalid property value"); } + }; + pp$8.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (!state.unicodeProperties.binary.test(nameOrValue)) + { state.raise("Invalid property name"); } + }; + + // UnicodePropertyName :: + // UnicodePropertyNameCharacters + pp$8.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F /* _ */ + } + + // UnicodePropertyValue :: + // UnicodePropertyValueCharacters + pp$8.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) + } + + // LoneUnicodePropertyNameOrValue :: + // UnicodePropertyValueCharacters + pp$8.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass + pp$8.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B /* [ */)) { + state.eat(0x5E /* ^ */); + this.regexp_classRanges(state); + if (state.eat(0x5D /* ] */)) { + return true + } + // Unreachable since it threw "unterminated regular expression" error before. + state.raise("Unterminated character class"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash + pp$8.regexp_classRanges = function(state) { + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.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"); + } + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash + pp$8.regexp_eatClassAtom = function(state) { + var start = state.pos; + + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + // Make the same message as V8. + var ch$1 = state.current(); + if (ch$1 === 0x63 /* c */ || 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 + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape + pp$8.regexp_eatClassEscape = function(state) { + var start = state.pos; + + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + + if (state.switchU && state.eat(0x2D /* - */)) { + state.lastIntValue = 0x2D; /* - */ + return true + } + + if (!state.switchU && state.eat(0x63 /* c */)) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } + + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter + pp$8.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$8.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 /* x */)) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true + } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits + pp$8.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 /* 0 */); + state.advance(); + } + return state.pos !== start + }; + function isDecimalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits + pp$8.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 /* 0 */ && ch <= 0x39 /* 9 */) || + (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || + (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) + ) + } + function hexToInt(ch) { + if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { + return 10 + (ch - 0x41 /* A */) + } + if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { + return 10 + (ch - 0x61 /* a */) + } + return ch - 0x30 /* 0 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence + // Allows only 0-377(octal) i.e. 0-255(decimal). + pp$8.regexp_eatLegacyOctalEscapeSequence = function(state) { + if (this.regexp_eatOctalDigit(state)) { + 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; + } + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit + pp$8.regexp_eatOctalDigit = function(state) { + var ch = state.current(); + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; /* 0 */ + state.advance(); + return true + } + state.lastIntValue = 0; + return false + }; + function isOctalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit + // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$8.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(); + } + return true + }; + + // Object type used to represent tokens. Note that normally, tokens + // simply exist as properties on the parser object. This is only + // used for the onToken callback and the external tokenizer. + + 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]; } + }; + + // ## Tokenizer + + var pp$9 = Parser.prototype; + + // Move to the next token + + pp$9.next = function(ignoreEscapeSequenceInKeyword) { + if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc) + { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); } + 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$9.getToken = function() { + this.next(); + return new Token(this) + }; + + // If we're in an ES6 environment, make parsers iterable + if (typeof Symbol !== "undefined") + { pp$9[Symbol.iterator] = function() { + var this$1 = this; + + return { + next: function () { + var token = this$1.getToken(); + return { + done: token.type === types.eof, + value: token + } + } + } + }; } + + // Toggle strict mode. Re-reads the next number or string to please + // pedantic tests (`"use strict"; 010;` should fail). + + pp$9.curContext = function() { + return this.context[this.context.length - 1] + }; + + // Read a single token, updating the parser object's token-related + // properties. + + pp$9.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$9.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } + + return this.getTokenFromCode(code) + }; + + pp$9.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$9.skipBlockComment = function() { + 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.curLine; + this.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$9.skipLineComment = function(startSkip) { + 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.input.charCodeAt(++this.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } + }; + + // Called at the start of the parse and after every token. Skips + // whitespace and comments, and. + + pp$9.skipSpace = function() { + loop: while (this.pos < this.input.length) { + var ch = this.input.charCodeAt(this.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this.pos; + break + case 13: + if (this.input.charCodeAt(this.pos + 1) === 10) { + ++this.pos; + } + case 10: case 8232: case 8233: + ++this.pos; + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + break + case 47: // '/' + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: // '*' + this.skipBlockComment(); + break + case 47: + this.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.pos; + } else { + break loop + } + } + } + }; + + // Called at the end of every token. Sets `end`, `val`, and + // maintains `context` and `exprAllowed`, and skips the space after + // the token, so that the next one's `start` will point at the + // right position. + + pp$9.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); + }; + + // ### Token reading + + // This is the function that is called to fetch the next token. It + // is somewhat obscure, because it works in character codes rather + // than characters, and because operator parsing has been inlined + // into it. + // + // All in the name of speed. + // + pp$9.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) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types.ellipsis) + } else { + ++this.pos; + return this.finishToken(types.dot) + } + }; + + pp$9.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$9.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; + + // exponentiation operator ** and **= + 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$9.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (this.options.ecmaVersion >= 12) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 === 61) { return this.finishOp(types.assign, 3) } + } + 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$9.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$9.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)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types.incDec, 2) + } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.plusMin, 1) + }; + + pp$9.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) { + // `0;) {") + code.push("if (!(" + shapeConditions.join(" && ") + ")) throw new Error('cwise: Arrays do not all have the same shape!')") + code.push("}") + } + // Process scalar arguments + for(var i=0; i + * All rights reserved + * + * Licensed under the MIT license. + * + * http://www.opensource.org/licenses/mit-license.php + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *****************************************************************************/ +var dijkstra = { + single_source_shortest_paths: function(graph, s, d) { + // Predecessor map for each node that has been encountered. + // node ID => predecessor node ID + var predecessors = {}; + + // Costs of shortest paths from s to all nodes encountered. + // node ID => cost + var costs = {}; + costs[s] = 0; + + // Costs of shortest paths from s to all nodes encountered; differs from + // `costs` in that it provides easy access to the node that currently has + // the known shortest path from s. + // XXX: Do we actually need both `costs` and `open`? + var open = dijkstra.PriorityQueue.make(); + open.push(s, 0); + + var closest, + u, v, + cost_of_s_to_u, + adjacent_nodes, + cost_of_e, + cost_of_s_to_u_plus_cost_of_e, + cost_of_s_to_v, + first_visit; + while (!open.empty()) { + // In the nodes remaining in graph that have a known cost from s, + // find the node, u, that currently has the shortest path from s. + closest = open.pop(); + u = closest.value; + cost_of_s_to_u = closest.cost; + + // Get nodes adjacent to u... + adjacent_nodes = graph[u] || {}; + + // ...and explore the edges that connect u to those nodes, updating + // the cost of the shortest paths to any or all of those nodes as + // necessary. v is the node across the current edge from u. + for (v in adjacent_nodes) { + if (adjacent_nodes.hasOwnProperty(v)) { + // Get the cost of the edge running from u to v. + cost_of_e = adjacent_nodes[v]; + + // Cost of s to u plus the cost of u to v across e--this is *a* + // cost from s to v that may or may not be less than the current + // known cost to v. + cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e; + + // If we haven't visited v yet OR if the current known cost from s to + // v is greater than the new cost we just found (cost of s to u plus + // cost of u to v across e), update v's cost in the cost list and + // update v's predecessor in the predecessor list (it's now u). + cost_of_s_to_v = costs[v]; + first_visit = (typeof costs[v] === 'undefined'); + if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) { + costs[v] = cost_of_s_to_u_plus_cost_of_e; + open.push(v, cost_of_s_to_u_plus_cost_of_e); + predecessors[v] = u; + } + } + } + } + + if (typeof d !== 'undefined' && typeof costs[d] === 'undefined') { + var msg = ['Could not find a path from ', s, ' to ', d, '.'].join(''); + throw new Error(msg); + } + + return predecessors; + }, + + extract_shortest_path_from_predecessor_list: function(predecessors, d) { + var nodes = []; + var u = d; + var predecessor; + while (u) { + nodes.push(u); + predecessor = predecessors[u]; + u = predecessors[u]; + } + nodes.reverse(); + return nodes; + }, + + find_path: function(graph, s, d) { + var predecessors = dijkstra.single_source_shortest_paths(graph, s, d); + return dijkstra.extract_shortest_path_from_predecessor_list( + predecessors, d); + }, + + /** + * A very naive priority queue implementation. + */ + PriorityQueue: { + make: function (opts) { + var T = dijkstra.PriorityQueue, + t = {}, + key; + opts = opts || {}; + for (key in T) { + if (T.hasOwnProperty(key)) { + t[key] = T[key]; + } + } + t.queue = []; + t.sorter = opts.sorter || T.default_sorter; + return t; + }, + + default_sorter: function (a, b) { + return a.cost - b.cost; + }, + + /** + * Add a new item to the queue and ensure the highest priority element + * is at the front of the queue. + */ + push: function (value, cost) { + var item = {value: value, cost: cost}; + this.queue.push(item); + this.queue.sort(this.sorter); + }, + + /** + * Return the highest priority element in the queue. + */ + pop: function () { + return this.queue.shift(); + }, + + empty: function () { + return this.queue.length === 0; + } + } +}; + + +// node.js module exports +if (typeof module !== 'undefined') { + module.exports = dijkstra; +} + +},{}],53:[function(require,module,exports){ +(function (process){ +'use strict'; +const path = require('path'); +const pathType = require('path-type'); + +const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; + +const getPath = (filepath, cwd) => { + const pth = filepath[0] === '!' ? filepath.slice(1) : filepath; + return path.isAbsolute(pth) ? pth : path.join(cwd, pth); +}; + +const addExtensions = (file, extensions) => { + if (path.extname(file)) { + return `**/${file}`; + } + + return `**/${file}.${getExtensions(extensions)}`; +}; + +const getGlob = (directory, options) => { + if (options.files && !Array.isArray(options.files)) { + throw new TypeError(`Expected \`files\` to be of type \`Array\` but received type \`${typeof options.files}\``); + } + + if (options.extensions && !Array.isArray(options.extensions)) { + throw new TypeError(`Expected \`extensions\` to be of type \`Array\` but received type \`${typeof options.extensions}\``); + } + + if (options.files && options.extensions) { + return options.files.map(x => path.posix.join(directory, addExtensions(x, options.extensions))); + } + + if (options.files) { + return options.files.map(x => path.posix.join(directory, `**/${x}`)); + } + + if (options.extensions) { + return [path.posix.join(directory, `**/*.${getExtensions(options.extensions)}`)]; + } + + return [path.posix.join(directory, '**')]; +}; + +module.exports = async (input, options) => { + options = { + cwd: process.cwd(), + ...options + }; + + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + } + + const globs = await Promise.all([].concat(input).map(async x => { + const isDirectory = await pathType.isDirectory(getPath(x, options.cwd)); + return isDirectory ? getGlob(x, options) : x; + })); + + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; + +module.exports.sync = (input, options) => { + options = { + cwd: process.cwd(), + ...options + }; + + if (typeof options.cwd !== 'string') { + throw new TypeError(`Expected \`cwd\` to be of type \`string\` but received type \`${typeof options.cwd}\``); + } + + const globs = [].concat(input).map(x => pathType.isDirectorySync(getPath(x, options.cwd)) ? getGlob(x, options) : x); + + return [].concat.apply([], globs); // eslint-disable-line prefer-spread +}; + +}).call(this,require('_process')) +},{"_process":432,"path":402,"path-type":54}],54:[function(require,module,exports){ +'use strict'; +const {promisify} = require('util'); +const fs = require('fs'); + +async function isType(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } + + try { + const stats = await promisify(fs[fsStatType])(filePath); + return stats[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + + throw error; + } +} + +function isTypeSync(fsStatType, statsMethodName, filePath) { + if (typeof filePath !== 'string') { + throw new TypeError(`Expected a string, got ${typeof filePath}`); + } + + try { + return fs[fsStatType](filePath)[statsMethodName](); + } catch (error) { + if (error.code === 'ENOENT') { + return false; + } + + throw error; + } +} + +exports.isFile = isType.bind(null, 'stat', 'isFile'); +exports.isDirectory = isType.bind(null, 'stat', 'isDirectory'); +exports.isSymlink = isType.bind(null, 'lstat', 'isSymbolicLink'); +exports.isFileSync = isTypeSync.bind(null, 'statSync', 'isFile'); +exports.isDirectorySync = isTypeSync.bind(null, 'statSync', 'isDirectory'); +exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); + +},{"fs":296,"util":523}],55:[function(require,module,exports){ +var once = require('once'); + +var noop = function() {}; + +var isRequest = function(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +}; + +var isChildProcess = function(stream) { + return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 +}; + +var eos = function(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; + + callback = once(callback || noop); + + var ws = stream._writableState; + var rs = stream._readableState; + var readable = opts.readable || (opts.readable !== false && stream.readable); + var writable = opts.writable || (opts.writable !== false && stream.writable); + + var onlegacyfinish = function() { + if (!stream.writable) onfinish(); + }; + + var onfinish = function() { + writable = false; + if (!readable) callback.call(stream); + }; + + var onend = function() { + readable = false; + if (!writable) callback.call(stream); + }; + + var onexit = function(exitCode) { + callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); + }; + + var onerror = function(err) { + callback.call(stream, err); + }; + + var onclose = function() { + if (readable && !(rs && rs.ended)) return callback.call(stream, new Error('premature close')); + if (writable && !(ws && ws.ended)) return callback.call(stream, new Error('premature close')); + }; + + var onrequest = function() { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest(); + else stream.on('request', onrequest); + } else if (writable && !ws) { // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } + + if (isChildProcess(stream)) stream.on('exit', onexit); + + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); + + return function() { + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('exit', onexit); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; +}; + +module.exports = eos; + +},{"once":397}],56:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +const fs = require('fs'); +const execa = require('execa'); +const pFinally = require('p-finally'); +const pify = require('pify'); +const rimraf = require('rimraf'); +const tempfile = require('tempfile'); + +const fsP = pify(fs); +const rmP = pify(rimraf); +const input = Symbol('inputPath'); +const output = Symbol('outputPath'); + +module.exports = opts => { + opts = Object.assign({}, opts); + + if (!Buffer.isBuffer(opts.input)) { + return Promise.reject(new Error('Input is required')); + } + + if (typeof opts.bin !== 'string') { + return Promise.reject(new Error('Binary is required')); + } + + if (!Array.isArray(opts.args)) { + return Promise.reject(new Error('Arguments are required')); + } + + const inputPath = opts.inputPath || tempfile(); + const outputPath = opts.outputPath || tempfile(); + + opts.args = opts.args.map(x => x === input ? inputPath : x === output ? outputPath : x); + + const promise = fsP.writeFile(inputPath, opts.input) + .then(() => execa(opts.bin, opts.args)) + .then(() => fsP.readFile(outputPath)); + + return pFinally(promise, () => Promise.all([ + rmP(inputPath), + rmP(outputPath) + ])); +}; + +module.exports.input = input; +module.exports.output = output; + +}).call(this,{"isBuffer":require("../is-buffer/index.js")}) +},{"../is-buffer/index.js":362,"execa":65,"fs":296,"p-finally":400,"pify":70,"rimraf":490,"tempfile":512}],57:[function(require,module,exports){ +'use strict'; + +var cp = require('child_process'); +var parse = require('./lib/parse'); +var enoent = require('./lib/enoent'); + +var cpSpawnSync = cp.spawnSync; + +function spawn(command, args, options) { + var parsed; + var spawned; + + // Parse the arguments + parsed = parse(command, args, options); + + // Spawn the child process + spawned = cp.spawn(parsed.command, parsed.args, parsed.options); + + // Hook into child process "exit" event to emit an error if the command + // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + enoent.hookChildProcess(spawned, parsed); + + return spawned; +} + +function spawnSync(command, args, options) { + var parsed; + var result; + + if (!cpSpawnSync) { + try { + cpSpawnSync = require('spawn-sync'); // eslint-disable-line global-require + } catch (ex) { + throw new Error( + 'In order to use spawnSync on node 0.10 or older, you must ' + + 'install spawn-sync:\n\n' + + ' npm install spawn-sync --save' + ); + } + } + + // Parse the arguments + parsed = parse(command, args, options); + + // Spawn the child process + result = cpSpawnSync(parsed.command, parsed.args, parsed.options); + + // Analyze if the command does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); + + return result; +} + +module.exports = spawn; +module.exports.spawn = spawn; +module.exports.sync = spawnSync; + +module.exports._parse = parse; +module.exports._enoent = enoent; + +},{"./lib/enoent":58,"./lib/parse":59,"child_process":296,"spawn-sync":502}],58:[function(require,module,exports){ +(function (process){ +'use strict'; + +var isWin = process.platform === 'win32'; +var resolveCommand = require('./util/resolveCommand'); + +var isNode10 = process.version.indexOf('v0.10.') === 0; + +function notFoundError(command, syscall) { + var err; + + err = new Error(syscall + ' ' + command + ' ENOENT'); + err.code = err.errno = 'ENOENT'; + err.syscall = syscall + ' ' + command; + + return err; +} + +function hookChildProcess(cp, parsed) { + var originalEmit; + + if (!isWin) { + return; + } + + originalEmit = cp.emit; + cp.emit = function (name, arg1) { + var err; + + // If emitting "exit" event and exit code is 1, we need to check if + // the command exists and emit an "error" instead + // See: https://github.com/IndigoUnited/node-cross-spawn/issues/16 + if (name === 'exit') { + err = verifyENOENT(arg1, parsed, 'spawn'); + + if (err) { + return originalEmit.call(cp, 'error', err); + } + } + + return originalEmit.apply(cp, arguments); + }; +} + +function verifyENOENT(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawn'); + } + + return null; +} + +function verifyENOENTSync(status, parsed) { + if (isWin && status === 1 && !parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + + // If we are in node 10, then we are using spawn-sync; if it exited + // with -1 it probably means that the command does not exist + if (isNode10 && status === -1) { + parsed.file = isWin ? parsed.file : resolveCommand(parsed.original); + + if (!parsed.file) { + return notFoundError(parsed.original, 'spawnSync'); + } + } + + return null; +} + +module.exports.hookChildProcess = hookChildProcess; +module.exports.verifyENOENT = verifyENOENT; +module.exports.verifyENOENTSync = verifyENOENTSync; +module.exports.notFoundError = notFoundError; + +}).call(this,require('_process')) +},{"./util/resolveCommand":64,"_process":432}],59:[function(require,module,exports){ +(function (process){ +'use strict'; + +var resolveCommand = require('./util/resolveCommand'); +var hasEmptyArgumentBug = require('./util/hasEmptyArgumentBug'); +var escapeArgument = require('./util/escapeArgument'); +var escapeCommand = require('./util/escapeCommand'); +var readShebang = require('./util/readShebang'); + +var isWin = process.platform === 'win32'; +var skipShellRegExp = /\.(?:com|exe)$/i; + +// Supported in Node >= 6 and >= 4.8 +var supportsShellOption = parseInt(process.version.substr(1).split('.')[0], 10) >= 6 || + parseInt(process.version.substr(1).split('.')[0], 10) === 4 && parseInt(process.version.substr(1).split('.')[1], 10) >= 8; + +function parseNonShell(parsed) { + var shebang; + var needsShell; + var applyQuotes; + + if (!isWin) { + return parsed; + } + + // Detect & add support for shebangs + parsed.file = resolveCommand(parsed.command); + parsed.file = parsed.file || resolveCommand(parsed.command, true); + shebang = parsed.file && readShebang(parsed.file); + + if (shebang) { + parsed.args.unshift(parsed.file); + parsed.command = shebang; + needsShell = hasEmptyArgumentBug || !skipShellRegExp.test(resolveCommand(shebang) || resolveCommand(shebang, true)); + } else { + needsShell = hasEmptyArgumentBug || !skipShellRegExp.test(parsed.file); + } + + // If a shell is required, use cmd.exe and take care of escaping everything correctly + if (needsShell) { + // Escape command & arguments + applyQuotes = (parsed.command !== 'echo'); // Do not quote arguments for the special "echo" command + parsed.command = escapeCommand(parsed.command); + parsed.args = parsed.args.map(function (arg) { + return escapeArgument(arg, applyQuotes); + }); + + // Make use of cmd.exe + parsed.args = ['/d', '/s', '/c', '"' + parsed.command + (parsed.args.length ? ' ' + parsed.args.join(' ') : '') + '"']; + parsed.command = process.env.comspec || 'cmd.exe'; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped + } + + return parsed; +} + +function parseShell(parsed) { + var shellCommand; + + // If node supports the shell option, there's no need to mimic its behavior + if (supportsShellOption) { + return parsed; + } + + // Mimic node shell option, see: https://github.com/nodejs/node/blob/b9f6a2dc059a1062776133f3d4fd848c4da7d150/lib/child_process.js#L335 + shellCommand = [parsed.command].concat(parsed.args).join(' '); + + if (isWin) { + parsed.command = typeof parsed.options.shell === 'string' ? parsed.options.shell : process.env.comspec || 'cmd.exe'; + parsed.args = ['/d', '/s', '/c', '"' + shellCommand + '"']; + parsed.options.windowsVerbatimArguments = true; // Tell node's spawn that the arguments are already escaped + } else { + if (typeof parsed.options.shell === 'string') { + parsed.command = parsed.options.shell; + } else if (process.platform === 'android') { + parsed.command = '/system/bin/sh'; + } else { + parsed.command = '/bin/sh'; + } + + parsed.args = ['-c', shellCommand]; + } + + return parsed; +} + +// ------------------------------------------------ + +function parse(command, args, options) { + var parsed; + + // Normalize arguments, similar to nodejs + if (args && !Array.isArray(args)) { + options = args; + args = null; + } + + args = args ? args.slice(0) : []; // Clone array to avoid changing the original + options = options || {}; + + // Build our parsed object + parsed = { + command: command, + args: args, + options: options, + file: undefined, + original: command, + }; + + // Delegate further parsing to shell or non-shell + return options.shell ? parseShell(parsed) : parseNonShell(parsed); +} + +module.exports = parse; + +}).call(this,require('_process')) +},{"./util/escapeArgument":60,"./util/escapeCommand":61,"./util/hasEmptyArgumentBug":62,"./util/readShebang":63,"./util/resolveCommand":64,"_process":432}],60:[function(require,module,exports){ +'use strict'; + +function escapeArgument(arg, quote) { + // Convert to string + arg = '' + arg; + + // If we are not going to quote the argument, + // escape shell metacharacters, including double and single quotes: + if (!quote) { + arg = arg.replace(/([()%!^<>&|;,"'\s])/g, '^$1'); + } else { + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote + arg = arg.replace(/(\\*)"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes + arg = arg.replace(/(\\*)$/, '$1$1'); + + // All other backslashes occur literally + + // Quote the whole thing: + arg = '"' + arg + '"'; + } + + return arg; +} + +module.exports = escapeArgument; + +},{}],61:[function(require,module,exports){ +'use strict'; + +var escapeArgument = require('./escapeArgument'); + +function escapeCommand(command) { + // Do not escape if this command is not dangerous.. + // We do this so that commands like "echo" or "ifconfig" work + // Quoting them, will make them unaccessible + return /^[a-z0-9_-]+$/i.test(command) ? command : escapeArgument(command, true); +} + +module.exports = escapeCommand; + +},{"./escapeArgument":60}],62:[function(require,module,exports){ +(function (process){ +'use strict'; + +// See: https://github.com/IndigoUnited/node-cross-spawn/pull/34#issuecomment-221623455 +function hasEmptyArgumentBug() { + var nodeVer; + + if (process.platform !== 'win32') { + return false; + } + + nodeVer = process.version.substr(1).split('.').map(function (num) { + return parseInt(num, 10); + }); + + return (nodeVer[0] === 0 && nodeVer[1] < 12); +} + +module.exports = hasEmptyArgumentBug(); + +}).call(this,require('_process')) +},{"_process":432}],63:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +var fs = require('fs'); +var LRU = require('lru-cache'); +var shebangCommand = require('shebang-command'); + +var shebangCache = new LRU({ max: 50, maxAge: 30 * 1000 }); // Cache just for 30sec + +function readShebang(command) { + var buffer; + var fd; + var shebang; + + // Check if it is in the cache first + if (shebangCache.has(command)) { + return shebangCache.get(command); + } + + // Read the first 150 bytes from the file + buffer = new Buffer(150); + + try { + fd = fs.openSync(command, 'r'); + fs.readSync(fd, buffer, 0, 150, 0); + fs.closeSync(fd); + } catch (e) { /* empty */ } + + // Attempt to extract shebang (null is returned if not a shebang) + shebang = shebangCommand(buffer.toString()); + + // Store the shebang in the cache + shebangCache.set(command, shebang); + + return shebang; +} + +module.exports = readShebang; + +}).call(this,require("buffer").Buffer) +},{"buffer":297,"fs":296,"lru-cache":375,"shebang-command":497}],64:[function(require,module,exports){ +(function (process){ +'use strict'; + +var path = require('path'); +var which = require('which'); +var LRU = require('lru-cache'); + +var commandCache = new LRU({ max: 50, maxAge: 30 * 1000 }); // Cache just for 30sec + +function resolveCommand(command, noExtension) { + var resolved; + + noExtension = !!noExtension; + resolved = commandCache.get(command + '!' + noExtension); + + // Check if its resolved in the cache + if (commandCache.has(command)) { + return commandCache.get(command); + } + + try { + resolved = !noExtension ? + which.sync(command) : + which.sync(command, { pathExt: path.delimiter + (process.env.PATHEXT || '') }); + } catch (e) { /* empty */ } + + commandCache.set(command + '!' + noExtension, resolved); + + return resolved; +} + +module.exports = resolveCommand; + +}).call(this,require('_process')) +},{"_process":432,"lru-cache":375,"path":402,"which":530}],65:[function(require,module,exports){ +(function (process){ +'use strict'; +const childProcess = require('child_process'); +const util = require('util'); +const crossSpawn = require('cross-spawn'); +const stripEof = require('strip-eof'); +const npmRunPath = require('npm-run-path'); +const isStream = require('is-stream'); +const _getStream = require('get-stream'); +const pFinally = require('p-finally'); +const onExit = require('signal-exit'); +const errname = require('./lib/errname'); +const stdio = require('./lib/stdio'); + +const TEN_MEGABYTES = 1000 * 1000 * 10; + +function handleArgs(cmd, args, opts) { + let parsed; + + if (opts && opts.env && opts.extendEnv !== false) { + opts.env = Object.assign({}, process.env, opts.env); + } + + if (opts && opts.__winShell === true) { + delete opts.__winShell; + parsed = { + command: cmd, + args, + options: opts, + file: cmd, + original: cmd + }; + } else { + parsed = crossSpawn._parse(cmd, args, opts); + } + + opts = Object.assign({ + maxBuffer: TEN_MEGABYTES, + stripEof: true, + preferLocal: true, + localDir: parsed.options.cwd || process.cwd(), + encoding: 'utf8', + reject: true, + cleanup: true + }, parsed.options); + + opts.stdio = stdio(opts); + + if (opts.preferLocal) { + opts.env = npmRunPath.env(Object.assign({}, opts, {cwd: opts.localDir})); + } + + return { + cmd: parsed.command, + args: parsed.args, + opts, + parsed + }; +} + +function handleInput(spawned, opts) { + const input = opts.input; + + if (input === null || input === undefined) { + return; + } + + if (isStream(input)) { + input.pipe(spawned.stdin); + } else { + spawned.stdin.end(input); + } +} + +function handleOutput(opts, val) { + if (val && opts.stripEof) { + val = stripEof(val); + } + + return val; +} + +function handleShell(fn, cmd, opts) { + let file = '/bin/sh'; + let args = ['-c', cmd]; + + opts = Object.assign({}, opts); + + if (process.platform === 'win32') { + opts.__winShell = true; + file = process.env.comspec || 'cmd.exe'; + args = ['/s', '/c', `"${cmd}"`]; + opts.windowsVerbatimArguments = true; + } + + if (opts.shell) { + file = opts.shell; + delete opts.shell; + } + + return fn(file, args, opts); +} + +function getStream(process, stream, encoding, maxBuffer) { + if (!process[stream]) { + return null; + } + + let ret; + + if (encoding) { + ret = _getStream(process[stream], { + encoding, + maxBuffer + }); + } else { + ret = _getStream.buffer(process[stream], {maxBuffer}); + } + + return ret.catch(err => { + err.stream = stream; + err.message = `${stream} ${err.message}`; + throw err; + }); +} + +module.exports = (cmd, args, opts) => { + let joinedCmd = cmd; + + if (Array.isArray(args) && args.length > 0) { + joinedCmd += ' ' + args.join(' '); + } + + const parsed = handleArgs(cmd, args, opts); + const encoding = parsed.opts.encoding; + const maxBuffer = parsed.opts.maxBuffer; + + let spawned; + try { + spawned = childProcess.spawn(parsed.cmd, parsed.args, parsed.opts); + } catch (err) { + return Promise.reject(err); + } + + let removeExitHandler; + if (parsed.opts.cleanup) { + removeExitHandler = onExit(() => { + spawned.kill(); + }); + } + + let timeoutId = null; + let timedOut = false; + + const cleanupTimeout = () => { + if (timeoutId) { + clearTimeout(timeoutId); + timeoutId = null; + } + }; + + if (parsed.opts.timeout > 0) { + timeoutId = setTimeout(() => { + timeoutId = null; + timedOut = true; + spawned.kill(parsed.opts.killSignal); + }, parsed.opts.timeout); + } + + const processDone = new Promise(resolve => { + spawned.on('exit', (code, signal) => { + cleanupTimeout(); + resolve({code, signal}); + }); + + spawned.on('error', err => { + cleanupTimeout(); + resolve({err}); + }); + + if (spawned.stdin) { + spawned.stdin.on('error', err => { + cleanupTimeout(); + resolve({err}); + }); + } + }); + + function destroy() { + if (spawned.stdout) { + spawned.stdout.destroy(); + } + + if (spawned.stderr) { + spawned.stderr.destroy(); + } + } + + const promise = pFinally(Promise.all([ + processDone, + getStream(spawned, 'stdout', encoding, maxBuffer), + getStream(spawned, 'stderr', encoding, maxBuffer) + ]).then(arr => { + const result = arr[0]; + const stdout = arr[1]; + const stderr = arr[2]; + + let err = result.err; + const code = result.code; + const signal = result.signal; + + if (removeExitHandler) { + removeExitHandler(); + } + + if (err || code !== 0 || signal !== null) { + if (!err) { + let output = ''; + + if (Array.isArray(parsed.opts.stdio)) { + if (parsed.opts.stdio[2] !== 'inherit') { + output += output.length > 0 ? stderr : `\n${stderr}`; + } + + if (parsed.opts.stdio[1] !== 'inherit') { + output += `\n${stdout}`; + } + } else if (parsed.opts.stdio !== 'inherit') { + output = `\n${stderr}${stdout}`; + } + + err = new Error(`Command failed: ${joinedCmd}${output}`); + err.code = code < 0 ? errname(code) : code; + } + + // TODO: missing some timeout logic for killed + // https://github.com/nodejs/node/blob/master/lib/child_process.js#L203 + // err.killed = spawned.killed || killed; + err.killed = err.killed || spawned.killed; + + err.stdout = stdout; + err.stderr = stderr; + err.failed = true; + err.signal = signal || null; + err.cmd = joinedCmd; + err.timedOut = timedOut; + + if (!parsed.opts.reject) { + return err; + } + + throw err; + } + + return { + stdout: handleOutput(parsed.opts, stdout), + stderr: handleOutput(parsed.opts, stderr), + code: 0, + failed: false, + killed: false, + signal: null, + cmd: joinedCmd, + timedOut: false + }; + }), destroy); + + crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed); + + handleInput(spawned, parsed.opts); + + spawned.then = promise.then.bind(promise); + spawned.catch = promise.catch.bind(promise); + + return spawned; +}; + +module.exports.stdout = function () { + // TODO: set `stderr: 'ignore'` when that option is implemented + return module.exports.apply(null, arguments).then(x => x.stdout); +}; + +module.exports.stderr = function () { + // TODO: set `stdout: 'ignore'` when that option is implemented + return module.exports.apply(null, arguments).then(x => x.stderr); +}; + +module.exports.shell = (cmd, opts) => handleShell(module.exports, cmd, opts); + +module.exports.sync = (cmd, args, opts) => { + const parsed = handleArgs(cmd, args, opts); + + if (isStream(parsed.opts.input)) { + throw new TypeError('The `input` option cannot be a stream in sync mode'); + } + + const result = childProcess.spawnSync(parsed.cmd, parsed.args, parsed.opts); + + if (result.error || result.status !== 0) { + throw (result.error || new Error(result.stderr === '' ? result.stdout : result.stderr)); + } + + result.stdout = handleOutput(parsed.opts, result.stdout); + result.stderr = handleOutput(parsed.opts, result.stderr); + + return result; +}; + +module.exports.shellSync = (cmd, opts) => handleShell(module.exports.sync, cmd, opts); + +module.exports.spawn = util.deprecate(module.exports, 'execa.spawn() is deprecated. Use execa() instead.'); + +}).call(this,require('_process')) +},{"./lib/errname":66,"./lib/stdio":67,"_process":432,"child_process":296,"cross-spawn":57,"get-stream":69,"is-stream":367,"npm-run-path":395,"p-finally":400,"signal-exit":499,"strip-eof":509,"util":523}],66:[function(require,module,exports){ +(function (process){ +'use strict'; +// The Node team wants to deprecate `process.bind(...)`. +// https://github.com/nodejs/node/pull/2768 +// +// However, we need the 'uv' binding for errname support. +// This is a defensive wrapper around it so `execa` will not fail entirely if it stops working someday. +// +// If this ever stops working. See: https://github.com/sindresorhus/execa/issues/31#issuecomment-215939939 for another possible solution. +let uv; + +try { + uv = process.binding('uv'); + + if (typeof uv.errname !== 'function') { + throw new TypeError('uv.errname is not a function'); + } +} catch (err) { + console.error('execa/lib/errname: unable to establish process.binding(\'uv\')', err); + uv = null; +} + +function errname(uv, code) { + if (uv) { + return uv.errname(code); + } + + if (!(code < 0)) { + throw new Error('err >= 0'); + } + + return `Unknown system error ${code}`; +} + +module.exports = code => errname(uv, code); + +// Used for testing the fallback behavior +module.exports.__test__ = errname; + +}).call(this,require('_process')) +},{"_process":432}],67:[function(require,module,exports){ +'use strict'; +const alias = ['stdin', 'stdout', 'stderr']; + +const hasAlias = opts => alias.some(x => Boolean(opts[x])); + +module.exports = opts => { + if (!opts) { + return null; + } + + if (opts.stdio && hasAlias(opts)) { + throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${alias.map(x => `\`${x}\``).join(', ')}`); + } + + if (typeof opts.stdio === 'string') { + return opts.stdio; + } + + const stdio = opts.stdio || []; + + if (!Array.isArray(stdio)) { + throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``); + } + + const result = []; + const len = Math.max(stdio.length, alias.length); + + for (let i = 0; i < len; i++) { + let value = null; + + if (stdio[i] !== undefined) { + value = stdio[i]; + } else if (opts[alias[i]] !== undefined) { + value = opts[alias[i]]; + } + + result[i] = value; + } + + return result; +}; + +},{}],68:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +const PassThrough = require('stream').PassThrough; + +module.exports = opts => { + opts = Object.assign({}, opts); + + const array = opts.array; + let encoding = opts.encoding; + const buffer = encoding === 'buffer'; + let objectMode = false; + + if (array) { + objectMode = !(encoding || buffer); + } else { + encoding = encoding || 'utf8'; + } + + if (buffer) { + encoding = null; + } + + let len = 0; + const ret = []; + const stream = new PassThrough({objectMode}); + + if (encoding) { + stream.setEncoding(encoding); + } + + stream.on('data', chunk => { + ret.push(chunk); + + if (objectMode) { + len = ret.length; + } else { + len += chunk.length; + } + }); + + stream.getBufferedValue = () => { + if (array) { + return ret; + } + + return buffer ? Buffer.concat(ret, len) : ret.join(''); + }; + + stream.getBufferedLength = () => len; + + return stream; +}; + +}).call(this,require("buffer").Buffer) +},{"buffer":297,"stream":503}],69:[function(require,module,exports){ +'use strict'; +const bufferStream = require('./buffer-stream'); + +function getStream(inputStream, opts) { + if (!inputStream) { + return Promise.reject(new Error('Expected a stream')); + } + + opts = Object.assign({maxBuffer: Infinity}, opts); + + const maxBuffer = opts.maxBuffer; + let stream; + let clean; + + const p = new Promise((resolve, reject) => { + const error = err => { + if (err) { // null check + err.bufferedData = stream.getBufferedValue(); + } + + reject(err); + }; + + stream = bufferStream(opts); + inputStream.once('error', error); + inputStream.pipe(stream); + + stream.on('data', () => { + if (stream.getBufferedLength() > maxBuffer) { + reject(new Error('maxBuffer exceeded')); + } + }); + stream.once('error', error); + stream.on('end', resolve); + + clean = () => { + // some streams doesn't implement the `stream.Readable` interface correctly + if (inputStream.unpipe) { + inputStream.unpipe(stream); + } + }; + }); + + p.then(clean, clean); + + return p.then(() => stream.getBufferedValue()); +} + +module.exports = getStream; +module.exports.buffer = (stream, opts) => getStream(stream, Object.assign({}, opts, {encoding: 'buffer'})); +module.exports.array = (stream, opts) => getStream(stream, Object.assign({}, opts, {array: true})); + +},{"./buffer-stream":68}],70:[function(require,module,exports){ +'use strict'; + +const processFn = (fn, opts) => function () { + const P = opts.promiseModule; + const args = new Array(arguments.length); + + for (let i = 0; i < arguments.length; i++) { + args[i] = arguments[i]; + } + + return new P((resolve, reject) => { + if (opts.errorFirst) { + args.push(function (err, result) { + if (opts.multiArgs) { + const results = new Array(arguments.length - 1); + + for (let i = 1; i < arguments.length; i++) { + results[i - 1] = arguments[i]; + } + + if (err) { + results.unshift(err); + reject(results); + } else { + resolve(results); + } + } else if (err) { + reject(err); + } else { + resolve(result); + } + }); + } else { + args.push(function (result) { + if (opts.multiArgs) { + const results = new Array(arguments.length - 1); + + for (let i = 0; i < arguments.length; i++) { + results[i] = arguments[i]; + } + + resolve(results); + } else { + resolve(result); + } + }); + } + + fn.apply(this, args); + }); +}; + +module.exports = (obj, opts) => { + opts = Object.assign({ + exclude: [/.+(Sync|Stream)$/], + errorFirst: true, + promiseModule: Promise + }, opts); + + const filter = key => { + const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key); + return opts.include ? opts.include.some(match) : !opts.exclude.some(match); + }; + + let ret; + if (typeof obj === 'function') { + ret = function () { + if (opts.excludeMain) { + return obj.apply(this, arguments); + } + + return processFn(obj, opts).apply(this, arguments); + }; + } else { + ret = Object.create(Object.getPrototypeOf(obj)); + } + + for (const key in obj) { // eslint-disable-line guard-for-in + const x = obj[key]; + ret[key] = typeof x === 'function' && filter(key) ? processFn(x, opts) : x; + } + + return ret; +}; + +},{}],71:[function(require,module,exports){ +'use strict'; + +const stringify = require('./lib/stringify'); +const compile = require('./lib/compile'); +const expand = require('./lib/expand'); +const parse = require('./lib/parse'); + +/** + * Expand the given pattern or create a regex-compatible string. + * + * ```js + * const braces = require('braces'); + * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] + * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] + * ``` + * @param {String} `str` + * @param {Object} `options` + * @return {String} + * @api public + */ + +const braces = (input, options = {}) => { + let output = []; + + if (Array.isArray(input)) { + for (let pattern of input) { + let result = braces.create(pattern, options); + if (Array.isArray(result)) { + output.push(...result); + } else { + output.push(result); + } + } + } else { + output = [].concat(braces.create(input, options)); + } + + if (options && options.expand === true && options.nodupes === true) { + output = [...new Set(output)]; + } + return output; +}; + +/** + * Parse the given `str` with the given `options`. + * + * ```js + * // braces.parse(pattern, [, options]); + * const ast = braces.parse('a/{b,c}/d'); + * console.log(ast); + * ``` + * @param {String} pattern Brace pattern to parse + * @param {Object} options + * @return {Object} Returns an AST + * @api public + */ + +braces.parse = (input, options = {}) => parse(input, options); + +/** + * Creates a braces string from an AST, or an AST node. + * + * ```js + * const braces = require('braces'); + * let ast = braces.parse('foo/{a,b}/bar'); + * console.log(stringify(ast.nodes[2])); //=> '{a,b}' + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.stringify = (input, options = {}) => { + if (typeof input === 'string') { + return stringify(braces.parse(input, options), options); + } + return stringify(input, options); +}; + +/** + * Compiles a brace pattern into a regex-compatible, optimized string. + * This method is called by the main [braces](#braces) function by default. + * + * ```js + * const braces = require('braces'); + * console.log(braces.compile('a/{b,c}/d')); + * //=> ['a/(b|c)/d'] + * ``` + * @param {String} `input` Brace pattern or AST. + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.compile = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + return compile(input, options); +}; + +/** + * Expands a brace pattern into an array. This method is called by the + * main [braces](#braces) function when `options.expand` is true. Before + * using this method it's recommended that you read the [performance notes](#performance)) + * and advantages of using [.compile](#compile) instead. + * + * ```js + * const braces = require('braces'); + * console.log(braces.expand('a/{b,c}/d')); + * //=> ['a/b/d', 'a/c/d']; + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.expand = (input, options = {}) => { + if (typeof input === 'string') { + input = braces.parse(input, options); + } + + let result = expand(input, options); + + // filter out empty strings if specified + if (options.noempty === true) { + result = result.filter(Boolean); + } + + // filter out duplicates if specified + if (options.nodupes === true) { + result = [...new Set(result)]; + } + + return result; +}; + +/** + * Processes a brace pattern and returns either an expanded array + * (if `options.expand` is true), a highly optimized regex-compatible string. + * This method is called by the main [braces](#braces) function. + * + * ```js + * const braces = require('braces'); + * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) + * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' + * ``` + * @param {String} `pattern` Brace pattern + * @param {Object} `options` + * @return {Array} Returns an array of expanded values. + * @api public + */ + +braces.create = (input, options = {}) => { + if (input === '' || input.length < 3) { + return [input]; + } + + return options.expand !== true + ? braces.compile(input, options) + : braces.expand(input, options); +}; + +/** + * Expose "braces" + */ + +module.exports = braces; + +},{"./lib/compile":72,"./lib/expand":74,"./lib/parse":75,"./lib/stringify":76}],72:[function(require,module,exports){ +'use strict'; + +const fill = require('fill-range'); +const utils = require('./utils'); + +const compile = (ast, options = {}) => { + let walk = (node, parent = {}) => { + let invalidBlock = utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let invalid = invalidBlock === true || invalidNode === true; + let prefix = options.escapeInvalid === true ? '\\' : ''; + let output = ''; + + if (node.isOpen === true) { + return prefix + node.value; + } + if (node.isClose === true) { + return prefix + node.value; + } + + if (node.type === 'open') { + return invalid ? (prefix + node.value) : '('; + } + + if (node.type === 'close') { + return invalid ? (prefix + node.value) : ')'; + } + + if (node.type === 'comma') { + return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); + } + + if (node.value) { + return node.value; + } + + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); + let range = fill(...args, { ...options, wrap: false, toRegex: true }); + + if (range.length !== 0) { + return args.length > 1 && range.length > 1 ? `(${range})` : range; + } + } + + if (node.nodes) { + for (let child of node.nodes) { + output += walk(child, node); + } + } + return output; + }; + + return walk(ast); +}; + +module.exports = compile; + +},{"./utils":77,"fill-range":78}],73:[function(require,module,exports){ +'use strict'; + +module.exports = { + MAX_LENGTH: 1024 * 64, + + // Digits + CHAR_0: '0', /* 0 */ + CHAR_9: '9', /* 9 */ + + // Alphabet chars. + CHAR_UPPERCASE_A: 'A', /* A */ + CHAR_LOWERCASE_A: 'a', /* a */ + CHAR_UPPERCASE_Z: 'Z', /* Z */ + CHAR_LOWERCASE_Z: 'z', /* z */ + + CHAR_LEFT_PARENTHESES: '(', /* ( */ + CHAR_RIGHT_PARENTHESES: ')', /* ) */ + + CHAR_ASTERISK: '*', /* * */ + + // Non-alphabetic chars. + CHAR_AMPERSAND: '&', /* & */ + CHAR_AT: '@', /* @ */ + CHAR_BACKSLASH: '\\', /* \ */ + CHAR_BACKTICK: '`', /* ` */ + CHAR_CARRIAGE_RETURN: '\r', /* \r */ + CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ + CHAR_COLON: ':', /* : */ + CHAR_COMMA: ',', /* , */ + CHAR_DOLLAR: '$', /* . */ + CHAR_DOT: '.', /* . */ + CHAR_DOUBLE_QUOTE: '"', /* " */ + CHAR_EQUAL: '=', /* = */ + CHAR_EXCLAMATION_MARK: '!', /* ! */ + CHAR_FORM_FEED: '\f', /* \f */ + CHAR_FORWARD_SLASH: '/', /* / */ + CHAR_HASH: '#', /* # */ + CHAR_HYPHEN_MINUS: '-', /* - */ + CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ + CHAR_LEFT_CURLY_BRACE: '{', /* { */ + CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ + CHAR_LINE_FEED: '\n', /* \n */ + CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ + CHAR_PERCENT: '%', /* % */ + CHAR_PLUS: '+', /* + */ + CHAR_QUESTION_MARK: '?', /* ? */ + CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ + CHAR_RIGHT_CURLY_BRACE: '}', /* } */ + CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ + CHAR_SEMICOLON: ';', /* ; */ + CHAR_SINGLE_QUOTE: '\'', /* ' */ + CHAR_SPACE: ' ', /* */ + CHAR_TAB: '\t', /* \t */ + CHAR_UNDERSCORE: '_', /* _ */ + CHAR_VERTICAL_LINE: '|', /* | */ + CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ +}; + +},{}],74:[function(require,module,exports){ +'use strict'; + +const fill = require('fill-range'); +const stringify = require('./stringify'); +const utils = require('./utils'); + +const append = (queue = '', stash = '', enclose = false) => { + let result = []; + + queue = [].concat(queue); + stash = [].concat(stash); + + if (!stash.length) return queue; + if (!queue.length) { + return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; + } + + for (let item of queue) { + if (Array.isArray(item)) { + for (let value of item) { + result.push(append(value, stash, enclose)); + } + } else { + for (let ele of stash) { + if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; + result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); + } + } + } + return utils.flatten(result); +}; + +const expand = (ast, options = {}) => { + let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; + + let walk = (node, parent = {}) => { + node.queue = []; + + let p = parent; + let q = parent.queue; + + while (p.type !== 'brace' && p.type !== 'root' && p.parent) { + p = p.parent; + q = p.queue; + } + + if (node.invalid || node.dollar) { + q.push(append(q.pop(), stringify(node, options))); + return; + } + + if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { + q.push(append(q.pop(), ['{}'])); + return; + } + + if (node.nodes && node.ranges > 0) { + let args = utils.reduce(node.nodes); + + if (utils.exceedsLimit(...args, options.step, rangeLimit)) { + throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); + } + + let range = fill(...args, options); + if (range.length === 0) { + range = stringify(node, options); + } + + q.push(append(q.pop(), range)); + node.nodes = []; + return; + } + + let enclose = utils.encloseBrace(node); + let queue = node.queue; + let block = node; + + while (block.type !== 'brace' && block.type !== 'root' && block.parent) { + block = block.parent; + queue = block.queue; + } + + for (let i = 0; i < node.nodes.length; i++) { + let child = node.nodes[i]; + + if (child.type === 'comma' && node.type === 'brace') { + if (i === 1) queue.push(''); + queue.push(''); + continue; + } + + if (child.type === 'close') { + q.push(append(q.pop(), queue, enclose)); + continue; + } + + if (child.value && child.type !== 'open') { + queue.push(append(queue.pop(), child.value)); + continue; + } + + if (child.nodes) { + walk(child, node); + } + } + + return queue; + }; + + return utils.flatten(walk(ast)); +}; + +module.exports = expand; + +},{"./stringify":76,"./utils":77,"fill-range":78}],75:[function(require,module,exports){ +'use strict'; + +const stringify = require('./stringify'); + +/** + * Constants + */ + +const { + MAX_LENGTH, + CHAR_BACKSLASH, /* \ */ + CHAR_BACKTICK, /* ` */ + CHAR_COMMA, /* , */ + CHAR_DOT, /* . */ + CHAR_LEFT_PARENTHESES, /* ( */ + CHAR_RIGHT_PARENTHESES, /* ) */ + CHAR_LEFT_CURLY_BRACE, /* { */ + CHAR_RIGHT_CURLY_BRACE, /* } */ + CHAR_LEFT_SQUARE_BRACKET, /* [ */ + CHAR_RIGHT_SQUARE_BRACKET, /* ] */ + CHAR_DOUBLE_QUOTE, /* " */ + CHAR_SINGLE_QUOTE, /* ' */ + CHAR_NO_BREAK_SPACE, + CHAR_ZERO_WIDTH_NOBREAK_SPACE +} = require('./constants'); + +/** + * parse + */ + +const parse = (input, options = {}) => { + if (typeof input !== 'string') { + throw new TypeError('Expected a string'); + } + + let opts = options || {}; + let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; + if (input.length > max) { + throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); + } + + let ast = { type: 'root', input, nodes: [] }; + let stack = [ast]; + let block = ast; + let prev = ast; + let brackets = 0; + let length = input.length; + let index = 0; + let depth = 0; + let value; + let memo = {}; + + /** + * Helpers + */ + + const advance = () => input[index++]; + const push = node => { + if (node.type === 'text' && prev.type === 'dot') { + prev.type = 'text'; + } + + if (prev && prev.type === 'text' && node.type === 'text') { + prev.value += node.value; + return; + } + + block.nodes.push(node); + node.parent = block; + node.prev = prev; + prev = node; + return node; + }; + + push({ type: 'bos' }); + + while (index < length) { + block = stack[stack.length - 1]; + value = advance(); + + /** + * Invalid chars + */ + + if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { + continue; + } + + /** + * Escaped chars + */ + + if (value === CHAR_BACKSLASH) { + push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); + continue; + } + + /** + * Right square bracket (literal): ']' + */ + + if (value === CHAR_RIGHT_SQUARE_BRACKET) { + push({ type: 'text', value: '\\' + value }); + continue; + } + + /** + * Left square bracket: '[' + */ + + if (value === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + + let closed = true; + let next; + + while (index < length && (next = advance())) { + value += next; + + if (next === CHAR_LEFT_SQUARE_BRACKET) { + brackets++; + continue; + } + + if (next === CHAR_BACKSLASH) { + value += advance(); + continue; + } + + if (next === CHAR_RIGHT_SQUARE_BRACKET) { + brackets--; + + if (brackets === 0) { + break; + } + } + } + + push({ type: 'text', value }); + continue; + } + + /** + * Parentheses + */ + + if (value === CHAR_LEFT_PARENTHESES) { + block = push({ type: 'paren', nodes: [] }); + stack.push(block); + push({ type: 'text', value }); + continue; + } + + if (value === CHAR_RIGHT_PARENTHESES) { + if (block.type !== 'paren') { + push({ type: 'text', value }); + continue; + } + block = stack.pop(); + push({ type: 'text', value }); + block = stack[stack.length - 1]; + continue; + } + + /** + * Quotes: '|"|` + */ + + if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { + let open = value; + let next; + + if (options.keepQuotes !== true) { + value = ''; + } + + while (index < length && (next = advance())) { + if (next === CHAR_BACKSLASH) { + value += next + advance(); + continue; + } + + if (next === open) { + if (options.keepQuotes === true) value += next; + break; + } + + value += next; + } + + push({ type: 'text', value }); + continue; + } + + /** + * Left curly brace: '{' + */ + + if (value === CHAR_LEFT_CURLY_BRACE) { + depth++; + + let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; + let brace = { + type: 'brace', + open: true, + close: false, + dollar, + depth, + commas: 0, + ranges: 0, + nodes: [] + }; + + block = push(brace); + stack.push(block); + push({ type: 'open', value }); + continue; + } + + /** + * Right curly brace: '}' + */ + + if (value === CHAR_RIGHT_CURLY_BRACE) { + if (block.type !== 'brace') { + push({ type: 'text', value }); + continue; + } + + let type = 'close'; + block = stack.pop(); + block.close = true; + + push({ type, value }); + depth--; + + block = stack[stack.length - 1]; + continue; + } + + /** + * Comma: ',' + */ + + if (value === CHAR_COMMA && depth > 0) { + if (block.ranges > 0) { + block.ranges = 0; + let open = block.nodes.shift(); + block.nodes = [open, { type: 'text', value: stringify(block) }]; + } + + push({ type: 'comma', value }); + block.commas++; + continue; + } + + /** + * Dot: '.' + */ + + if (value === CHAR_DOT && depth > 0 && block.commas === 0) { + let siblings = block.nodes; + + if (depth === 0 || siblings.length === 0) { + push({ type: 'text', value }); + continue; + } + + if (prev.type === 'dot') { + block.range = []; + prev.value += value; + prev.type = 'range'; + + if (block.nodes.length !== 3 && block.nodes.length !== 5) { + block.invalid = true; + block.ranges = 0; + prev.type = 'text'; + continue; + } + + block.ranges++; + block.args = []; + continue; + } + + if (prev.type === 'range') { + siblings.pop(); + + let before = siblings[siblings.length - 1]; + before.value += prev.value + value; + prev = before; + block.ranges--; + continue; + } + + push({ type: 'dot', value }); + continue; + } + + /** + * Text + */ + + push({ type: 'text', value }); + } + + // Mark imbalanced braces and brackets as invalid + do { + block = stack.pop(); + + if (block.type !== 'root') { + block.nodes.forEach(node => { + if (!node.nodes) { + if (node.type === 'open') node.isOpen = true; + if (node.type === 'close') node.isClose = true; + if (!node.nodes) node.type = 'text'; + node.invalid = true; + } + }); + + // get the location of the block on parent.nodes (block's siblings) + let parent = stack[stack.length - 1]; + let index = parent.nodes.indexOf(block); + // replace the (invalid) block with it's nodes + parent.nodes.splice(index, 1, ...block.nodes); + } + } while (stack.length > 0); + + push({ type: 'eos' }); + return ast; +}; + +module.exports = parse; + +},{"./constants":73,"./stringify":76}],76:[function(require,module,exports){ +'use strict'; + +const utils = require('./utils'); + +module.exports = (ast, options = {}) => { + let stringify = (node, parent = {}) => { + let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); + let invalidNode = node.invalid === true && options.escapeInvalid === true; + let output = ''; + + if (node.value) { + if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { + return '\\' + node.value; + } + return node.value; + } + + if (node.value) { + return node.value; + } + + if (node.nodes) { + for (let child of node.nodes) { + output += stringify(child); + } + } + return output; + }; + + return stringify(ast); +}; + + +},{"./utils":77}],77:[function(require,module,exports){ +'use strict'; + +exports.isInteger = num => { + if (typeof num === 'number') { + return Number.isInteger(num); + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isInteger(Number(num)); + } + return false; +}; + +/** + * Find a node of the given type + */ + +exports.find = (node, type) => node.nodes.find(node => node.type === type); + +/** + * Find a node of the given type + */ + +exports.exceedsLimit = (min, max, step = 1, limit) => { + if (limit === false) return false; + if (!exports.isInteger(min) || !exports.isInteger(max)) return false; + return ((Number(max) - Number(min)) / Number(step)) >= limit; +}; + +/** + * Escape the given node with '\\' before node.value + */ + +exports.escapeNode = (block, n = 0, type) => { + let node = block.nodes[n]; + if (!node) return; + + if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { + if (node.escaped !== true) { + node.value = '\\' + node.value; + node.escaped = true; + } + } +}; + +/** + * Returns true if the given brace node should be enclosed in literal braces + */ + +exports.encloseBrace = node => { + if (node.type !== 'brace') return false; + if ((node.commas >> 0 + node.ranges >> 0) === 0) { + node.invalid = true; + return true; + } + return false; +}; + +/** + * Returns true if a brace node is invalid. + */ + +exports.isInvalidBrace = block => { + if (block.type !== 'brace') return false; + if (block.invalid === true || block.dollar) return true; + if ((block.commas >> 0 + block.ranges >> 0) === 0) { + block.invalid = true; + return true; + } + if (block.open !== true || block.close !== true) { + block.invalid = true; + return true; + } + return false; +}; + +/** + * Returns true if a node is an open or close node + */ + +exports.isOpenOrClose = node => { + if (node.type === 'open' || node.type === 'close') { + return true; + } + return node.open === true || node.close === true; +}; + +/** + * Reduce an array of text nodes. + */ + +exports.reduce = nodes => nodes.reduce((acc, node) => { + if (node.type === 'text') acc.push(node.value); + if (node.type === 'range') node.type = 'text'; + return acc; +}, []); + +/** + * Flatten an array + */ + +exports.flatten = (...args) => { + const result = []; + const flat = arr => { + for (let i = 0; i < arr.length; i++) { + let ele = arr[i]; + Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele); + } + return result; + }; + flat(args); + return result; +}; + +},{}],78:[function(require,module,exports){ +/*! + * fill-range + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +const util = require('util'); +const toRegexRange = require('to-regex-range'); + +const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); + +const transform = toNumber => { + return value => toNumber === true ? Number(value) : String(value); +}; + +const isValidValue = value => { + return typeof value === 'number' || (typeof value === 'string' && value !== ''); +}; + +const isNumber = num => Number.isInteger(+num); + +const zeros = input => { + let value = `${input}`; + let index = -1; + if (value[0] === '-') value = value.slice(1); + if (value === '0') return false; + while (value[++index] === '0'); + return index > 0; +}; + +const stringify = (start, end, options) => { + if (typeof start === 'string' || typeof end === 'string') { + return true; + } + return options.stringify === true; +}; + +const pad = (input, maxLength, toNumber) => { + if (maxLength > 0) { + let dash = input[0] === '-' ? '-' : ''; + if (dash) input = input.slice(1); + input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); + } + if (toNumber === false) { + return String(input); + } + return input; +}; + +const toMaxLen = (input, maxLength) => { + let negative = input[0] === '-' ? '-' : ''; + if (negative) { + input = input.slice(1); + maxLength--; + } + while (input.length < maxLength) input = '0' + input; + return negative ? ('-' + input) : input; +}; + +const toSequence = (parts, options) => { + parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); + parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); + + let prefix = options.capture ? '' : '?:'; + let positives = ''; + let negatives = ''; + let result; + + if (parts.positives.length) { + positives = parts.positives.join('|'); + } + + if (parts.negatives.length) { + negatives = `-(${prefix}${parts.negatives.join('|')})`; + } + + if (positives && negatives) { + result = `${positives}|${negatives}`; + } else { + result = positives || negatives; + } + + if (options.wrap) { + return `(${prefix}${result})`; + } + + return result; +}; + +const toRange = (a, b, isNumbers, options) => { + if (isNumbers) { + return toRegexRange(a, b, { wrap: false, ...options }); + } + + let start = String.fromCharCode(a); + if (a === b) return start; + + let stop = String.fromCharCode(b); + return `[${start}-${stop}]`; +}; + +const toRegex = (start, end, options) => { + if (Array.isArray(start)) { + let wrap = options.wrap === true; + let prefix = options.capture ? '' : '?:'; + return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); + } + return toRegexRange(start, end, options); +}; + +const rangeError = (...args) => { + return new RangeError('Invalid range arguments: ' + util.inspect(...args)); +}; + +const invalidRange = (start, end, options) => { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; +}; + +const invalidStep = (step, options) => { + if (options.strictRanges === true) { + throw new TypeError(`Expected step "${step}" to be a number`); + } + return []; +}; + +const fillNumbers = (start, end, step = 1, options = {}) => { + let a = Number(start); + let b = Number(end); + + if (!Number.isInteger(a) || !Number.isInteger(b)) { + if (options.strictRanges === true) throw rangeError([start, end]); + return []; + } + + // fix negative zero + if (a === 0) a = 0; + if (b === 0) b = 0; + + let descending = a > b; + let startString = String(start); + let endString = String(end); + let stepString = String(step); + step = Math.max(Math.abs(step), 1); + + let padded = zeros(startString) || zeros(endString) || zeros(stepString); + let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; + let toNumber = padded === false && stringify(start, end, options) === false; + let format = options.transform || transform(toNumber); + + if (options.toRegex && step === 1) { + return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); + } + + let parts = { negatives: [], positives: [] }; + let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); + let range = []; + let index = 0; + + while (descending ? a >= b : a <= b) { + if (options.toRegex === true && step > 1) { + push(a); + } else { + range.push(pad(format(a, index), maxLen, toNumber)); + } + a = descending ? a - step : a + step; + index++; + } + + if (options.toRegex === true) { + return step > 1 + ? toSequence(parts, options) + : toRegex(range, null, { wrap: false, ...options }); + } + + return range; +}; + +const fillLetters = (start, end, step = 1, options = {}) => { + if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { + return invalidRange(start, end, options); + } + + + let format = options.transform || (val => String.fromCharCode(val)); + let a = `${start}`.charCodeAt(0); + let b = `${end}`.charCodeAt(0); + + let descending = a > b; + let min = Math.min(a, b); + let max = Math.max(a, b); + + if (options.toRegex && step === 1) { + return toRange(min, max, false, options); + } + + let range = []; + let index = 0; + + while (descending ? a >= b : a <= b) { + range.push(format(a, index)); + a = descending ? a - step : a + step; + index++; + } + + if (options.toRegex === true) { + return toRegex(range, null, { wrap: false, options }); + } + + return range; +}; + +const fill = (start, end, step, options = {}) => { + if (end == null && isValidValue(start)) { + return [start]; + } + + if (!isValidValue(start) || !isValidValue(end)) { + return invalidRange(start, end, options); + } + + if (typeof step === 'function') { + return fill(start, end, 1, { transform: step }); + } + + if (isObject(step)) { + return fill(start, end, 0, step); + } + + let opts = { ...options }; + if (opts.capture === true) opts.wrap = true; + step = step || opts.step || 1; + + if (!isNumber(step)) { + if (step != null && !isObject(step)) return invalidStep(step, opts); + return fill(start, end, 1, step); + } + + if (isNumber(start) && isNumber(end)) { + return fillNumbers(start, end, step, opts); + } + + return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); +}; + +module.exports = fill; + +},{"to-regex-range":82,"util":523}],79:[function(require,module,exports){ +'use strict'; + +var isGlob = require('is-glob'); +var pathPosixDirname = require('path').posix.dirname; +var isWin32 = require('os').platform() === 'win32'; + +var slash = '/'; +var backslash = /\\/g; +var enclosure = /[\{\[].*[\/]*.*[\}\]]$/; +var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; +var escaped = /\\([\*\?\|\[\]\(\)\{\}])/g; + +module.exports = function globParent(str) { + // flip windows path separators + if (isWin32 && str.indexOf(slash) < 0) { + str = str.replace(backslash, slash); + } + + // special case for strings ending in enclosure containing path separator + if (enclosure.test(str)) { + str += slash; + } + + // preserves full path in case of trailing path separator + str += 'a'; + + // remove path parts that are globby + do { + str = pathPosixDirname(str); + } while (isGlob(str) || globby.test(str)); + + // remove escape chars and return result + return str.replace(escaped, '$1'); +}; + +},{"is-glob":364,"os":299,"path":402}],80:[function(require,module,exports){ +/*! + * is-number + * + * Copyright (c) 2014-present, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +module.exports = function(num) { + if (typeof num === 'number') { + return num - num === 0; + } + if (typeof num === 'string' && num.trim() !== '') { + return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); + } + return false; +}; + +},{}],81:[function(require,module,exports){ +'use strict'; + +const util = require('util'); +const braces = require('braces'); +const picomatch = require('picomatch'); +const utils = require('picomatch/lib/utils'); +const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); + +/** + * Returns an array of strings that match one or more glob patterns. + * + * ```js + * const mm = require('micromatch'); + * // mm(list, patterns[, options]); + * + * console.log(mm(['a.js', 'a.txt'], ['*.js'])); + * //=> [ 'a.js' ] + * ``` + * @param {String|Array} list List of strings to match. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} options See available [options](#options) + * @return {Array} Returns an array of matches + * @summary false + * @api public + */ + +const micromatch = (list, patterns, options) => { + patterns = [].concat(patterns); + list = [].concat(list); + + let omit = new Set(); + let keep = new Set(); + let items = new Set(); + let negatives = 0; + + let onResult = state => { + items.add(state.output); + if (options && options.onResult) { + options.onResult(state); + } + }; + + for (let i = 0; i < patterns.length; i++) { + let isMatch = picomatch(String(patterns[i]), { ...options, onResult }, true); + let negated = isMatch.state.negated || isMatch.state.negatedExtglob; + if (negated) negatives++; + + for (let item of list) { + let matched = isMatch(item, true); + + let match = negated ? !matched.isMatch : matched.isMatch; + if (!match) continue; + + if (negated) { + omit.add(matched.output); + } else { + omit.delete(matched.output); + keep.add(matched.output); + } + } + } + + let result = negatives === patterns.length ? [...items] : [...keep]; + let matches = result.filter(item => !omit.has(item)); + + if (options && matches.length === 0) { + if (options.failglob === true) { + throw new Error(`No matches found for "${patterns.join(', ')}"`); + } + + if (options.nonull === true || options.nullglob === true) { + return options.unescape ? patterns.map(p => p.replace(/\\/g, '')) : patterns; + } + } + + return matches; +}; + +/** + * Backwards compatibility + */ + +micromatch.match = micromatch; + +/** + * Returns a matcher function from the given glob `pattern` and `options`. + * The returned function takes a string to match as its only argument and returns + * true if the string is a match. + * + * ```js + * const mm = require('micromatch'); + * // mm.matcher(pattern[, options]); + * + * const isMatch = mm.matcher('*.!(*a)'); + * console.log(isMatch('a.a')); //=> false + * console.log(isMatch('a.b')); //=> true + * ``` + * @param {String} `pattern` Glob pattern + * @param {Object} `options` + * @return {Function} Returns a matcher function. + * @api public + */ + +micromatch.matcher = (pattern, options) => picomatch(pattern, options); + +/** + * Returns true if **any** of the given glob `patterns` match the specified `string`. + * + * ```js + * const mm = require('micromatch'); + * // mm.isMatch(string, patterns[, options]); + * + * console.log(mm.isMatch('a.a', ['b.*', '*.a'])); //=> true + * console.log(mm.isMatch('a.a', 'b.*')); //=> false + * ``` + * @param {String} str The string to test. + * @param {String|Array} patterns One or more glob patterns to use for matching. + * @param {Object} [options] See available [options](#options). + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +micromatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); + +/** + * Backwards compatibility + */ + +micromatch.any = micromatch.isMatch; + +/** + * Returns a list of strings that _**do not match any**_ of the given `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.not(list, patterns[, options]); + * + * console.log(mm.not(['a.a', 'b.b', 'c.c'], '*.a')); + * //=> ['b.b', 'c.c'] + * ``` + * @param {Array} `list` Array of strings to match. + * @param {String|Array} `patterns` One or more glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Array} Returns an array of strings that **do not match** the given patterns. + * @api public + */ + +micromatch.not = (list, patterns, options = {}) => { + patterns = [].concat(patterns).map(String); + let result = new Set(); + let items = []; + + let onResult = state => { + if (options.onResult) options.onResult(state); + items.push(state.output); + }; + + let matches = micromatch(list, patterns, { ...options, onResult }); + + for (let item of items) { + if (!matches.includes(item)) { + result.add(item); + } + } + return [...result]; +}; + +/** + * Returns true if the given `string` contains the given pattern. Similar + * to [.isMatch](#isMatch) but the pattern can match any part of the string. + * + * ```js + * var mm = require('micromatch'); + * // mm.contains(string, pattern[, options]); + * + * console.log(mm.contains('aa/bb/cc', '*b')); + * //=> true + * console.log(mm.contains('aa/bb/cc', '*d')); + * //=> false + * ``` + * @param {String} `str` The string to match. + * @param {String|Array} `patterns` Glob pattern to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if the patter matches any part of `str`. + * @api public + */ + +micromatch.contains = (str, pattern, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util.inspect(str)}"`); + } + + if (Array.isArray(pattern)) { + return pattern.some(p => micromatch.contains(str, p, options)); + } + + if (typeof pattern === 'string') { + if (isEmptyString(str) || isEmptyString(pattern)) { + return false; + } + + if (str.includes(pattern) || (str.startsWith('./') && str.slice(2).includes(pattern))) { + return true; + } + } + + return micromatch.isMatch(str, pattern, { ...options, contains: true }); +}; + +/** + * Filter the keys of the given object with the given `glob` pattern + * and `options`. Does not attempt to match nested keys. If you need this feature, + * use [glob-object][] instead. + * + * ```js + * const mm = require('micromatch'); + * // mm.matchKeys(object, patterns[, options]); + * + * const obj = { aa: 'a', ab: 'b', ac: 'c' }; + * console.log(mm.matchKeys(obj, '*b')); + * //=> { ab: 'b' } + * ``` + * @param {Object} `object` The object with keys to filter. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Object} Returns an object with only keys that match the given patterns. + * @api public + */ + +micromatch.matchKeys = (obj, patterns, options) => { + if (!utils.isObject(obj)) { + throw new TypeError('Expected the first argument to be an object'); + } + let keys = micromatch(Object.keys(obj), patterns, options); + let res = {}; + for (let key of keys) res[key] = obj[key]; + return res; +}; + +/** + * Returns true if some of the strings in the given `list` match any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.some(list, patterns[, options]); + * + * console.log(mm.some(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // true + * console.log(mm.some(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. Returns as soon as the first match is found. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +micromatch.some = (list, patterns, options) => { + let items = [].concat(list); + + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch(String(pattern), options); + if (items.some(item => isMatch(item))) { + return true; + } + } + return false; +}; + +/** + * Returns true if every string in the given `list` matches + * any of the given glob `patterns`. + * + * ```js + * const mm = require('micromatch'); + * // mm.every(list, patterns[, options]); + * + * console.log(mm.every('foo.js', ['foo.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js'])); + * // true + * console.log(mm.every(['foo.js', 'bar.js'], ['*.js', '!foo.js'])); + * // false + * console.log(mm.every(['foo.js'], ['*.js', '!foo.js'])); + * // false + * ``` + * @param {String|Array} `list` The string or array of strings to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +micromatch.every = (list, patterns, options) => { + let items = [].concat(list); + + for (let pattern of [].concat(patterns)) { + let isMatch = picomatch(String(pattern), options); + if (!items.every(item => isMatch(item))) { + return false; + } + } + return true; +}; + +/** + * Returns true if **all** of the given `patterns` match + * the specified string. + * + * ```js + * const mm = require('micromatch'); + * // mm.all(string, patterns[, options]); + * + * console.log(mm.all('foo.js', ['foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', '!foo.js'])); + * // false + * + * console.log(mm.all('foo.js', ['*.js', 'foo.js'])); + * // true + * + * console.log(mm.all('foo.js', ['*.js', 'f*', '*o*', '*o.js'])); + * // true + * ``` + * @param {String|Array} `str` The string to test. + * @param {String|Array} `patterns` One or more glob patterns to use for matching. + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns true if any patterns match `str` + * @api public + */ + +micromatch.all = (str, patterns, options) => { + if (typeof str !== 'string') { + throw new TypeError(`Expected a string: "${util.inspect(str)}"`); + } + + return [].concat(patterns).every(p => picomatch(p, options)(str)); +}; + +/** + * Returns an array of matches captured by `pattern` in `string, or `null` if the pattern did not match. + * + * ```js + * const mm = require('micromatch'); + * // mm.capture(pattern, string[, options]); + * + * console.log(mm.capture('test/*.js', 'test/foo.js')); + * //=> ['foo'] + * console.log(mm.capture('test/*.js', 'foo/bar.css')); + * //=> null + * ``` + * @param {String} `glob` Glob pattern to use for matching. + * @param {String} `input` String to match + * @param {Object} `options` See available [options](#options) for changing how matches are performed + * @return {Boolean} Returns an array of captures if the input matches the glob pattern, otherwise `null`. + * @api public + */ + +micromatch.capture = (glob, input, options) => { + let posix = utils.isWindows(options); + let regex = picomatch.makeRe(String(glob), { ...options, capture: true }); + let match = regex.exec(posix ? utils.toPosixSlashes(input) : input); + + if (match) { + return match.slice(1).map(v => v === void 0 ? '' : v); + } +}; + +/** + * Create a regular expression from the given glob `pattern`. + * + * ```js + * const mm = require('micromatch'); + * // mm.makeRe(pattern[, options]); + * + * console.log(mm.makeRe('*.js')); + * //=> /^(?:(\.[\\\/])?(?!\.)(?=.)[^\/]*?\.js)$/ + * ``` + * @param {String} `pattern` A glob pattern to convert to regex. + * @param {Object} `options` + * @return {RegExp} Returns a regex created from the given pattern. + * @api public + */ + +micromatch.makeRe = (...args) => picomatch.makeRe(...args); + +/** + * Scan a glob pattern to separate the pattern into segments. Used + * by the [split](#split) method. + * + * ```js + * const mm = require('micromatch'); + * const state = mm.scan(pattern[, options]); + * ``` + * @param {String} `pattern` + * @param {Object} `options` + * @return {Object} Returns an object with + * @api public + */ + +micromatch.scan = (...args) => picomatch.scan(...args); + +/** + * Parse a glob pattern to create the source string for a regular + * expression. + * + * ```js + * const mm = require('micromatch'); + * const state = mm(pattern[, options]); + * ``` + * @param {String} `glob` + * @param {Object} `options` + * @return {Object} Returns an object with useful properties and output to be used as regex source string. + * @api public + */ + +micromatch.parse = (patterns, options) => { + let res = []; + for (let pattern of [].concat(patterns || [])) { + for (let str of braces(String(pattern), options)) { + res.push(picomatch.parse(str, options)); + } + } + return res; +}; + +/** + * Process the given brace `pattern`. + * + * ```js + * const { braces } = require('micromatch'); + * console.log(braces('foo/{a,b,c}/bar')); + * //=> [ 'foo/(a|b|c)/bar' ] + * + * console.log(braces('foo/{a,b,c}/bar', { expand: true })); + * //=> [ 'foo/a/bar', 'foo/b/bar', 'foo/c/bar' ] + * ``` + * @param {String} `pattern` String with brace pattern to process. + * @param {Object} `options` Any [options](#options) to change how expansion is performed. See the [braces][] library for all available options. + * @return {Array} + * @api public + */ + +micromatch.braces = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + if ((options && options.nobrace === true) || !/\{.*\}/.test(pattern)) { + return [pattern]; + } + return braces(pattern, options); +}; + +/** + * Expand braces + */ + +micromatch.braceExpand = (pattern, options) => { + if (typeof pattern !== 'string') throw new TypeError('Expected a string'); + return micromatch.braces(pattern, { ...options, expand: true }); +}; + +/** + * Expose micromatch + */ + +module.exports = micromatch; + +},{"braces":71,"picomatch":405,"picomatch/lib/utils":410,"util":523}],82:[function(require,module,exports){ +/*! + * to-regex-range + * + * Copyright (c) 2015-present, Jon Schlinkert. + * Released under the MIT License. + */ + +'use strict'; + +const isNumber = require('is-number'); + +const toRegexRange = (min, max, options) => { + if (isNumber(min) === false) { + throw new TypeError('toRegexRange: expected the first argument to be a number'); + } + + if (max === void 0 || min === max) { + return String(min); + } + + if (isNumber(max) === false) { + throw new TypeError('toRegexRange: expected the second argument to be a number.'); + } + + let opts = { relaxZeros: true, ...options }; + if (typeof opts.strictZeros === 'boolean') { + opts.relaxZeros = opts.strictZeros === false; + } + + let relax = String(opts.relaxZeros); + let shorthand = String(opts.shorthand); + let capture = String(opts.capture); + let wrap = String(opts.wrap); + let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; + + if (toRegexRange.cache.hasOwnProperty(cacheKey)) { + return toRegexRange.cache[cacheKey].result; + } + + let a = Math.min(min, max); + let b = Math.max(min, max); + + if (Math.abs(a - b) === 1) { + let result = min + '|' + max; + if (opts.capture) { + return `(${result})`; + } + if (opts.wrap === false) { + return result; + } + return `(?:${result})`; + } + + let isPadded = hasPadding(min) || hasPadding(max); + let state = { min, max, a, b }; + let positives = []; + let negatives = []; + + if (isPadded) { + state.isPadded = isPadded; + state.maxLen = String(state.max).length; + } + + if (a < 0) { + let newMin = b < 0 ? Math.abs(b) : 1; + negatives = splitToPatterns(newMin, Math.abs(a), state, opts); + a = state.a = 0; + } + + if (b >= 0) { + positives = splitToPatterns(a, b, state, opts); + } + + state.negatives = negatives; + state.positives = positives; + state.result = collatePatterns(negatives, positives, opts); + + if (opts.capture === true) { + state.result = `(${state.result})`; + } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { + state.result = `(?:${state.result})`; + } + + toRegexRange.cache[cacheKey] = state; + return state.result; +}; + +function collatePatterns(neg, pos, options) { + let onlyNegative = filterPatterns(neg, pos, '-', false, options) || []; + let onlyPositive = filterPatterns(pos, neg, '', false, options) || []; + let intersected = filterPatterns(neg, pos, '-?', true, options) || []; + let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); + return subpatterns.join('|'); +} + +function splitToRanges(min, max) { + let nines = 1; + let zeros = 1; + + let stop = countNines(min, nines); + let stops = new Set([max]); + + while (min <= stop && stop <= max) { + stops.add(stop); + nines += 1; + stop = countNines(min, nines); + } + + stop = countZeros(max + 1, zeros) - 1; + + while (min < stop && stop <= max) { + stops.add(stop); + zeros += 1; + stop = countZeros(max + 1, zeros) - 1; + } + + stops = [...stops]; + stops.sort(compare); + return stops; +} + +/** + * Convert a range to a regex pattern + * @param {Number} `start` + * @param {Number} `stop` + * @return {String} + */ + +function rangeToPattern(start, stop, options) { + if (start === stop) { + return { pattern: start, count: [], digits: 0 }; + } + + let zipped = zip(start, stop); + let digits = zipped.length; + let pattern = ''; + let count = 0; + + for (let i = 0; i < digits; i++) { + let [startDigit, stopDigit] = zipped[i]; + + if (startDigit === stopDigit) { + pattern += startDigit; + + } else if (startDigit !== '0' || stopDigit !== '9') { + pattern += toCharacterClass(startDigit, stopDigit, options); + + } else { + count++; + } + } + + if (count) { + pattern += options.shorthand === true ? '\\d' : '[0-9]'; + } + + return { pattern, count: [count], digits }; +} + +function splitToPatterns(min, max, tok, options) { + let ranges = splitToRanges(min, max); + let tokens = []; + let start = min; + let prev; + + for (let i = 0; i < ranges.length; i++) { + let max = ranges[i]; + let obj = rangeToPattern(String(start), String(max), options); + let zeros = ''; + + if (!tok.isPadded && prev && prev.pattern === obj.pattern) { + if (prev.count.length > 1) { + prev.count.pop(); + } + + prev.count.push(obj.count[0]); + prev.string = prev.pattern + toQuantifier(prev.count); + start = max + 1; + continue; + } + + if (tok.isPadded) { + zeros = padZeros(max, tok, options); + } + + obj.string = zeros + obj.pattern + toQuantifier(obj.count); + tokens.push(obj); + start = max + 1; + prev = obj; + } + + return tokens; +} + +function filterPatterns(arr, comparison, prefix, intersection, options) { + let result = []; + + for (let ele of arr) { + let { string } = ele; + + // only push if _both_ are negative... + if (!intersection && !contains(comparison, 'string', string)) { + result.push(prefix + string); + } + + // or _both_ are positive + if (intersection && contains(comparison, 'string', string)) { + result.push(prefix + string); + } + } + return result; +} + +/** + * Zip strings + */ + +function zip(a, b) { + let arr = []; + for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); + return arr; +} + +function compare(a, b) { + return a > b ? 1 : b > a ? -1 : 0; +} + +function contains(arr, key, val) { + return arr.some(ele => ele[key] === val); +} + +function countNines(min, len) { + return Number(String(min).slice(0, -len) + '9'.repeat(len)); +} + +function countZeros(integer, zeros) { + return integer - (integer % Math.pow(10, zeros)); +} + +function toQuantifier(digits) { + let [start = 0, stop = ''] = digits; + if (stop || start > 1) { + return `{${start + (stop ? ',' + stop : '')}}`; + } + return ''; +} + +function toCharacterClass(a, b, options) { + return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; +} + +function hasPadding(str) { + return /^-?(0+)\d/.test(str); +} + +function padZeros(value, tok, options) { + if (!tok.isPadded) { + return value; + } + + let diff = Math.abs(tok.maxLen - String(value).length); + let relax = options.relaxZeros !== false; + + switch (diff) { + case 0: + return ''; + case 1: + return relax ? '0?' : '0'; + case 2: + return relax ? '0{0,2}' : '00'; + default: { + return relax ? `0{0,${diff}}` : `0{${diff}}`; + } + } +} + +/** + * Cache + */ + +toRegexRange.cache = {}; +toRegexRange.clearCache = () => (toRegexRange.cache = {}); + +/** + * Expose `toRegexRange` + */ + +module.exports = toRegexRange; + +},{"is-number":80}],83:[function(require,module,exports){ +"use strict"; +const taskManager = require("./managers/tasks"); +const async_1 = require("./providers/async"); +const stream_1 = require("./providers/stream"); +const sync_1 = require("./providers/sync"); +const settings_1 = require("./settings"); +const utils = require("./utils/index"); +function FastGlob(source, options) { + try { + assertPatternsInput(source); + } + catch (error) { + return Promise.reject(error); + } + const works = getWorks(source, async_1.default, options); + return Promise.all(works).then(utils.array.flatten); +} +(function (FastGlob) { + function sync(source, options) { + assertPatternsInput(source); + const works = getWorks(source, sync_1.default, options); + return utils.array.flatten(works); + } + FastGlob.sync = sync; + function stream(source, options) { + assertPatternsInput(source); + const works = getWorks(source, stream_1.default, options); + /** + * The stream returned by the provider cannot work with an asynchronous iterator. + * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams. + * This affects performance (+25%). I don't see best solution right now. + */ + return utils.stream.merge(works); + } + FastGlob.stream = stream; + function generateTasks(source, options) { + assertPatternsInput(source); + const patterns = [].concat(source); + const settings = new settings_1.default(options); + return taskManager.generate(patterns, settings); + } + FastGlob.generateTasks = generateTasks; +})(FastGlob || (FastGlob = {})); +function getWorks(source, _Provider, options) { + const patterns = [].concat(source); + const settings = new settings_1.default(options); + const tasks = taskManager.generate(patterns, settings); + const provider = new _Provider(settings); + return tasks.map(provider.read, provider); +} +function assertPatternsInput(source) { + if ([].concat(source).every(isString)) { + return; + } + throw new TypeError('Patterns must be a string or an array of strings'); +} +function isString(source) { + /* tslint:disable-next-line strict-type-predicates */ + return typeof source === 'string'; +} +module.exports = FastGlob; + +},{"./managers/tasks":84,"./providers/async":85,"./providers/stream":90,"./providers/sync":91,"./settings":96,"./utils/index":100}],84:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../utils/index"); +function generate(patterns, settings) { + const positivePatterns = getPositivePatterns(patterns); + const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); + /** + * When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check + * filepath directly (without read directory). + */ + const staticPatterns = !settings.caseSensitiveMatch ? [] : positivePatterns.filter(utils.pattern.isStaticPattern); + const dynamicPatterns = !settings.caseSensitiveMatch ? positivePatterns : positivePatterns.filter(utils.pattern.isDynamicPattern); + const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false); + const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true); + return staticTasks.concat(dynamicTasks); +} +exports.generate = generate; +function convertPatternsToTasks(positive, negative, dynamic) { + const positivePatternsGroup = groupPatternsByBaseDirectory(positive); + // When we have a global group – there is no reason to divide the patterns into independent tasks. + // In this case, the global task covers the rest. + if ('.' in positivePatternsGroup) { + const task = convertPatternGroupToTask('.', positive, negative, dynamic); + return [task]; + } + return convertPatternGroupsToTasks(positivePatternsGroup, negative, dynamic); +} +exports.convertPatternsToTasks = convertPatternsToTasks; +function getPositivePatterns(patterns) { + return utils.pattern.getPositivePatterns(patterns); +} +exports.getPositivePatterns = getPositivePatterns; +function getNegativePatternsAsPositive(patterns, ignore) { + const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore); + const positive = negative.map(utils.pattern.convertToPositivePattern); + return positive; +} +exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive; +function groupPatternsByBaseDirectory(patterns) { + return patterns.reduce((collection, pattern) => { + const base = utils.pattern.getBaseDirectory(pattern); + if (base in collection) { + collection[base].push(pattern); + } + else { + collection[base] = [pattern]; + } + return collection; + }, {}); +} +exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory; +function convertPatternGroupsToTasks(positive, negative, dynamic) { + return Object.keys(positive).map((base) => { + return convertPatternGroupToTask(base, positive[base], negative, dynamic); + }); +} +exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks; +function convertPatternGroupToTask(base, positive, negative, dynamic) { + return { + dynamic, + positive, + negative, + base, + patterns: [].concat(positive, negative.map(utils.pattern.convertToNegativePattern)) + }; +} +exports.convertPatternGroupToTask = convertPatternGroupToTask; + +},{"../utils/index":100}],85:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = require("../readers/stream"); +const provider_1 = require("./provider"); +class ProviderAsync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_1.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = []; + return new Promise((resolve, reject) => { + const stream = this.api(root, task, options); + stream.once('error', reject); + stream.on('data', (entry) => entries.push(options.transform(entry))); + stream.once('end', () => resolve(entries)); + }); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderAsync; + +},{"../readers/stream":94,"./provider":89}],86:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils/index"); +class DeepFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + } + getFilter(basePath, positive, negative) { + const maxPatternDepth = this._getMaxPatternDepth(positive); + const negativeRe = this._getNegativePatternsRe(negative); + return (entry) => this._filter(basePath, entry, negativeRe, maxPatternDepth); + } + _getMaxPatternDepth(patterns) { + const globstar = patterns.some(utils.pattern.hasGlobStar); + return globstar ? Infinity : utils.pattern.getMaxNaivePatternsDepth(patterns); + } + _getNegativePatternsRe(patterns) { + const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern); + return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions); + } + _filter(basePath, entry, negativeRe, maxPatternDepth) { + const depth = this._getEntryDepth(basePath, entry.path); + if (this._isSkippedByDeep(depth)) { + return false; + } + if (this._isSkippedByMaxPatternDepth(depth, maxPatternDepth)) { + return false; + } + if (this._isSkippedSymbolicLink(entry)) { + return false; + } + if (this._isSkippedDotDirectory(entry)) { + return false; + } + return this._isSkippedByNegativePatterns(entry, negativeRe); + } + _getEntryDepth(basePath, entryPath) { + const basePathDepth = basePath.split('/').length; + const entryPathDepth = entryPath.split('/').length; + return entryPathDepth - (basePath === '' ? 0 : basePathDepth); + } + _isSkippedByDeep(entryDepth) { + return entryDepth >= this._settings.deep; + } + _isSkippedByMaxPatternDepth(entryDepth, maxPatternDepth) { + return !this._settings.baseNameMatch && maxPatternDepth !== Infinity && entryDepth > maxPatternDepth; + } + _isSkippedSymbolicLink(entry) { + return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink(); + } + _isSkippedDotDirectory(entry) { + return !this._settings.dot && entry.name.startsWith('.'); + } + _isSkippedByNegativePatterns(entry, negativeRe) { + return !utils.pattern.matchAny(entry.path, negativeRe); + } +} +exports.default = DeepFilter; + +},{"../../utils/index":100}],87:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils/index"); +class EntryFilter { + constructor(_settings, _micromatchOptions) { + this._settings = _settings; + this._micromatchOptions = _micromatchOptions; + this.index = new Map(); + } + getFilter(positive, negative) { + const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions); + const negativeRe = utils.pattern.convertPatternsToRe(negative, this._micromatchOptions); + return (entry) => this._filter(entry, positiveRe, negativeRe); + } + _filter(entry, positiveRe, negativeRe) { + if (this._settings.unique) { + if (this._isDuplicateEntry(entry)) { + return false; + } + this._createIndexRecord(entry); + } + if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) { + return false; + } + if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) { + return false; + } + const filepath = this._settings.baseNameMatch ? entry.name : entry.path; + return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe); + } + _isDuplicateEntry(entry) { + return this.index.has(entry.path); + } + _createIndexRecord(entry) { + this.index.set(entry.path, undefined); + } + _onlyFileFilter(entry) { + return this._settings.onlyFiles && !entry.dirent.isFile(); + } + _onlyDirectoryFilter(entry) { + return this._settings.onlyDirectories && !entry.dirent.isDirectory(); + } + _isSkippedByAbsoluteNegativePatterns(entry, negativeRe) { + if (!this._settings.absolute) { + return false; + } + const fullpath = utils.path.makeAbsolute(this._settings.cwd, entry.path); + return this._isMatchToPatterns(fullpath, negativeRe); + } + _isMatchToPatterns(filepath, patternsRe) { + return utils.pattern.matchAny(filepath, patternsRe); + } +} +exports.default = EntryFilter; + +},{"../../utils/index":100}],88:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils/index"); +class ErrorFilter { + constructor(_settings) { + this._settings = _settings; + } + getFilter() { + return (error) => this._isNonFatalError(error); + } + _isNonFatalError(error) { + return utils.errno.isEnoentCodeError(error) || this._settings.suppressErrors; + } +} +exports.default = ErrorFilter; + +},{"../../utils/index":100}],89:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +const deep_1 = require("./filters/deep"); +const entry_1 = require("./filters/entry"); +const error_1 = require("./filters/error"); +const entry_2 = require("./transformers/entry"); +class Provider { + constructor(_settings) { + this._settings = _settings; + this.errorFilter = new error_1.default(this._settings); + this.entryFilter = new entry_1.default(this._settings, this._getMicromatchOptions()); + this.deepFilter = new deep_1.default(this._settings, this._getMicromatchOptions()); + this.entryTransformer = new entry_2.default(this._settings); + } + _getRootDirectory(task) { + return path.resolve(this._settings.cwd, task.base); + } + _getReaderOptions(task) { + const basePath = task.base === '.' ? '' : task.base; + return { + basePath, + pathSegmentSeparator: '/', + concurrency: this._settings.concurrency, + deepFilter: this.deepFilter.getFilter(basePath, task.positive, task.negative), + entryFilter: this.entryFilter.getFilter(task.positive, task.negative), + errorFilter: this.errorFilter.getFilter(), + followSymbolicLinks: this._settings.followSymbolicLinks, + fs: this._settings.fs, + stats: this._settings.stats, + throwErrorOnBrokenSymbolicLink: this._settings.throwErrorOnBrokenSymbolicLink, + transform: this.entryTransformer.getTransformer() + }; + } + _getMicromatchOptions() { + return { + dot: this._settings.dot, + matchBase: this._settings.baseNameMatch, + nobrace: !this._settings.braceExpansion, + nocase: !this._settings.caseSensitiveMatch, + noext: !this._settings.extglob, + noglobstar: !this._settings.globstar, + posix: true + }; + } +} +exports.default = Provider; + +},{"./filters/deep":86,"./filters/entry":87,"./filters/error":88,"./transformers/entry":92,"path":402}],90:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = require("stream"); +const stream_2 = require("../readers/stream"); +const provider_1 = require("./provider"); +class ProviderStream extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new stream_2.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const source = this.api(root, task, options); + const dest = new stream_1.Readable({ objectMode: true, read: () => { } }); + source + .once('error', (error) => dest.emit('error', error)) + .on('data', (entry) => dest.emit('data', options.transform(entry))) + .once('end', () => dest.emit('end')); + return dest; + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderStream; + +},{"../readers/stream":94,"./provider":89,"stream":503}],91:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const sync_1 = require("../readers/sync"); +const provider_1 = require("./provider"); +class ProviderSync extends provider_1.default { + constructor() { + super(...arguments); + this._reader = new sync_1.default(this._settings); + } + read(task) { + const root = this._getRootDirectory(task); + const options = this._getReaderOptions(task); + const entries = this.api(root, task, options); + return entries.map(options.transform); + } + api(root, task, options) { + if (task.dynamic) { + return this._reader.dynamic(root, options); + } + return this._reader.static(task.patterns, options); + } +} +exports.default = ProviderSync; + +},{"../readers/sync":95,"./provider":89}],92:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const utils = require("../../utils/index"); +class EntryTransformer { + constructor(_settings) { + this._settings = _settings; + } + getTransformer() { + return (entry) => this._transform(entry); + } + _transform(entry) { + let filepath = entry.path; + if (this._settings.absolute) { + filepath = utils.path.makeAbsolute(this._settings.cwd, filepath); + filepath = utils.path.unixify(filepath); + } + if (this._settings.markDirectories && entry.dirent.isDirectory()) { + filepath += '/'; + } + if (!this._settings.objectMode) { + return filepath; + } + return Object.assign({}, entry, { path: filepath }); + } +} +exports.default = EntryTransformer; + +},{"../../utils/index":100}],93:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +const fsStat = require("@nodelib/fs.stat"); +const utils = require("../utils/index"); +class Reader { + constructor(_settings) { + this._settings = _settings; + this._fsStatSettings = new fsStat.Settings({ + followSymbolicLink: this._settings.followSymbolicLinks, + fs: this._settings.fs, + throwErrorOnBrokenSymbolicLink: this._settings.followSymbolicLinks + }); + } + _getFullEntryPath(filepath) { + return path.resolve(this._settings.cwd, filepath); + } + _makeEntry(stats, pattern) { + const entry = { + name: pattern, + path: pattern, + dirent: utils.fs.createDirentFromStats(pattern, stats) + }; + if (this._settings.stats) { + entry.stats = stats; + } + return entry; + } + _isFatalError(error) { + return !utils.errno.isEnoentCodeError(error) && !this._settings.suppressErrors; + } +} +exports.default = Reader; + +},{"../utils/index":100,"@nodelib/fs.stat":10,"path":402}],94:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const stream_1 = require("stream"); +const fsStat = require("@nodelib/fs.stat"); +const fsWalk = require("@nodelib/fs.walk"); +const reader_1 = require("./reader"); +class ReaderStream extends reader_1.default { + constructor() { + super(...arguments); + this._walkStream = fsWalk.walkStream; + this._stat = fsStat.stat; + } + dynamic(root, options) { + return this._walkStream(root, options); + } + static(patterns, options) { + const filepaths = patterns.map(this._getFullEntryPath, this); + const stream = new stream_1.PassThrough({ objectMode: true }); + stream._write = (index, _enc, done) => { + return this._getEntry(filepaths[index], patterns[index], options) + .then((entry) => { + if (entry !== null && options.entryFilter(entry)) { + stream.push(entry); + } + if (index === filepaths.length - 1) { + stream.end(); + } + done(); + }) + .catch(done); + }; + for (let i = 0; i < filepaths.length; i++) { + stream.write(i); + } + return stream; + } + _getEntry(filepath, pattern, options) { + return this._getStat(filepath) + .then((stats) => this._makeEntry(stats, pattern)) + .catch((error) => { + if (options.errorFilter(error)) { + return null; + } + throw error; + }); + } + _getStat(filepath) { + return new Promise((resolve, reject) => { + this._stat(filepath, this._fsStatSettings, (error, stats) => { + error ? reject(error) : resolve(stats); + }); + }); + } +} +exports.default = ReaderStream; + +},{"./reader":93,"@nodelib/fs.stat":10,"@nodelib/fs.walk":14,"stream":503}],95:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fsStat = require("@nodelib/fs.stat"); +const fsWalk = require("@nodelib/fs.walk"); +const reader_1 = require("./reader"); +class ReaderSync extends reader_1.default { + constructor() { + super(...arguments); + this._walkSync = fsWalk.walkSync; + this._statSync = fsStat.statSync; + } + dynamic(root, options) { + return this._walkSync(root, options); + } + static(patterns, options) { + const entries = []; + for (const pattern of patterns) { + const filepath = this._getFullEntryPath(pattern); + const entry = this._getEntry(filepath, pattern, options); + if (entry === null || !options.entryFilter(entry)) { + continue; + } + entries.push(entry); + } + return entries; + } + _getEntry(filepath, pattern, options) { + try { + const stats = this._getStat(filepath); + return this._makeEntry(stats, pattern); + } + catch (error) { + if (options.errorFilter(error)) { + return null; + } + throw error; + } + } + _getStat(filepath) { + return this._statSync(filepath, this._fsStatSettings); + } +} +exports.default = ReaderSync; + +},{"./reader":93,"@nodelib/fs.stat":10,"@nodelib/fs.walk":14}],96:[function(require,module,exports){ +(function (process){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = require("fs"); +const os = require("os"); +const CPU_COUNT = os.cpus().length; +exports.DEFAULT_FILE_SYSTEM_ADAPTER = { + lstat: fs.lstat, + lstatSync: fs.lstatSync, + stat: fs.stat, + statSync: fs.statSync, + readdir: fs.readdir, + readdirSync: fs.readdirSync +}; +// tslint:enable no-redundant-jsdoc +class Settings { + constructor(_options = {}) { + this._options = _options; + this.absolute = this._getValue(this._options.absolute, false); + this.baseNameMatch = this._getValue(this._options.baseNameMatch, false); + this.braceExpansion = this._getValue(this._options.braceExpansion, true); + this.caseSensitiveMatch = this._getValue(this._options.caseSensitiveMatch, true); + this.concurrency = this._getValue(this._options.concurrency, CPU_COUNT); + this.cwd = this._getValue(this._options.cwd, process.cwd()); + this.deep = this._getValue(this._options.deep, Infinity); + this.dot = this._getValue(this._options.dot, false); + this.extglob = this._getValue(this._options.extglob, true); + this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, true); + this.fs = this._getFileSystemMethods(this._options.fs); + this.globstar = this._getValue(this._options.globstar, true); + this.ignore = this._getValue(this._options.ignore, []); + this.markDirectories = this._getValue(this._options.markDirectories, false); + this.objectMode = this._getValue(this._options.objectMode, false); + this.onlyDirectories = this._getValue(this._options.onlyDirectories, false); + this.onlyFiles = this._getValue(this._options.onlyFiles, true); + this.stats = this._getValue(this._options.stats, false); + this.suppressErrors = this._getValue(this._options.suppressErrors, false); + this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, false); + this.unique = this._getValue(this._options.unique, true); + if (this.onlyDirectories) { + this.onlyFiles = false; + } + if (this.stats) { + this.objectMode = true; + } + } + _getValue(option, value) { + return option === undefined ? value : option; + } + _getFileSystemMethods(methods = {}) { + return Object.assign({}, exports.DEFAULT_FILE_SYSTEM_ADAPTER, methods); + } +} +exports.default = Settings; + +}).call(this,require('_process')) +},{"_process":432,"fs":296,"os":299}],97:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function flatten(items) { + return items.reduce((collection, item) => [].concat(collection, item), []); +} +exports.flatten = flatten; + +},{}],98:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function isEnoentCodeError(error) { + return error.code === 'ENOENT'; +} +exports.isEnoentCodeError = isEnoentCodeError; + +},{}],99:[function(require,module,exports){ +arguments[4][7][0].apply(exports,arguments) +},{"dup":7}],100:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const array = require("./array"); +exports.array = array; +const errno = require("./errno"); +exports.errno = errno; +const fs = require("./fs"); +exports.fs = fs; +const path = require("./path"); +exports.path = path; +const pattern = require("./pattern"); +exports.pattern = pattern; +const stream = require("./stream"); +exports.stream = stream; + +},{"./array":97,"./errno":98,"./fs":99,"./path":101,"./pattern":102,"./stream":103}],101:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +/** + * Designed to work only with simple paths: `dir\\file`. + */ +function unixify(filepath) { + return filepath.replace(/\\/g, '/'); +} +exports.unixify = unixify; +function makeAbsolute(cwd, filepath) { + return path.resolve(cwd, filepath); +} +exports.makeAbsolute = makeAbsolute; + +},{"path":402}],102:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const path = require("path"); +const globParent = require("glob-parent"); +const isGlob = require("is-glob"); +const micromatch = require("micromatch"); +const GLOBSTAR = '**'; +function isStaticPattern(pattern) { + return !isDynamicPattern(pattern); +} +exports.isStaticPattern = isStaticPattern; +function isDynamicPattern(pattern) { + return isGlob(pattern, { strict: false }); +} +exports.isDynamicPattern = isDynamicPattern; +function convertToPositivePattern(pattern) { + return isNegativePattern(pattern) ? pattern.slice(1) : pattern; +} +exports.convertToPositivePattern = convertToPositivePattern; +function convertToNegativePattern(pattern) { + return '!' + pattern; +} +exports.convertToNegativePattern = convertToNegativePattern; +function isNegativePattern(pattern) { + return pattern.startsWith('!') && pattern[1] !== '('; +} +exports.isNegativePattern = isNegativePattern; +function isPositivePattern(pattern) { + return !isNegativePattern(pattern); +} +exports.isPositivePattern = isPositivePattern; +function getNegativePatterns(patterns) { + return patterns.filter(isNegativePattern); +} +exports.getNegativePatterns = getNegativePatterns; +function getPositivePatterns(patterns) { + return patterns.filter(isPositivePattern); +} +exports.getPositivePatterns = getPositivePatterns; +function getBaseDirectory(pattern) { + return globParent(pattern); +} +exports.getBaseDirectory = getBaseDirectory; +function hasGlobStar(pattern) { + return pattern.indexOf(GLOBSTAR) !== -1; +} +exports.hasGlobStar = hasGlobStar; +function endsWithSlashGlobStar(pattern) { + return pattern.endsWith('/' + GLOBSTAR); +} +exports.endsWithSlashGlobStar = endsWithSlashGlobStar; +function isAffectDepthOfReadingPattern(pattern) { + const basename = path.basename(pattern); + return endsWithSlashGlobStar(pattern) || isStaticPattern(basename); +} +exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern; +function getNaiveDepth(pattern) { + const base = getBaseDirectory(pattern); + const patternDepth = pattern.split('/').length; + const patternBaseDepth = base.split('/').length; + /** + * This is a hack for pattern that has no base directory. + * + * This is related to the `*\something\*` pattern. + */ + if (base === '.') { + return patternDepth - patternBaseDepth; + } + return patternDepth - patternBaseDepth - 1; +} +exports.getNaiveDepth = getNaiveDepth; +function getMaxNaivePatternsDepth(patterns) { + return patterns.reduce((max, pattern) => { + const depth = getNaiveDepth(pattern); + return depth > max ? depth : max; + }, 0); +} +exports.getMaxNaivePatternsDepth = getMaxNaivePatternsDepth; +function makeRe(pattern, options) { + return micromatch.makeRe(pattern, options); +} +exports.makeRe = makeRe; +function convertPatternsToRe(patterns, options) { + return patterns.map((pattern) => makeRe(pattern, options)); +} +exports.convertPatternsToRe = convertPatternsToRe; +function matchAny(entry, patternsRe) { + const filepath = entry.replace(/^\.[\\\/]/, ''); + return patternsRe.some((patternRe) => patternRe.test(filepath)); +} +exports.matchAny = matchAny; + +},{"glob-parent":79,"is-glob":364,"micromatch":81,"path":402}],103:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const merge2 = require("merge2"); +function merge(streams) { + const mergedStream = merge2(streams); + streams.forEach((stream) => { + stream.once('error', (err) => mergedStream.emit('error', err)); + }); + return mergedStream; +} +exports.merge = merge; + +},{"merge2":379}],104:[function(require,module,exports){ +'use strict' + +var reusify = require('reusify') + +function fastqueue (context, worker, concurrency) { + if (typeof context === 'function') { + concurrency = worker + worker = context + context = null + } + + var cache = reusify(Task) + var queueHead = null + var queueTail = null + var _running = 0 + + var self = { + push: push, + drain: noop, + saturated: noop, + pause: pause, + paused: false, + concurrency: concurrency, + running: running, + resume: resume, + idle: idle, + length: length, + unshift: unshift, + empty: noop, + kill: kill, + killAndDrain: killAndDrain + } + + return self + + function running () { + return _running + } + + function pause () { + self.paused = true + } + + function length () { + var current = queueHead + var counter = 0 + + while (current) { + current = current.next + counter++ + } + + return counter + } + + function resume () { + if (!self.paused) return + self.paused = false + for (var i = 0; i < self.concurrency; i++) { + _running++ + release() + } + } + + function idle () { + return _running === 0 && self.length() === 0 + } + + function push (value, done) { + var current = cache.get() + + current.context = context + current.release = release + current.value = value + current.callback = done || noop + + if (_running === self.concurrency || self.paused) { + if (queueTail) { + queueTail.next = current + queueTail = current + } else { + queueHead = current + queueTail = current + self.saturated() + } + } else { + _running++ + worker.call(context, current.value, current.worked) + } + } + + function unshift (value, done) { + var current = cache.get() + + current.context = context + current.release = release + current.value = value + current.callback = done || noop + + if (_running === self.concurrency || self.paused) { + if (queueHead) { + current.next = queueHead + queueHead = current + } else { + queueHead = current + queueTail = current + self.saturated() + } + } else { + _running++ + worker.call(context, current.value, current.worked) + } + } + + function release (holder) { + if (holder) { + cache.release(holder) + } + var next = queueHead + if (next) { + if (!self.paused) { + if (queueTail === queueHead) { + queueTail = null + } + queueHead = next.next + next.next = null + worker.call(context, next.value, next.worked) + if (queueTail === null) { + self.empty() + } + } else { + _running-- + } + } else if (--_running === 0) { + self.drain() + } + } + + function kill () { + queueHead = null + queueTail = null + self.drain = noop + } + + function killAndDrain () { + queueHead = null + queueTail = null + self.drain() + self.drain = noop + } +} + +function noop () {} + +function Task () { + this.value = null + this.callback = noop + this.next = null + this.release = noop + this.context = null + + var self = this + + this.worked = function worked (err, result) { + var callback = self.callback + self.value = null + self.callback = noop + callback.call(self.context, err, result) + self.release(self) + } +} + +module.exports = fastqueue + +},{"reusify":486}],105:[function(require,module,exports){ +var util = require('utils-extend'); +/** + * @description + * @example + * `**\/*` match all files + * `*.js` only match current dir files + * '**\/*.js' match all js files + * 'path/*.js' match js files in path + * '!*.js' exclude js files + */ +function fileMatch(filter, ignore) { + if (filter === null) { + return function() { + return true; + }; + } else if (filter === '' || (util.isArray(filter) && !filter.length)) { + return function() { + return false; + }; + } + + if (util.isString(filter)) { + filter = [filter]; + } + + var match = []; + var negate = []; + var isIgnore = ignore ? 'i' : ''; + + filter.forEach(function(item) { + var isNegate = item.indexOf('!') === 0; + item = item + .replace(/^!/, '') + .replace(/\*(?![\/*])/, '[^/]*?') + .replace('**\/', '([^/]+\/)*') + .replace(/\{([^\}]+)\}/g, function($1, $2) { + var collection = $2.split(','); + var length = collection.length; + var result = '(?:'; + + collection.forEach(function(item, index) { + result += '(' + item.trim() + ')'; + + if (index + 1 !== length) { + result += '|'; + } + }); + + result += ')'; + + return result; + }) + .replace(/([\/\.])/g, '\\$1'); + + item = '(^' + item + '$)'; + + if (isNegate) { + negate.push(item); + } else { + match.push(item); + } + }); + + match = match.length ? new RegExp(match.join('|'), isIgnore) : null; + negate = negate.length ? new RegExp(negate.join('|'), isIgnore) : null; + + return function(filepath) { + // Normalize \\ paths to / paths. + filepath = util.path.unixifyPath(filepath); + + if (negate && negate.test(filepath)) { + return false; + } + + if (match && match.test(filepath)) { + return true; + } + + return false; + }; +} + +module.exports = fileMatch; +},{"utils-extend":524}],106:[function(require,module,exports){ +/** + * @fileoverview Strengthen the ability of file system + * @author wliao + */ +var fs = require('fs'); +var util = require('utils-extend'); +var path = require('path'); +var fileMatch = require('file-match'); + +function checkCbAndOpts(options, callback) { + if (util.isFunction(options)) { + return { + options: null, + callback: options + }; + } else if (util.isObject(options)) { + return { + options: options, + callback: callback + }; + } else { + return { + options: null, + callback: util.noop + }; + } +} + +function getExists(filepath) { + var exists = fs.existsSync(filepath); + + if (exists) { + return filepath; + } else { + return getExists(path.dirname(filepath)); + } +} + +util.extend(exports, fs); + +/** + * @description + * Assign node origin methods to fs + */ +exports.fs = fs; + +exports.fileMatch = fileMatch; + +/** + * @description + * Create dir, if dir exist, it will only invoke callback. + * + * @example + * ```js + * fs.mkdir('1/2/3/4/5', 511); + * fs.mkdir('path/2/3', function() {}); + * ``` + */ +exports.mkdir = function(filepath, mode, callback) { + var root = getExists(filepath); + var children = path.relative(root, filepath); + + if (util.isFunction(mode)) { + callback = mode; + mode = null; + } + + if (!util.isFunction(callback)) { + callback = util.noop; + } + + mode = mode || 511; + + if (!children) return callback(); + + children = children.split(path.sep); + + function create(filepath) { + if (create.count === children.length) { + return callback(); + } + + filepath = path.join(filepath, children[create.count]); + + fs.mkdir(filepath, mode, function(err) { + create.count++; + create(filepath); + }); + } + + create.count = 0; + create(root); +}; + +/** + * @description + * Same as mkdir, but it is synchronous + */ +exports.mkdirSync = function(filepath, mode) { + var root = getExists(filepath); + var children = path.relative(root, filepath); + + if (!children) return; + + children = children.split(path.sep); + + children.forEach(function(item) { + root = path.join(root, item); + fs.mkdirSync(root, mode); + }); +}; + +/** + * @description + * Create file, if path don't exists, it will not throw error. + * And will mkdir for path, it is asynchronous + * + * @example + * ```js + * fs.writeFile('path/filename.txt', 'something') + * fs.writeFile('path/filename.txt', 'something', {}) + * ``` + */ +exports.writeFile = function(filename, data, options, callback) { + var result = checkCbAndOpts(options, callback); + var dirname = path.dirname(filename); + options = result.options; + callback = result.callback; + + // Create dir first + exports.mkdir(dirname, function() { + fs.writeFile(filename, data, options, callback); + }); +}; + +/** + * @description + * Same as writeFile, but it is synchronous + */ +exports.writeFileSync = function(filename, data, options) { + var dirname = path.dirname(filename); + + exports.mkdirSync(dirname); + fs.writeFileSync(filename, data, options); +}; + +/** + * @description + * Asynchronously copy a file + * @example + * file.copyFile('demo.txt', 'demo.dest.txt', { done: function(err) { }}) + */ +exports.copyFile = function(srcpath, destpath, options) { + options = util.extend({ + encoding: 'utf8', + done: util.noop + }, options || {}); + + if (!options.process) { + options.encoding = null; + } + + fs.readFile(srcpath, { + encoding: options.encoding + }, function(err, contents) { + if (err) return options.done(err); + + if (options.process) { + contents = options.process(contents); + } + + exports.writeFile(destpath, contents, options, options.done); + }); +}; + +/** + * @description + * Copy file to dest, if no process options, it will only copy file to dest + * @example + * file.copyFileSync('demo.txt', 'demo.dest.txt' { process: function(contents) { }}); + * file.copyFileSync('demo.png', 'dest.png'); + */ +exports.copyFileSync = function(srcpath, destpath, options) { + options = util.extend({ + encoding: 'utf8' + }, options || {}); + var contents; + + if (options.process) { + contents = fs.readFileSync(srcpath, options); + contents = options.process(contents, srcpath, options.relative); + + if (util.isObject(contents) && contents.filepath) { + destpath = contents.filepath; + contents = contents.contents; + } + + exports.writeFileSync(destpath, contents, options); + } else { + contents = fs.readFileSync(srcpath); + exports.writeFileSync(destpath, contents); + } +}; + +/** + * @description + * Recurse into a directory, executing callback for each file and folder + * if the filename is undefiend, the callback is for folder, otherwise for file. + * and it is asynchronous + * @example + * file.recurse('path', function(filepath, filename) { }); + * file.recurse('path', ['*.js', 'path/**\/*.html'], function(filepath, relative, filename) { }); + */ +exports.recurse = function(dirpath, filter, callback) { + if (util.isFunction(filter)) { + callback = filter; + filter = null; + } + var filterCb = fileMatch(filter); + var rootpath = dirpath; + + function recurse(dirpath) { + fs.readdir(dirpath, function(err, files) { + if (err) return callback(err); + + files.forEach(function(filename) { + var filepath = path.join(dirpath, filename); + + fs.stat(filepath, function(err, stats) { + var relative = path.relative(rootpath, filepath); + var flag = filterCb(relative); + + if (stats.isDirectory()) { + recurse(filepath); + if (flag) callback(filepath, relative); + } else { + if (flag) callback(filepath, relative, filename); + } + }); + }); + }); + } + + recurse(dirpath); +}; + +/** + * @description + * Same as recurse, but it is synchronous + * @example + * file.recurseSync('path', function(filepath, filename) {}); + * file.recurseSync('path', ['*.js', 'path/**\/*.html'], function(filepath, relative, filename) {}); + */ +exports.recurseSync = function(dirpath, filter, callback) { + if (util.isFunction(filter)) { + callback = filter; + filter = null; + } + var filterCb = fileMatch(filter); + var rootpath = dirpath; + + function recurse(dirpath) { + fs.readdirSync(dirpath).forEach(function(filename) { + var filepath = path.join(dirpath, filename); + var stats = fs.statSync(filepath); + var relative = path.relative(rootpath, filepath); + var flag = filterCb(relative); + + if (stats.isDirectory()) { + recurse(filepath); + if (flag) callback(filepath, relative); + } else { + if (flag) callback(filepath, relative, filename); + } + }); + } + + recurse(dirpath); +}; + +/** + * @description + * Remove folder and files in folder, but it's synchronous + * @example + * file.rmdirSync('path'); + */ +exports.rmdirSync = function(dirpath) { + exports.recurseSync(dirpath, function(filepath, relative, filename) { + // it is file, otherwise it's folder + if (filename) { + fs.unlinkSync(filepath); + } else { + fs.rmdirSync(filepath); + } + }); + + fs.rmdirSync(dirpath); +}; + +/** + * @description + * Copy dirpath to destpath, pass process callback for each file hanlder + * if you want to change the dest filepath, process callback return { contents: '', filepath: ''} + * otherwise only change contents + * @example + * file.copySync('path', 'dest'); + * file.copySync('src', 'dest/src'); + * file.copySync('path', 'dest', { process: function(contents, filepath) {} }); + * file.copySync('path', 'dest', { process: function(contents, filepath) {} }, noProcess: ['']); + */ +exports.copySync = function(dirpath, destpath, options) { + options = util.extend({ + encoding: 'utf8', + filter: null, + noProcess: '' + }, options || {}); + var noProcessCb = fileMatch(options.noProcess); + + // Make sure dest root + exports.mkdirSync(destpath); + exports.recurseSync(dirpath, options.filter, function(filepath, relative, filename) { + if (!filename) return; + var newpath = path.join(destpath, relative); + var opts = { + relative: relative + }; + + if (options.process && !noProcessCb(relative)) { + opts.encoding = options.encoding; + opts.process = options.process; + } + + exports.copyFileSync(filepath, newpath, opts); + }); +}; +},{"file-match":105,"fs":296,"path":402,"utils-extend":524}],107:[function(require,module,exports){ +(function (Buffer){ +'use strict'; +const { + multiByteIndexOf, + stringToBytes, + readUInt64LE, + tarHeaderChecksumMatches, + uint8ArrayUtf8ByteString +} = require('./util'); +const supported = require('./supported'); + +const xpiZipFilename = stringToBytes('META-INF/mozilla.rsa'); +const oxmlContentTypes = stringToBytes('[Content_Types].xml'); +const oxmlRels = stringToBytes('_rels/.rels'); + +const fileType = input => { + if (!(input instanceof Uint8Array || input instanceof ArrayBuffer || Buffer.isBuffer(input))) { + throw new TypeError(`Expected the \`input\` argument to be of type \`Uint8Array\` or \`Buffer\` or \`ArrayBuffer\`, got \`${typeof input}\``); + } + + const buffer = input instanceof Uint8Array ? input : new Uint8Array(input); + + if (!(buffer && buffer.length > 1)) { + return; + } + + const check = (header, options) => { + options = { + offset: 0, + ...options + }; + + for (let i = 0; i < header.length; i++) { + // If a bitmask is set + if (options.mask) { + // If header doesn't equal `buf` with bits masked off + if (header[i] !== (options.mask[i] & buffer[i + options.offset])) { + return false; + } + } else if (header[i] !== buffer[i + options.offset]) { + return false; + } + } + + return true; + }; + + const checkString = (header, options) => check(stringToBytes(header), options); + + if (check([0xFF, 0xD8, 0xFF])) { + return { + ext: 'jpg', + mime: 'image/jpeg' + }; + } + + if (check([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) { + // APNG format (https://wiki.mozilla.org/APNG_Specification) + // 1. Find the first IDAT (image data) chunk (49 44 41 54) + // 2. Check if there is an "acTL" chunk before the IDAT one (61 63 54 4C) + + // Offset calculated as follows: + // - 8 bytes: PNG signature + // - 4 (length) + 4 (chunk type) + 13 (chunk data) + 4 (CRC): IHDR chunk + const startIndex = 33; + const firstImageDataChunkIndex = buffer.findIndex((el, i) => i >= startIndex && buffer[i] === 0x49 && buffer[i + 1] === 0x44 && buffer[i + 2] === 0x41 && buffer[i + 3] === 0x54); + const sliced = buffer.subarray(startIndex, firstImageDataChunkIndex); + + if (sliced.findIndex((el, i) => sliced[i] === 0x61 && sliced[i + 1] === 0x63 && sliced[i + 2] === 0x54 && sliced[i + 3] === 0x4C) >= 0) { + return { + ext: 'apng', + mime: 'image/apng' + }; + } + + return { + ext: 'png', + mime: 'image/png' + }; + } + + if (check([0x47, 0x49, 0x46])) { + return { + ext: 'gif', + mime: 'image/gif' + }; + } + + if (check([0x57, 0x45, 0x42, 0x50], {offset: 8})) { + return { + ext: 'webp', + mime: 'image/webp' + }; + } + + if (check([0x46, 0x4C, 0x49, 0x46])) { + return { + ext: 'flif', + mime: 'image/flif' + }; + } + + // `cr2`, `orf`, and `arw` need to be before `tif` check + if ( + (check([0x49, 0x49, 0x2A, 0x0]) || check([0x4D, 0x4D, 0x0, 0x2A])) && + check([0x43, 0x52], {offset: 8}) + ) { + return { + ext: 'cr2', + mime: 'image/x-canon-cr2' + }; + } + + if (check([0x49, 0x49, 0x52, 0x4F, 0x08, 0x00, 0x00, 0x00, 0x18])) { + return { + ext: 'orf', + mime: 'image/x-olympus-orf' + }; + } + + if ( + check([0x49, 0x49, 0x2A, 0x00]) && + (check([0x10, 0xFB, 0x86, 0x01], {offset: 4}) || check([0x08, 0x00, 0x00, 0x00], {offset: 4})) && + // This pattern differentiates ARW from other TIFF-ish file types: + check([0x00, 0xFE, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x01], {offset: 9}) + ) { + return { + ext: 'arw', + mime: 'image/x-sony-arw' + }; + } + + if ( + check([0x49, 0x49, 0x2A, 0x00, 0x08, 0x00, 0x00, 0x00]) && + (check([0x2D, 0x00, 0xFE, 0x00], {offset: 8}) || + check([0x27, 0x00, 0xFE, 0x00], {offset: 8})) + ) { + return { + ext: 'dng', + mime: 'image/x-adobe-dng' + }; + } + + if ( + check([0x49, 0x49, 0x2A, 0x00]) && + check([0x1C, 0x00, 0xFE, 0x00], {offset: 8}) + ) { + return { + ext: 'nef', + mime: 'image/x-nikon-nef' + }; + } + + if (check([0x49, 0x49, 0x55, 0x00, 0x18, 0x00, 0x00, 0x00, 0x88, 0xE7, 0x74, 0xD8])) { + return { + ext: 'rw2', + mime: 'image/x-panasonic-rw2' + }; + } + + // `raf` is here just to keep all the raw image detectors together. + if (checkString('FUJIFILMCCD-RAW')) { + return { + ext: 'raf', + mime: 'image/x-fujifilm-raf' + }; + } + + if ( + check([0x49, 0x49, 0x2A, 0x0]) || + check([0x4D, 0x4D, 0x0, 0x2A]) + ) { + return { + ext: 'tif', + mime: 'image/tiff' + }; + } + + if (check([0x42, 0x4D])) { + return { + ext: 'bmp', + mime: 'image/bmp' + }; + } + + if (check([0x49, 0x49, 0xBC])) { + return { + ext: 'jxr', + mime: 'image/vnd.ms-photo' + }; + } + + if (check([0x38, 0x42, 0x50, 0x53])) { + return { + ext: 'psd', + mime: 'image/vnd.adobe.photoshop' + }; + } + + // Zip-based file formats + // Need to be before the `zip` check + const zipHeader = [0x50, 0x4B, 0x3, 0x4]; + if (check(zipHeader)) { + if ( + check([0x6D, 0x69, 0x6D, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x65, 0x70, 0x75, 0x62, 0x2B, 0x7A, 0x69, 0x70], {offset: 30}) + ) { + return { + ext: 'epub', + mime: 'application/epub+zip' + }; + } + + // Assumes signed `.xpi` from addons.mozilla.org + if (check(xpiZipFilename, {offset: 30})) { + return { + ext: 'xpi', + mime: 'application/x-xpinstall' + }; + } + + if (checkString('mimetypeapplication/vnd.oasis.opendocument.text', {offset: 30})) { + return { + ext: 'odt', + mime: 'application/vnd.oasis.opendocument.text' + }; + } + + if (checkString('mimetypeapplication/vnd.oasis.opendocument.spreadsheet', {offset: 30})) { + return { + ext: 'ods', + mime: 'application/vnd.oasis.opendocument.spreadsheet' + }; + } + + if (checkString('mimetypeapplication/vnd.oasis.opendocument.presentation', {offset: 30})) { + return { + ext: 'odp', + mime: 'application/vnd.oasis.opendocument.presentation' + }; + } + + // The docx, xlsx and pptx file types extend the Office Open XML file format: + // https://en.wikipedia.org/wiki/Office_Open_XML_file_formats + // We look for: + // - one entry named '[Content_Types].xml' or '_rels/.rels', + // - one entry indicating specific type of file. + // MS Office, OpenOffice and LibreOffice may put the parts in different order, so the check should not rely on it. + let zipHeaderIndex = 0; // The first zip header was already found at index 0 + let oxmlFound = false; + let type; + + do { + const offset = zipHeaderIndex + 30; + + if (!oxmlFound) { + oxmlFound = (check(oxmlContentTypes, {offset}) || check(oxmlRels, {offset})); + } + + if (!type) { + if (checkString('word/', {offset})) { + type = { + ext: 'docx', + mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + }; + } else if (checkString('ppt/', {offset})) { + type = { + ext: 'pptx', + mime: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' + }; + } else if (checkString('xl/', {offset})) { + type = { + ext: 'xlsx', + mime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + }; + } + } + + if (oxmlFound && type) { + return type; + } + + zipHeaderIndex = multiByteIndexOf(buffer, zipHeader, offset); + } while (zipHeaderIndex >= 0); + + // No more zip parts available in the buffer, but maybe we are almost certain about the type? + if (type) { + return type; + } + } + + if ( + check([0x50, 0x4B]) && + (buffer[2] === 0x3 || buffer[2] === 0x5 || buffer[2] === 0x7) && + (buffer[3] === 0x4 || buffer[3] === 0x6 || buffer[3] === 0x8) + ) { + return { + ext: 'zip', + mime: 'application/zip' + }; + } + + if ( + check([0x30, 0x30, 0x30, 0x30, 0x30, 0x30], {offset: 148, mask: [0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8]}) && // Valid tar checksum + tarHeaderChecksumMatches(buffer) + ) { + return { + ext: 'tar', + mime: 'application/x-tar' + }; + } + + if ( + check([0x52, 0x61, 0x72, 0x21, 0x1A, 0x7]) && + (buffer[6] === 0x0 || buffer[6] === 0x1) + ) { + return { + ext: 'rar', + mime: 'application/x-rar-compressed' + }; + } + + if (check([0x1F, 0x8B, 0x8])) { + return { + ext: 'gz', + mime: 'application/gzip' + }; + } + + if (check([0x42, 0x5A, 0x68])) { + return { + ext: 'bz2', + mime: 'application/x-bzip2' + }; + } + + if (check([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])) { + return { + ext: '7z', + mime: 'application/x-7z-compressed' + }; + } + + if (check([0x78, 0x01])) { + return { + ext: 'dmg', + mime: 'application/x-apple-diskimage' + }; + } + + // `mov` format variants + if ( + check([0x66, 0x72, 0x65, 0x65], {offset: 4}) || // `free` + check([0x6D, 0x64, 0x61, 0x74], {offset: 4}) || // `mdat` MJPEG + check([0x6D, 0x6F, 0x6F, 0x76], {offset: 4}) || // `moov` + check([0x77, 0x69, 0x64, 0x65], {offset: 4}) // `wide` + ) { + return { + ext: 'mov', + mime: 'video/quicktime' + }; + } + + // File Type Box (https://en.wikipedia.org/wiki/ISO_base_media_file_format) + // It's not required to be first, but it's recommended to be. Almost all ISO base media files start with `ftyp` box. + // `ftyp` box must contain a brand major identifier, which must consist of ISO 8859-1 printable characters. + // Here we check for 8859-1 printable characters (for simplicity, it's a mask which also catches one non-printable character). + if ( + checkString('ftyp', {offset: 4}) && + (buffer[8] & 0x60) !== 0x00 // Brand major, first character ASCII? + ) { + // They all can have MIME `video/mp4` except `application/mp4` special-case which is hard to detect. + // For some cases, we're specific, everything else falls to `video/mp4` with `mp4` extension. + const brandMajor = uint8ArrayUtf8ByteString(buffer, 8, 12).replace('\0', ' ').trim(); + switch (brandMajor) { + case 'mif1': + return {ext: 'heic', mime: 'image/heif'}; + case 'msf1': + return {ext: 'heic', mime: 'image/heif-sequence'}; + case 'heic': case 'heix': + return {ext: 'heic', mime: 'image/heic'}; + case 'hevc': case 'hevx': + return {ext: 'heic', mime: 'image/heic-sequence'}; + case 'qt': + return {ext: 'mov', mime: 'video/quicktime'}; + case 'M4V': case 'M4VH': case 'M4VP': + return {ext: 'm4v', mime: 'video/x-m4v'}; + case 'M4P': + return {ext: 'm4p', mime: 'video/mp4'}; + case 'M4B': + return {ext: 'm4b', mime: 'audio/mp4'}; + case 'M4A': + return {ext: 'm4a', mime: 'audio/x-m4a'}; + case 'F4V': + return {ext: 'f4v', mime: 'video/mp4'}; + case 'F4P': + return {ext: 'f4p', mime: 'video/mp4'}; + case 'F4A': + return {ext: 'f4a', mime: 'audio/mp4'}; + case 'F4B': + return {ext: 'f4b', mime: 'audio/mp4'}; + default: + if (brandMajor.startsWith('3g')) { + if (brandMajor.startsWith('3g2')) { + return {ext: '3g2', mime: 'video/3gpp2'}; + } + + return {ext: '3gp', mime: 'video/3gpp'}; + } + + return {ext: 'mp4', mime: 'video/mp4'}; + } + } + + if (check([0x4D, 0x54, 0x68, 0x64])) { + return { + ext: 'mid', + mime: 'audio/midi' + }; + } + + // https://github.com/threatstack/libmagic/blob/master/magic/Magdir/matroska + if (check([0x1A, 0x45, 0xDF, 0xA3])) { + const sliced = buffer.subarray(4, 4 + 4096); + const idPos = sliced.findIndex((el, i, arr) => arr[i] === 0x42 && arr[i + 1] === 0x82); + + if (idPos !== -1) { + const docTypePos = idPos + 3; + const findDocType = type => [...type].every((c, i) => sliced[docTypePos + i] === c.charCodeAt(0)); + + if (findDocType('matroska')) { + return { + ext: 'mkv', + mime: 'video/x-matroska' + }; + } + + if (findDocType('webm')) { + return { + ext: 'webm', + mime: 'video/webm' + }; + } + } + } + + // RIFF file format which might be AVI, WAV, QCP, etc + if (check([0x52, 0x49, 0x46, 0x46])) { + if (check([0x41, 0x56, 0x49], {offset: 8})) { + return { + ext: 'avi', + mime: 'video/vnd.avi' + }; + } + + if (check([0x57, 0x41, 0x56, 0x45], {offset: 8})) { + return { + ext: 'wav', + mime: 'audio/vnd.wave' + }; + } + + // QLCM, QCP file + if (check([0x51, 0x4C, 0x43, 0x4D], {offset: 8})) { + return { + ext: 'qcp', + mime: 'audio/qcelp' + }; + } + } + + // ASF_Header_Object first 80 bytes + if (check([0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9])) { + // Search for header should be in first 1KB of file. + + let offset = 30; + do { + const objectSize = readUInt64LE(buffer, offset + 16); + if (check([0x91, 0x07, 0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65], {offset})) { + // Sync on Stream-Properties-Object (B7DC0791-A9B7-11CF-8EE6-00C00C205365) + if (check([0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B], {offset: offset + 24})) { + // Found audio: + return { + ext: 'wma', + mime: 'audio/x-ms-wma' + }; + } + + if (check([0xC0, 0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B], {offset: offset + 24})) { + // Found video: + return { + ext: 'wmv', + mime: 'video/x-ms-asf' + }; + } + + break; + } + + offset += objectSize; + } while (offset + 24 <= buffer.length); + + // Default to ASF generic extension + return { + ext: 'asf', + mime: 'application/vnd.ms-asf' + }; + } + + if ( + check([0x0, 0x0, 0x1, 0xBA]) || + check([0x0, 0x0, 0x1, 0xB3]) + ) { + return { + ext: 'mpg', + mime: 'video/mpeg' + }; + } + + // Check for MPEG header at different starting offsets + for (let start = 0; start < 2 && start < (buffer.length - 16); start++) { + if ( + check([0x49, 0x44, 0x33], {offset: start}) || // ID3 header + check([0xFF, 0xE2], {offset: start, mask: [0xFF, 0xE6]}) // MPEG 1 or 2 Layer 3 header + ) { + return { + ext: 'mp3', + mime: 'audio/mpeg' + }; + } + + if ( + check([0xFF, 0xE4], {offset: start, mask: [0xFF, 0xE6]}) // MPEG 1 or 2 Layer 2 header + ) { + return { + ext: 'mp2', + mime: 'audio/mpeg' + }; + } + + if ( + check([0xFF, 0xF8], {offset: start, mask: [0xFF, 0xFC]}) // MPEG 2 layer 0 using ADTS + ) { + return { + ext: 'mp2', + mime: 'audio/mpeg' + }; + } + + if ( + check([0xFF, 0xF0], {offset: start, mask: [0xFF, 0xFC]}) // MPEG 4 layer 0 using ADTS + ) { + return { + ext: 'mp4', + mime: 'audio/mpeg' + }; + } + } + + // Needs to be before `ogg` check + if (check([0x4F, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64], {offset: 28})) { + return { + ext: 'opus', + mime: 'audio/opus' + }; + } + + // If 'OggS' in first bytes, then OGG container + if (check([0x4F, 0x67, 0x67, 0x53])) { + // This is a OGG container + + // If ' theora' in header. + if (check([0x80, 0x74, 0x68, 0x65, 0x6F, 0x72, 0x61], {offset: 28})) { + return { + ext: 'ogv', + mime: 'video/ogg' + }; + } + + // If '\x01video' in header. + if (check([0x01, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x00], {offset: 28})) { + return { + ext: 'ogm', + mime: 'video/ogg' + }; + } + + // If ' FLAC' in header https://xiph.org/flac/faq.html + if (check([0x7F, 0x46, 0x4C, 0x41, 0x43], {offset: 28})) { + return { + ext: 'oga', + mime: 'audio/ogg' + }; + } + + // 'Speex ' in header https://en.wikipedia.org/wiki/Speex + if (check([0x53, 0x70, 0x65, 0x65, 0x78, 0x20, 0x20], {offset: 28})) { + return { + ext: 'spx', + mime: 'audio/ogg' + }; + } + + // If '\x01vorbis' in header + if (check([0x01, 0x76, 0x6F, 0x72, 0x62, 0x69, 0x73], {offset: 28})) { + return { + ext: 'ogg', + mime: 'audio/ogg' + }; + } + + // Default OGG container https://www.iana.org/assignments/media-types/application/ogg + return { + ext: 'ogx', + mime: 'application/ogg' + }; + } + + if (check([0x66, 0x4C, 0x61, 0x43])) { + return { + ext: 'flac', + mime: 'audio/x-flac' + }; + } + + if (check([0x4D, 0x41, 0x43, 0x20])) { // 'MAC ' + return { + ext: 'ape', + mime: 'audio/ape' + }; + } + + if (check([0x77, 0x76, 0x70, 0x6B])) { // 'wvpk' + return { + ext: 'wv', + mime: 'audio/wavpack' + }; + } + + if (check([0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A])) { + return { + ext: 'amr', + mime: 'audio/amr' + }; + } + + if (check([0x25, 0x50, 0x44, 0x46])) { + return { + ext: 'pdf', + mime: 'application/pdf' + }; + } + + if (check([0x4D, 0x5A])) { + return { + ext: 'exe', + mime: 'application/x-msdownload' + }; + } + + if ( + (buffer[0] === 0x43 || buffer[0] === 0x46) && + check([0x57, 0x53], {offset: 1}) + ) { + return { + ext: 'swf', + mime: 'application/x-shockwave-flash' + }; + } + + if (check([0x7B, 0x5C, 0x72, 0x74, 0x66])) { + return { + ext: 'rtf', + mime: 'application/rtf' + }; + } + + if (check([0x00, 0x61, 0x73, 0x6D])) { + return { + ext: 'wasm', + mime: 'application/wasm' + }; + } + + if ( + check([0x77, 0x4F, 0x46, 0x46]) && + ( + check([0x00, 0x01, 0x00, 0x00], {offset: 4}) || + check([0x4F, 0x54, 0x54, 0x4F], {offset: 4}) + ) + ) { + return { + ext: 'woff', + mime: 'font/woff' + }; + } + + if ( + check([0x77, 0x4F, 0x46, 0x32]) && + ( + check([0x00, 0x01, 0x00, 0x00], {offset: 4}) || + check([0x4F, 0x54, 0x54, 0x4F], {offset: 4}) + ) + ) { + return { + ext: 'woff2', + mime: 'font/woff2' + }; + } + + if ( + check([0x4C, 0x50], {offset: 34}) && + ( + check([0x00, 0x00, 0x01], {offset: 8}) || + check([0x01, 0x00, 0x02], {offset: 8}) || + check([0x02, 0x00, 0x02], {offset: 8}) + ) + ) { + return { + ext: 'eot', + mime: 'application/vnd.ms-fontobject' + }; + } + + if (check([0x00, 0x01, 0x00, 0x00, 0x00])) { + return { + ext: 'ttf', + mime: 'font/ttf' + }; + } + + if (check([0x4F, 0x54, 0x54, 0x4F, 0x00])) { + return { + ext: 'otf', + mime: 'font/otf' + }; + } + + if (check([0x00, 0x00, 0x01, 0x00])) { + return { + ext: 'ico', + mime: 'image/x-icon' + }; + } + + if (check([0x00, 0x00, 0x02, 0x00])) { + return { + ext: 'cur', + mime: 'image/x-icon' + }; + } + + if (check([0x46, 0x4C, 0x56, 0x01])) { + return { + ext: 'flv', + mime: 'video/x-flv' + }; + } + + if (check([0x25, 0x21])) { + return { + ext: 'ps', + mime: 'application/postscript' + }; + } + + if (check([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])) { + return { + ext: 'xz', + mime: 'application/x-xz' + }; + } + + if (check([0x53, 0x51, 0x4C, 0x69])) { + return { + ext: 'sqlite', + mime: 'application/x-sqlite3' + }; + } + + if (check([0x4E, 0x45, 0x53, 0x1A])) { + return { + ext: 'nes', + mime: 'application/x-nintendo-nes-rom' + }; + } + + if (check([0x43, 0x72, 0x32, 0x34])) { + return { + ext: 'crx', + mime: 'application/x-google-chrome-extension' + }; + } + + if ( + check([0x4D, 0x53, 0x43, 0x46]) || + check([0x49, 0x53, 0x63, 0x28]) + ) { + return { + ext: 'cab', + mime: 'application/vnd.ms-cab-compressed' + }; + } + + // Needs to be before `ar` check + if (check([0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E, 0x0A, 0x64, 0x65, 0x62, 0x69, 0x61, 0x6E, 0x2D, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79])) { + return { + ext: 'deb', + mime: 'application/x-deb' + }; + } + + if (check([0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E])) { + return { + ext: 'ar', + mime: 'application/x-unix-archive' + }; + } + + if (check([0xED, 0xAB, 0xEE, 0xDB])) { + return { + ext: 'rpm', + mime: 'application/x-rpm' + }; + } + + if ( + check([0x1F, 0xA0]) || + check([0x1F, 0x9D]) + ) { + return { + ext: 'Z', + mime: 'application/x-compress' + }; + } + + if (check([0x4C, 0x5A, 0x49, 0x50])) { + return { + ext: 'lz', + mime: 'application/x-lzip' + }; + } + + if (check([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E])) { + return { + ext: 'msi', + mime: 'application/x-msi' + }; + } + + if (check([0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02])) { + return { + ext: 'mxf', + mime: 'application/mxf' + }; + } + + if (check([0x47], {offset: 4}) && (check([0x47], {offset: 192}) || check([0x47], {offset: 196}))) { + return { + ext: 'mts', + mime: 'video/mp2t' + }; + } + + if (check([0x42, 0x4C, 0x45, 0x4E, 0x44, 0x45, 0x52])) { + return { + ext: 'blend', + mime: 'application/x-blender' + }; + } + + if (check([0x42, 0x50, 0x47, 0xFB])) { + return { + ext: 'bpg', + mime: 'image/bpg' + }; + } + + if (check([0x00, 0x00, 0x00, 0x0C, 0x6A, 0x50, 0x20, 0x20, 0x0D, 0x0A, 0x87, 0x0A])) { + // JPEG-2000 family + + if (check([0x6A, 0x70, 0x32, 0x20], {offset: 20})) { + return { + ext: 'jp2', + mime: 'image/jp2' + }; + } + + if (check([0x6A, 0x70, 0x78, 0x20], {offset: 20})) { + return { + ext: 'jpx', + mime: 'image/jpx' + }; + } + + if (check([0x6A, 0x70, 0x6D, 0x20], {offset: 20})) { + return { + ext: 'jpm', + mime: 'image/jpm' + }; + } + + if (check([0x6D, 0x6A, 0x70, 0x32], {offset: 20})) { + return { + ext: 'mj2', + mime: 'image/mj2' + }; + } + } + + if (check([0x46, 0x4F, 0x52, 0x4D])) { + return { + ext: 'aif', + mime: 'audio/aiff' + }; + } + + if (checkString(' new Promise((resolve, reject) => { + // Using `eval` to work around issues when bundling with Webpack + const stream = eval('require')('stream'); // eslint-disable-line no-eval + + readableStream.on('error', reject); + readableStream.once('readable', () => { + const pass = new stream.PassThrough(); + const chunk = readableStream.read(module.exports.minimumBytes) || readableStream.read(); + try { + pass.fileType = fileType(chunk); + } catch (error) { + reject(error); + } + + readableStream.unshift(chunk); + + if (stream.pipeline) { + resolve(stream.pipeline(readableStream, pass, () => {})); + } else { + resolve(readableStream.pipe(pass)); + } + }); +}); + +Object.defineProperty(fileType, 'extensions', { + get() { + return new Set(supported.extensions); + } +}); + +Object.defineProperty(fileType, 'mimeTypes', { + get() { + return new Set(supported.mimeTypes); + } +}); + +}).call(this,{"isBuffer":require("../is-buffer/index.js")}) +},{"../is-buffer/index.js":362,"./supported":108,"./util":109}],108:[function(require,module,exports){ +'use strict'; + +module.exports = { + extensions: [ + 'jpg', + 'png', + 'apng', + 'gif', + 'webp', + 'flif', + 'cr2', + 'orf', + 'arw', + 'dng', + 'nef', + 'rw2', + 'raf', + 'tif', + 'bmp', + 'jxr', + 'psd', + 'zip', + 'tar', + 'rar', + 'gz', + 'bz2', + '7z', + 'dmg', + 'mp4', + 'mid', + 'mkv', + 'webm', + 'mov', + 'avi', + 'mpg', + 'mp2', + 'mp3', + 'm4a', + 'oga', + 'ogg', + 'ogv', + 'opus', + 'flac', + 'wav', + 'spx', + 'amr', + 'pdf', + 'epub', + 'exe', + 'swf', + 'rtf', + 'wasm', + 'woff', + 'woff2', + 'eot', + 'ttf', + 'otf', + 'ico', + 'flv', + 'ps', + 'xz', + 'sqlite', + 'nes', + 'crx', + 'xpi', + 'cab', + 'deb', + 'ar', + 'rpm', + 'Z', + 'lz', + 'msi', + 'mxf', + 'mts', + 'blend', + 'bpg', + 'docx', + 'pptx', + 'xlsx', + '3gp', + '3g2', + 'jp2', + 'jpm', + 'jpx', + 'mj2', + 'aif', + 'qcp', + 'odt', + 'ods', + 'odp', + 'xml', + 'mobi', + 'heic', + 'cur', + 'ktx', + 'ape', + 'wv', + 'wmv', + 'wma', + 'dcm', + 'ics', + 'glb', + 'pcap', + 'dsf', + 'lnk', + 'alias', + 'voc', + 'ac3', + 'm4v', + 'm4p', + 'm4b', + 'f4v', + 'f4p', + 'f4b', + 'f4a', + 'mie', + 'asf', + 'ogm', + 'ogx', + 'mpc', + 'arrow', + 'shp' + ], + mimeTypes: [ + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/webp', + 'image/flif', + 'image/x-canon-cr2', + 'image/tiff', + 'image/bmp', + 'image/vnd.ms-photo', + 'image/vnd.adobe.photoshop', + 'application/epub+zip', + 'application/x-xpinstall', + 'application/vnd.oasis.opendocument.text', + 'application/vnd.oasis.opendocument.spreadsheet', + 'application/vnd.oasis.opendocument.presentation', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/zip', + 'application/x-tar', + 'application/x-rar-compressed', + 'application/gzip', + 'application/x-bzip2', + 'application/x-7z-compressed', + 'application/x-apple-diskimage', + 'application/x-apache-arrow', + 'video/mp4', + 'audio/midi', + 'video/x-matroska', + 'video/webm', + 'video/quicktime', + 'video/vnd.avi', + 'audio/vnd.wave', + 'audio/qcelp', + 'audio/x-ms-wma', + 'video/x-ms-asf', + 'application/vnd.ms-asf', + 'video/mpeg', + 'video/3gpp', + 'audio/mpeg', + 'audio/mp4', // RFC 4337 + 'audio/opus', + 'video/ogg', + 'audio/ogg', + 'application/ogg', + 'audio/x-flac', + 'audio/ape', + 'audio/wavpack', + 'audio/amr', + 'application/pdf', + 'application/x-msdownload', + 'application/x-shockwave-flash', + 'application/rtf', + 'application/wasm', + 'font/woff', + 'font/woff2', + 'application/vnd.ms-fontobject', + 'font/ttf', + 'font/otf', + 'image/x-icon', + 'video/x-flv', + 'application/postscript', + 'application/x-xz', + 'application/x-sqlite3', + 'application/x-nintendo-nes-rom', + 'application/x-google-chrome-extension', + 'application/vnd.ms-cab-compressed', + 'application/x-deb', + 'application/x-unix-archive', + 'application/x-rpm', + 'application/x-compress', + 'application/x-lzip', + 'application/x-msi', + 'application/x-mie', + 'application/mxf', + 'video/mp2t', + 'application/x-blender', + 'image/bpg', + 'image/jp2', + 'image/jpx', + 'image/jpm', + 'image/mj2', + 'audio/aiff', + 'application/xml', + 'application/x-mobipocket-ebook', + 'image/heif', + 'image/heif-sequence', + 'image/heic', + 'image/heic-sequence', + 'image/ktx', + 'application/dicom', + 'audio/x-musepack', + 'text/calendar', + 'model/gltf-binary', + 'application/vnd.tcpdump.pcap', + 'audio/x-dsf', // Non-standard + 'application/x.ms.shortcut', // Invented by us + 'application/x.apple.alias', // Invented by us + 'audio/x-voc', + 'audio/vnd.dolby.dd-raw', + 'audio/x-m4a', + 'image/apng', + 'image/x-olympus-orf', + 'image/x-sony-arw', + 'image/x-adobe-dng', + 'image/x-nikon-nef', + 'image/x-panasonic-rw2', + 'image/x-fujifilm-raf', + 'video/x-m4v', + 'video/3gpp2', + 'application/x-esri-shape' + ] +}; + +},{}],109:[function(require,module,exports){ +(function (Buffer){ +'use strict'; + +exports.stringToBytes = string => [...string].map(character => character.charCodeAt(0)); + +const uint8ArrayUtf8ByteString = (array, start, end) => { + return String.fromCharCode(...array.slice(start, end)); +}; + +exports.readUInt64LE = (buffer, offset = 0) => { + let n = buffer[offset]; + let mul = 1; + let i = 0; + + while (++i < 8) { + mul *= 0x100; + n += buffer[offset + i] * mul; + } + + return n; +}; + +exports.tarHeaderChecksumMatches = buffer => { // Does not check if checksum field characters are valid + if (buffer.length < 512) { // `tar` header size, cannot compute checksum without it + return false; + } + + const MASK_8TH_BIT = 0x80; + + let sum = 256; // Intitalize sum, with 256 as sum of 8 spaces in checksum field + let signedBitSum = 0; // Initialize signed bit sum + + for (let i = 0; i < 148; i++) { + const byte = buffer[i]; + sum += byte; + signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum + } + + // Skip checksum field + + for (let i = 156; i < 512; i++) { + const byte = buffer[i]; + sum += byte; + signedBitSum += byte & MASK_8TH_BIT; // Add signed bit to signed bit sum + } + + const readSum = parseInt(uint8ArrayUtf8ByteString(buffer, 148, 154), 8); // Read sum in header + + // Some implementations compute checksum incorrectly using signed bytes + return ( + // Checksum in header equals the sum we calculated + readSum === sum || + + // Checksum in header equals sum we calculated plus signed-to-unsigned delta + readSum === (sum - (signedBitSum << 1)) + ); +}; + +exports.multiByteIndexOf = (buffer, bytesToSearch, startAt = 0) => { + // `Buffer#indexOf()` can search for multiple bytes + if (Buffer && Buffer.isBuffer(buffer)) { + return buffer.indexOf(Buffer.from(bytesToSearch), startAt); + } + + const nextBytesMatch = (buffer, bytes, startIndex) => { + for (let i = 1; i < bytes.length; i++) { + if (bytes[i] !== buffer[startIndex + i]) { + return false; + } + } + + return true; + }; + + // `Uint8Array#indexOf()` can search for only a single byte + let index = buffer.indexOf(bytesToSearch[0], startAt); + while (index >= 0) { + if (nextBytesMatch(buffer, bytesToSearch, index)) { + return index; + } + + index = buffer.indexOf(bytesToSearch[0], index + 1); + } + + return -1; +}; + +exports.uint8ArrayUtf8ByteString = uint8ArrayUtf8ByteString; + +}).call(this,require("buffer").Buffer) +},{"buffer":297}],110:[function(require,module,exports){ + +/** + * Module dependencies. + */ + +var sep = require('path').sep || '/'; + +/** + * Module exports. + */ + +module.exports = fileUriToPath; + +/** + * File URI to Path function. + * + * @param {String} uri + * @return {String} path + * @api public + */ + +function fileUriToPath (uri) { + if ('string' != typeof uri || + uri.length <= 7 || + 'file://' != uri.substring(0, 7)) { + throw new TypeError('must pass in a file:// URI to convert to a file path'); + } + + var rest = decodeURI(uri.substring(7)); + var firstSlash = rest.indexOf('/'); + var host = rest.substring(0, firstSlash); + var path = rest.substring(firstSlash + 1); + + // 2. Scheme Definition + // As a special case, can be the string "localhost" or the empty + // string; this is interpreted as "the machine from which the URL is + // being interpreted". + if ('localhost' == host) host = ''; + + if (host) { + host = sep + sep + host; + } + + // 3.2 Drives, drive letters, mount points, file system root + // Drive letters are mapped into the top of a file URI in various ways, + // depending on the implementation; some applications substitute + // vertical bar ("|") for the colon after the drive letter, yielding + // "file:///c|/tmp/test.txt". In some cases, the colon is left + // unchanged, as in "file:///c:/tmp/test.txt". In other cases, the + // colon is simply omitted, as in "file:///c/tmp/test.txt". + path = path.replace(/^(.+)\|/, '$1:'); + + // for Windows, we need to invert the path separators from what a URI uses + if (sep == '\\') { + path = path.replace(/\//g, '\\'); + } + + if (/^.+\:/.test(path)) { + // has Windows drive at beginning of path + } else { + // unix path… + path = sep + path; + } + + return host + path; +} + +},{"path":402}],111:[function(require,module,exports){ +var FisheyeGl = function FisheyeGl(options){ + + // Defaults: + options = options || {}; + + options.width = options.width || 800; + options.height = options.height || 600; + + var model = options.model || { + vertex :[ + -1.0, -1.0, 0.0, + 1.0, -1.0, 0.0, + 1.0, 1.0, 0.0, + -1.0, 1.0, 0.0 + ], + indices :[ + 0, 1, 2, + 0, 2, 3, + 2, 1, 0, + 3, 2, 0 + ], + textureCoords : [ + 0.0, 0.0, + 1.0, 0.0, + 1.0, 1.0, + 0.0, 1.0 + ] + }; + + var lens = options.lens || { + a : 1.0, + b : 1.0, + Fx : 0.0, + Fy : 0.0, + scale : 1.5 + }; + var fov = options.fov || { + x : 1.0, + y : 1.0 + } + var image = options.image || "images/barrel-distortion.png"; + + var selector = options.selector || "#canvas"; + var gl = getGLContext(selector); + + var shaders = require('./shaders'); + + var vertexSrc = loadFile(options.vertexSrc || "vertex"); + var fragmentSrc = loadFile(options.fragmentSrc || "fragment3"); + + var program = compileShader(gl, vertexSrc, fragmentSrc) + gl.useProgram(program); + + var aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); + var aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); + var uSampler = gl.getUniformLocation(program, "uSampler"); + var uLensS = gl.getUniformLocation(program, "uLensS"); + var uLensF = gl.getUniformLocation(program, "uLensF"); + var uFov = gl.getUniformLocation(program, "uFov"); + + var vertexBuffer, + indexBuffer, + textureBuffer; + + function createBuffers() { + + vertexBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(model.vertex), gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + + indexBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(model.indices), gl.STATIC_DRAW); + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); + + textureBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(model.textureCoords), gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, null); + + } + + createBuffers(); + + function getGLContext(selector){ + var canvas = document.querySelector(selector); + + if(canvas == null){ + throw new Error("there is no canvas on this page"); + } + + var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"]; + for (var i = 0; i < names.length; ++i) { + var gl; + try { + gl = canvas.getContext(names[i], { preserveDrawingBuffer: true }); + } catch(e) { + continue; + } + if (gl) return gl; + } + + throw new Error("WebGL is not supported!"); + } + + function compileShader(gl, vertexSrc, fragmentSrc){ + var vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vertexSrc); + gl.compileShader(vertexShader); + + _checkCompile(vertexShader); + + var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentSrc); + gl.compileShader(fragmentShader); + + _checkCompile(fragmentShader); + + var program = gl.createProgram(); + + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + + gl.linkProgram(program); + + return program; + + function _checkCompile(shader){ + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + throw new Error(gl.getShaderInfoLog(shader)); + } + } + } + + function loadFile(url, callback){ + + if(shaders.hasOwnProperty(url)) { + return shaders[url]; + } + + var ajax = new XMLHttpRequest(); + + if(callback) { + ajax.addEventListener("readystatechange", on) + ajax.open("GET", url, true); + ajax.send(null); + } else { + ajax.open("GET", url, false); + ajax.send(null); + + if(ajax.status == 200){ + return ajax.responseText; + } + } + + function on(){ + if(ajax.readyState === 4){ + //complete requset + if(ajax.status === 200){ + //not error + callback(null, ajax.responseText); + } else { + callback(new Error("fail to load!")); + } + } + } + } + + function loadImage(gl, img, callback, texture){ + texture = texture || gl.createTexture(); + + gl.bindTexture(gl.TEXTURE_2D, texture); + + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); + + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); //gl.NEAREST is also allowed, instead of gl.LINEAR, as neither mipmap. + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); //Prevents s-coordinate wrapping (repeating). + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); //Prevents t-coordinate wrapping (repeating). + //gl.generateMipmap(gl.TEXTURE_2D); + gl.bindTexture(gl.TEXTURE_2D, null); + + if(callback) callback(null, texture); + return texture; + } + + function loadImageFromUrl(gl, url, callback){ + var texture = gl.createTexture(); + var img = new Image(); + img.addEventListener("load", function onload(){ + loadImage(gl, img, callback, texture); + options.width = img.width; + options.height = img.height; + resize( + options.width, + options.height + ) + }); + img.src = url; + return texture; + } + + function run(animate, callback){ + var f = window.requestAnimationFrame || window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; + + // ugh + if(animate === true){ + if(f){ + f(on); + } else { + throw new Error("do not support 'requestAnimationFram'"); + } + } else { + f(on); + } + + var current = null; + function on(t){ + if(!current) current = t; + var dt = t - current; + current = t; + options.runner(dt); + if (callback) callback(); + if (animate === true) f(on); + } + } + + function resize(w, h) { + gl.viewport(0, 0, w, h); + gl.canvas.width = w; + gl.canvas.height = h; + } + + options.runner = options.runner|| function runner(dt){ + + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.enable(gl.DEPTH_TEST); + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + gl.enableVertexAttribArray(aVertexPosition); + + gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); + gl.vertexAttribPointer(aVertexPosition, 3, gl.FLOAT, false, 0, 0); + + gl.enableVertexAttribArray(aTextureCoord); + + gl.bindBuffer(gl.ARRAY_BUFFER, textureBuffer); + gl.vertexAttribPointer(aTextureCoord, 2, gl.FLOAT, false, 0, 0); + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.uniform1i(uSampler, 0); + + gl.uniform3fv(uLensS, [lens.a, lens.b, lens.scale]); + gl.uniform2fv(uLensF, [lens.Fx, lens.Fy]); + gl.uniform2fv(uFov, [fov.x, fov.y]); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); + gl.drawElements(gl.TRIANGLES, model.indices.length, gl.UNSIGNED_SHORT, 0); + } + + var texture; + + function setImage(imageUrl, callback) { + texture = loadImageFromUrl(gl, imageUrl, function onImageLoad() { + + run(options.animate, callback); + + }); + } + + setImage(image); + + // asynchronous! + function getImage(format) { + + var img = new Image(); + + img.src = gl.canvas.toDataURL(format || 'image/jpeg'); + + return img; + + } + + // external API: + var distorter = { + options: options, + gl: gl, + lens: lens, + fov: fov, + run: run, + getImage: getImage, + setImage: setImage + } + + return distorter; + +} + +if (typeof(document) != 'undefined') + window.FisheyeGl = FisheyeGl; +else + module.exports = FisheyeGl; + +},{"./shaders":112}],112:[function(require,module,exports){ +module.exports = { + fragment: require('./shaders/fragment.glfs'), + fragment2: require('./shaders/fragment2.glfs'), + fragment3: require('./shaders/fragment3.glfs'), + method1: require('./shaders/method1.glfs'), + method2: require('./shaders/method2.glfs'), + vertex: require('./shaders/vertex.glvs') +}; + +},{"./shaders/fragment.glfs":113,"./shaders/fragment2.glfs":114,"./shaders/fragment3.glfs":115,"./shaders/method1.glfs":116,"./shaders/method2.glfs":117,"./shaders/vertex.glvs":118}],113:[function(require,module,exports){ +module.exports = "\ +#ifdef GL_ES\n\ +precision highp float;\n\ +#endif\n\ +uniform vec4 uLens;\n\ +uniform vec2 uFov;\n\ +uniform sampler2D uSampler;\n\ +varying vec3 vPosition;\n\ +varying vec2 vTextureCoord;\n\ +vec2 GLCoord2TextureCoord(vec2 glCoord) {\n\ + return glCoord * vec2(1.0, -1.0)/ 2.0 + vec2(0.5, 0.5);\n\ +}\n\ +void main(void){\n\ + float scale = uLens.w;\n\ + float F = uLens.z;\n\ + \n\ + float L = length(vec3(vPosition.xy/scale, F));\n\ + vec2 vMapping = vPosition.xy * F / L;\n\ + vMapping = vMapping * uLens.xy;\n\ + vMapping = GLCoord2TextureCoord(vMapping/scale);\n\ + vec4 texture = texture2D(uSampler, vMapping);\n\ + if(vMapping.x > 0.99 || vMapping.x < 0.01 || vMapping.y > 0.99 || vMapping.y < 0.01){\n\ + texture = vec4(0.0, 0.0, 0.0, 1.0);\n\ + } \n\ + gl_FragColor = texture;\n\ +}\n\ +"; +},{}],114:[function(require,module,exports){ +module.exports = "\ +#ifdef GL_ES\n\ +precision highp float;\n\ +#endif\n\ +uniform vec4 uLens;\n\ +uniform vec2 uFov;\n\ +uniform sampler2D uSampler;\n\ +varying vec3 vPosition;\n\ +varying vec2 vTextureCoord;\n\ +vec2 TextureCoord2GLCoord(vec2 textureCoord) {\n\ + return (textureCoord - vec2(0.5, 0.5)) * 2.0;\n\ +}\n\ +vec2 GLCoord2TextureCoord(vec2 glCoord) {\n\ + return glCoord / 2.0 + vec2(0.5, 0.5);\n\ +}\n\ +void main(void){\n\ + float correctionRadius = 0.5;\n\ + float distance = sqrt(vPosition.x * vPosition.x + vPosition.y * vPosition.y) / correctionRadius;\n\ + float theta = 1.0;\n\ + if(distance != 0.0){\n\ + theta = atan(distance);\n\ + }\n\ + vec2 vMapping = theta * vPosition.xy;\n\ + vMapping = GLCoord2TextureCoord(vMapping);\n\ + \n\ + vec4 texture = texture2D(uSampler, vMapping);\n\ + if(vMapping.x > 0.99 || vMapping.x < 0.01 || vMapping.y > 0.99 || vMapping.y < 0.01){\n\ + texture = vec4(0.0, 0.0, 0.0, 1.0);\n\ + } \n\ + gl_FragColor = texture;\n\ +}\n\ +"; +},{}],115:[function(require,module,exports){ +module.exports = "\ +#ifdef GL_ES\n\ +precision highp float;\n\ +#endif\n\ +uniform vec3 uLensS;\n\ +uniform vec2 uLensF;\n\ +uniform vec2 uFov;\n\ +uniform sampler2D uSampler;\n\ +varying vec3 vPosition;\n\ +varying vec2 vTextureCoord;\n\ +vec2 GLCoord2TextureCoord(vec2 glCoord) {\n\ + return glCoord * vec2(1.0, -1.0)/ 2.0 + vec2(0.5, 0.5);\n\ +}\n\ +void main(void){\n\ + float scale = uLensS.z;\n\ + vec3 vPos = vPosition;\n\ + float Fx = uLensF.x;\n\ + float Fy = uLensF.y;\n\ + vec2 vMapping = vPos.xy;\n\ + vMapping.x = vMapping.x + ((pow(vPos.y, 2.0)/scale)*vPos.x/scale)*-Fx;\n\ + vMapping.y = vMapping.y + ((pow(vPos.x, 2.0)/scale)*vPos.y/scale)*-Fy;\n\ + vMapping = vMapping * uLensS.xy;\n\ + vMapping = GLCoord2TextureCoord(vMapping/scale);\n\ + vec4 texture = texture2D(uSampler, vMapping);\n\ + if(vMapping.x > 0.99 || vMapping.x < 0.01 || vMapping.y > 0.99 || vMapping.y < 0.01){\n\ + texture = vec4(0.0, 0.0, 0.0, 1.0);\n\ + }\n\ + gl_FragColor = texture;\n\ +}\n\ +"; +},{}],116:[function(require,module,exports){ +module.exports = "\ +#ifdef GL_ES\n\ +precision highp float;\n\ +#endif\n\ +uniform vec4 uLens;\n\ +uniform vec2 uFov;\n\ +uniform sampler2D uSampler;\n\ +varying vec3 vPosition;\n\ +varying vec2 vTextureCoord;\n\ +vec2 TextureCoord2GLCoord(vec2 textureCoord) {\n\ + return (textureCoord - vec2(0.5, 0.5)) * 2.0;\n\ +}\n\ +vec2 GLCoord2TextureCoord(vec2 glCoord) {\n\ + return glCoord / 2.0 + vec2(0.5, 0.5);\n\ +}\n\ +void main(void){\n\ + vec2 vMapping = vec2(vTextureCoord.x, 1.0 - vTextureCoord.y);\n\ + vMapping = TextureCoord2GLCoord(vMapping);\n\ + //TODO insert Code\n\ + float F = uLens.x/ uLens.w;\n\ + float seta = length(vMapping) / F;\n\ + vMapping = sin(seta) * F / length(vMapping) * vMapping;\n\ + vMapping *= uLens.w * 1.414;\n\ + vMapping = GLCoord2TextureCoord(vMapping);\n\ + vec4 texture = texture2D(uSampler, vMapping);\n\ + if(vMapping.x > 0.99 || vMapping.x < 0.01 || vMapping.y > 0.99 || vMapping.y < 0.01){\n\ + texture = vec4(0.0, 0.0, 0.0, 1.0);\n\ + } \n\ + gl_FragColor = texture;\n\ +}\n\ +"; +},{}],117:[function(require,module,exports){ +module.exports = "\ +#ifdef GL_ES\n\ +precision highp float;\n\ +#endif\n\ +uniform vec4 uLens;\n\ +uniform vec2 uFov;\n\ +uniform sampler2D uSampler;\n\ +varying vec3 vPosition;\n\ +varying vec2 vTextureCoord;\n\ +vec2 TextureCoord2GLCoord(vec2 textureCoord) {\n\ + return (textureCoord - vec2(0.5, 0.5)) * 2.0;\n\ +}\n\ +vec2 GLCoord2TextureCoord(vec2 glCoord) {\n\ + return glCoord / 2.0 + vec2(0.5, 0.5);\n\ +}\n\ +void main(void){\n\ + vec2 vMapping = vec2(vTextureCoord.x, 1.0 - vTextureCoord.y);\n\ + vMapping = TextureCoord2GLCoord(vMapping);\n\ + //TOD insert Code\n\ + float F = uLens.x/ uLens.w;\n\ + float seta = length(vMapping) / F;\n\ + vMapping = sin(seta) * F / length(vMapping) * vMapping;\n\ + vMapping *= uLens.w * 1.414;\n\ + vMapping = GLCoord2TextureCoord(vMapping);\n\ + vec4 texture = texture2D(uSampler, vMapping);\n\ + if(vMapping.x > 0.99 || vMapping.x < 0.01 || vMapping.y > 0.99 || vMapping.y < 0.01){\n\ + texture = vec4(0.0, 0.0, 0.0, 1.0);\n\ + } \n\ + gl_FragColor = texture;\n\ +}\n\ +"; +},{}],118:[function(require,module,exports){ +module.exports = "\ +#ifdef GL_ES\n\ +precision highp float;\n\ +#endif\n\ +attribute vec3 aVertexPosition;\n\ +attribute vec2 aTextureCoord;\n\ +varying vec3 vPosition;\n\ +varying vec2 vTextureCoord;\n\ +void main(void){\n\ + vPosition = aVertexPosition;\n\ + vTextureCoord = aTextureCoord;\n\ + gl_Position = vec4(vPosition,1.0);\n\ +}\n\ +"; +},{}],119:[function(require,module,exports){ +(function (process){ +module.exports = realpath +realpath.realpath = realpath +realpath.sync = realpathSync +realpath.realpathSync = realpathSync +realpath.monkeypatch = monkeypatch +realpath.unmonkeypatch = unmonkeypatch + +var fs = require('fs') +var origRealpath = fs.realpath +var origRealpathSync = fs.realpathSync + +var version = process.version +var ok = /^v[0-5]\./.test(version) +var old = require('./old.js') + +function newError (er) { + return er && er.syscall === 'realpath' && ( + er.code === 'ELOOP' || + er.code === 'ENOMEM' || + er.code === 'ENAMETOOLONG' + ) +} + +function realpath (p, cache, cb) { + if (ok) { + return origRealpath(p, cache, cb) + } + + if (typeof cache === 'function') { + cb = cache + cache = null + } + origRealpath(p, cache, function (er, result) { + if (newError(er)) { + old.realpath(p, cache, cb) + } else { + cb(er, result) + } + }) +} + +function realpathSync (p, cache) { + if (ok) { + return origRealpathSync(p, cache) + } + + try { + return origRealpathSync(p, cache) + } catch (er) { + if (newError(er)) { + return old.realpathSync(p, cache) + } else { + throw er + } + } +} + +function monkeypatch () { + fs.realpath = realpath + fs.realpathSync = realpathSync +} + +function unmonkeypatch () { + fs.realpath = origRealpath + fs.realpathSync = origRealpathSync +} + +}).call(this,require('_process')) +},{"./old.js":120,"_process":432,"fs":296}],120:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var pathModule = require('path'); +var isWindows = process.platform === 'win32'; +var fs = require('fs'); + +// JavaScript implementation of realpath, ported from node pre-v6 + +var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); + +function rethrow() { + // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and + // is fairly slow to generate. + var callback; + if (DEBUG) { + var backtrace = new Error; + callback = debugCallback; + } else + callback = missingCallback; + + return callback; + + function debugCallback(err) { + if (err) { + backtrace.message = err.message; + err = backtrace; + missingCallback(err); + } + } + + function missingCallback(err) { + if (err) { + if (process.throwDeprecation) + throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs + else if (!process.noDeprecation) { + var msg = 'fs: missing callback ' + (err.stack || err.message); + if (process.traceDeprecation) + console.trace(msg); + else + console.error(msg); + } + } + } +} + +function maybeCallback(cb) { + return typeof cb === 'function' ? cb : rethrow(); +} + +var normalize = pathModule.normalize; + +// Regexp that finds the next partion of a (partial) path +// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] +if (isWindows) { + var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; +} else { + var nextPartRe = /(.*?)(?:[\/]+|$)/g; +} + +// Regex to find the device root, including trailing slash. E.g. 'c:\\'. +if (isWindows) { + var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; +} else { + var splitRootRe = /^[\/]*/; +} + +exports.realpathSync = function realpathSync(p, cache) { + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return cache[p]; + } + + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstatSync(base); + knownHard[base] = true; + } + } + + // walk down the path, swapping out linked pathparts for their real + // values + // NB: p.length changes. + while (pos < p.length) { + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + continue; + } + + var resolvedLink; + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // some known symbolic link. no need to stat again. + resolvedLink = cache[base]; + } else { + var stat = fs.lstatSync(base); + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + continue; + } + + // read the link if it wasn't read before + // dev/ino always return 0 on windows, so skip the check. + var linkTarget = null; + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + linkTarget = seenLinks[id]; + } + } + if (linkTarget === null) { + fs.statSync(base); + linkTarget = fs.readlinkSync(base); + } + resolvedLink = pathModule.resolve(previous, linkTarget); + // track this, if given a cache. + if (cache) cache[base] = resolvedLink; + if (!isWindows) seenLinks[id] = linkTarget; + } + + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } + + if (cache) cache[original] = p; + + return p; +}; + + +exports.realpath = function realpath(p, cache, cb) { + if (typeof cb !== 'function') { + cb = maybeCallback(cache); + cache = null; + } + + // make p is absolute + p = pathModule.resolve(p); + + if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { + return process.nextTick(cb.bind(null, null, cache[p])); + } + + var original = p, + seenLinks = {}, + knownHard = {}; + + // current character position in p + var pos; + // the partial path so far, including a trailing slash if any + var current; + // the partial path without a trailing slash (except when pointing at a root) + var base; + // the partial path scanned in the previous round, with slash + var previous; + + start(); + + function start() { + // Skip over roots + var m = splitRootRe.exec(p); + pos = m[0].length; + current = m[0]; + base = m[0]; + previous = ''; + + // On windows, check that the root exists. On unix there is no need. + if (isWindows && !knownHard[base]) { + fs.lstat(base, function(err) { + if (err) return cb(err); + knownHard[base] = true; + LOOP(); + }); + } else { + process.nextTick(LOOP); + } + } + + // walk down the path, swapping out linked pathparts for their real + // values + function LOOP() { + // stop if scanned past end of path + if (pos >= p.length) { + if (cache) cache[original] = p; + return cb(null, p); + } + + // find the next part + nextPartRe.lastIndex = pos; + var result = nextPartRe.exec(p); + previous = current; + current += result[0]; + base = previous + result[1]; + pos = nextPartRe.lastIndex; + + // continue if not a symlink + if (knownHard[base] || (cache && cache[base] === base)) { + return process.nextTick(LOOP); + } + + if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { + // known symbolic link. no need to stat again. + return gotResolvedLink(cache[base]); + } + + return fs.lstat(base, gotStat); + } + + function gotStat(err, stat) { + if (err) return cb(err); + + // if not a symlink, skip to the next path part + if (!stat.isSymbolicLink()) { + knownHard[base] = true; + if (cache) cache[base] = base; + return process.nextTick(LOOP); + } + + // stat & read the link if not read before + // call gotTarget as soon as the link target is known + // dev/ino always return 0 on windows, so skip the check. + if (!isWindows) { + var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); + if (seenLinks.hasOwnProperty(id)) { + return gotTarget(null, seenLinks[id], base); + } + } + fs.stat(base, function(err) { + if (err) return cb(err); + + fs.readlink(base, function(err, target) { + if (!isWindows) seenLinks[id] = target; + gotTarget(err, target); + }); + }); + } + + function gotTarget(err, target, base) { + if (err) return cb(err); + + var resolvedLink = pathModule.resolve(previous, target); + if (cache) cache[base] = resolvedLink; + gotResolvedLink(resolvedLink); + } + + function gotResolvedLink(resolvedLink) { + // resolve the link, then start over + p = pathModule.resolve(resolvedLink, p.slice(pos)); + start(); + } +}; + +}).call(this,require('_process')) +},{"_process":432,"fs":296,"path":402}],121:[function(require,module,exports){ +(function (Buffer,process){ +'use strict' + +var path = require('path') +var ndarray = require('ndarray') +var GifReader = require('omggif').GifReader +var pack = require('ndarray-pack') +var through = require('through') +var parseDataURI = require('data-uri-to-buffer') + +function defaultImage(url, cb) { + var img = new Image() + img.crossOrigin = "Anonymous" + img.onload = function() { + var canvas = document.createElement('canvas') + canvas.width = img.width + canvas.height = img.height + var context = canvas.getContext('2d') + context.drawImage(img, 0, 0) + var pixels = context.getImageData(0, 0, img.width, img.height) + cb(null, ndarray(new Uint8Array(pixels.data), [img.width, img.height, 4], [4, 4*img.width, 1], 0)) + } + img.onerror = function(err) { + cb(err) + } + img.src = url +} + +//Animated gif loading +function handleGif(data, cb) { + var reader + try { + reader = new GifReader(data) + } catch(err) { + cb(err) + return + } + if(reader.numFrames() > 0) { + var nshape = [reader.numFrames(), reader.height, reader.width, 4] + var ndata = new Uint8Array(nshape[0] * nshape[1] * nshape[2] * nshape[3]) + var result = ndarray(ndata, nshape) + try { + for(var i=0; i= 0) this.dispose = disposalCode; +}; + +/* + Sets the number of times the set of GIF frames should be played. + + -1 = play once + 0 = repeat indefinitely + + Default is -1 + + Must be invoked before the first image is added +*/ + +GIFEncoder.prototype.setRepeat = function(repeat) { + this.repeat = repeat; +}; + +/* + Sets the transparent color for the last added frame and any subsequent + frames. Since all colors are subject to modification in the quantization + process, the color in the final palette for each frame closest to the given + color becomes the transparent color for that frame. May be set to null to + indicate no transparent color. +*/ +GIFEncoder.prototype.setTransparent = function(color) { + this.transparent = color; +}; + +// Custom methods for performance hacks around streaming GIF data pieces without re-analyzing/loading +GIFEncoder.prototype.analyzeImage = function (imageData) { + // convert to correct format if necessary + this.setImagePixels(this.removeAlphaChannel(imageData)); + this.analyzePixels(); // build color table & map pixels +}; + +GIFEncoder.prototype.writeImageInfo = function () { + if (this.firstFrame) { + this.writeLSD(); // logical screen descriptior + this.writePalette(); // global color table + if (this.repeat >= 0) { + // use NS app extension to indicate reps + this.writeNetscapeExt(); + } + } + + this.writeGraphicCtrlExt(); // write graphic control extension + this.writeImageDesc(); // image descriptor + if (!this.firstFrame) this.writePalette(); // local color table + + // DEV: This was originally after outputImage but it does not affect order it seems + this.firstFrame = false; +}; + +GIFEncoder.prototype.outputImage = function () { + this.writePixels(); // encode and write pixel data +}; + +/* + Adds next GIF frame. The frame is not written immediately, but is + actually deferred until the next frame is received so that timing + data can be inserted. Invoking finish() flushes all frames. +*/ +GIFEncoder.prototype.addFrame = function(imageData) { + this.emit('frame#start'); + + this.analyzeImage(imageData); + this.writeImageInfo(); + this.outputImage(); + + this.emit('frame#stop'); +}; + +/* + Adds final trailer to the GIF stream, if you don't call the finish method + the GIF stream will not be valid. +*/ +GIFEncoder.prototype.finish = function() { + this.emit('finish#start'); + this.writeByte(0x3b); // gif trailer + this.emit('finish#stop'); +}; + +/* + Sets quality of color quantization (conversion of images to the maximum 256 + colors allowed by the GIF specification). Lower values (minimum = 1) + produce better colors, but slow processing significantly. 10 is the + default, and produces good color mapping at reasonable speeds. Values + greater than 20 do not yield significant improvements in speed. +*/ +GIFEncoder.prototype.setQuality = function(quality) { + if (quality < 1) quality = 1; + this.sample = quality; +}; + +/* + Writes GIF file header +*/ +GIFEncoder.prototype.writeHeader = function() { + this.emit('writeHeader#start'); + this.writeUTFBytes("GIF89a"); + this.emit('writeHeader#stop'); +}; + +/* + Analyzes current frame colors and creates color map. +*/ +GIFEncoder.prototype.analyzePixels = function() { + var len = this.pixels.length; + var nPix = len / 3; + + // TODO: Re-use indexedPixels + this.indexedPixels = new Uint8Array(nPix); + + var imgq = new NeuQuant(this.pixels, this.sample); + imgq.buildColormap(); // create reduced palette + this.colorTab = imgq.getColormap(); + + // map image pixels to new palette + var k = 0; + for (var j = 0; j < nPix; j++) { + var index = imgq.lookupRGB( + this.pixels[k++] & 0xff, + this.pixels[k++] & 0xff, + this.pixels[k++] & 0xff + ); + this.usedEntry[index] = true; + this.indexedPixels[j] = index; + } + + this.pixels = null; + this.colorDepth = 8; + this.palSize = 7; + + // get closest match to transparent color if specified + if (this.transparent !== null) { + this.transIndex = this.findClosest(this.transparent); + } +}; + +/* + Returns index of palette color closest to c +*/ +GIFEncoder.prototype.findClosest = function(c) { + if (this.colorTab === null) return -1; + + var r = (c & 0xFF0000) >> 16; + var g = (c & 0x00FF00) >> 8; + var b = (c & 0x0000FF); + var minpos = 0; + var dmin = 256 * 256 * 256; + var len = this.colorTab.length; + + for (var i = 0; i < len;) { + var dr = r - (this.colorTab[i++] & 0xff); + var dg = g - (this.colorTab[i++] & 0xff); + var db = b - (this.colorTab[i] & 0xff); + var d = dr * dr + dg * dg + db * db; + var index = i / 3; + if (this.usedEntry[index] && (d < dmin)) { + dmin = d; + minpos = index; + } + i++; + } + + return minpos; +}; + +/* + Extracts image pixels into byte array pixels + (removes alphachannel from canvas imagedata) +*/ +GIFEncoder.prototype.removeAlphaChannel = function (data) { + var w = this.width; + var h = this.height; + var pixels = new Uint8Array(w * h * 3); + + var count = 0; + + for (var i = 0; i < h; i++) { + for (var j = 0; j < w; j++) { + var b = (i * w * 4) + j * 4; + pixels[count++] = data[b]; + pixels[count++] = data[b+1]; + pixels[count++] = data[b+2]; + } + } + + return pixels; +}; + +GIFEncoder.prototype.setImagePixels = function(pixels) { + this.pixels = pixels; +}; + +/* + Writes Graphic Control Extension +*/ +GIFEncoder.prototype.writeGraphicCtrlExt = function() { + this.writeByte(0x21); // extension introducer + this.writeByte(0xf9); // GCE label + this.writeByte(4); // data block size + + var transp, disp; + if (this.transparent === null) { + transp = 0; + disp = 0; // dispose = no action + } else { + transp = 1; + disp = 2; // force clear if using transparent color + } + + if (this.dispose >= 0) { + disp = dispose & 7; // user override + } + disp <<= 2; + + // packed fields + this.writeByte( + 0 | // 1:3 reserved + disp | // 4:6 disposal + 0 | // 7 user input - 0 = none + transp // 8 transparency flag + ); + + this.writeShort(this.delay); // delay x 1/100 sec + this.writeByte(this.transIndex); // transparent color index + this.writeByte(0); // block terminator +}; + +/* + Writes Image Descriptor +*/ +GIFEncoder.prototype.writeImageDesc = function() { + this.writeByte(0x2c); // image separator + this.writeShort(0); // image position x,y = 0,0 + this.writeShort(0); + this.writeShort(this.width); // image size + this.writeShort(this.height); + + // packed fields + if (this.firstFrame) { + // no LCT - GCT is used for first (or only) frame + this.writeByte(0); + } else { + // specify normal LCT + this.writeByte( + 0x80 | // 1 local color table 1=yes + 0 | // 2 interlace - 0=no + 0 | // 3 sorted - 0=no + 0 | // 4-5 reserved + this.palSize // 6-8 size of color table + ); + } +}; + +/* + Writes Logical Screen Descriptor +*/ +GIFEncoder.prototype.writeLSD = function() { + // logical screen size + this.writeShort(this.width); + this.writeShort(this.height); + + // packed fields + this.writeByte( + 0x80 | // 1 : global color table flag = 1 (gct used) + 0x70 | // 2-4 : color resolution = 7 + 0x00 | // 5 : gct sort flag = 0 + this.palSize // 6-8 : gct size + ); + + this.writeByte(0); // background color index + this.writeByte(0); // pixel aspect ratio - assume 1:1 +}; + +/* + Writes Netscape application extension to define repeat count. +*/ +GIFEncoder.prototype.writeNetscapeExt = function() { + this.writeByte(0x21); // extension introducer + this.writeByte(0xff); // app extension label + this.writeByte(11); // block size + this.writeUTFBytes('NETSCAPE2.0'); // app id + auth code + this.writeByte(3); // sub-block size + this.writeByte(1); // loop sub-block id + this.writeShort(this.repeat); // loop count (extra iterations, 0=repeat forever) + this.writeByte(0); // block terminator +}; + +/* + Writes color table +*/ +GIFEncoder.prototype.writePalette = function() { + this.writeBytes(this.colorTab); + var n = (3 * 256) - this.colorTab.length; + for (var i = 0; i < n; i++) + this.writeByte(0); +}; + +GIFEncoder.prototype.writeShort = function(pValue) { + this.writeByte(pValue & 0xFF); + this.writeByte((pValue >> 8) & 0xFF); +}; + +/* + Encodes and writes pixel data +*/ +GIFEncoder.prototype.writePixels = function() { + var enc = new LZWEncoder(this.width, this.height, this.indexedPixels, this.colorDepth); + enc.encode(this); +}; + +/* + Retrieves the GIF stream +*/ +GIFEncoder.prototype.stream = function() { + return this; +}; + +GIFEncoder.ByteCapacitor = ByteCapacitor; + +module.exports = GIFEncoder; + +}).call(this,require("buffer").Buffer) +},{"./LZWEncoder.js":124,"./TypedNeuQuant.js":125,"assert":290,"buffer":297,"events":298,"readable-stream":131,"util":523}],124:[function(require,module,exports){ +/* + LZWEncoder.js + + Authors + Kevin Weiner (original Java version - kweiner@fmsware.com) + Thibault Imbert (AS3 version - bytearray.org) + Johan Nordberg (JS version - code@johan-nordberg.com) + + Acknowledgements + GIFCOMPR.C - GIF Image compression routines + Lempel-Ziv compression based on 'compress'. GIF modifications by + David Rowley (mgardi@watdcsu.waterloo.edu) + GIF Image compression - modified 'compress' + Based on: compress.c - File compression ala IEEE Computer, June 1984. + By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) + Jim McKie (decvax!mcvax!jim) + Steve Davies (decvax!vax135!petsd!peora!srd) + Ken Turkowski (decvax!decwrl!turtlevax!ken) + James A. Woods (decvax!ihnp4!ames!jaw) + Joe Orost (decvax!vax135!petsd!joe) +*/ + +var EOF = -1; +var BITS = 12; +var HSIZE = 5003; // 80% occupancy +var masks = [0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, + 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, + 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF]; + +function LZWEncoder(width, height, pixels, colorDepth) { + var initCodeSize = Math.max(2, colorDepth); + + var accum = new Uint8Array(256); + var htab = new Int32Array(HSIZE); + var codetab = new Int32Array(HSIZE); + + var cur_accum, cur_bits = 0; + var a_count; + var free_ent = 0; // first unused entry + var maxcode; + var remaining; + var curPixel; + var n_bits; + + // block compression parameters -- after all codes are used up, + // and compression rate changes, start over. + var clear_flg = false; + + // Algorithm: use open addressing double hashing (no chaining) on the + // prefix code / next character combination. We do a variant of Knuth's + // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime + // secondary probe. Here, the modular division first probe is gives way + // to a faster exclusive-or manipulation. Also do block compression with + // an adaptive reset, whereby the code table is cleared when the compression + // ratio decreases, but after the table fills. The variable-length output + // codes are re-sized at this point, and a special CLEAR code is generated + // for the decompressor. Late addition: construct the table according to + // file size for noticeable speed improvement on small files. Please direct + // questions about this implementation to ames!jaw. + var g_init_bits, ClearCode, EOFCode; + + // Add a character to the end of the current packet, and if it is 254 + // characters, flush the packet to disk. + function char_out(c, outs) { + accum[a_count++] = c; + if (a_count >= 254) flush_char(outs); + } + + // Clear out the hash table + // table clear for block compress + function cl_block(outs) { + cl_hash(HSIZE); + free_ent = ClearCode + 2; + clear_flg = true; + output(ClearCode, outs); + } + + // Reset code table + function cl_hash(hsize) { + for (var i = 0; i < hsize; ++i) htab[i] = -1; + } + + function compress(init_bits, outs) { + var fcode, c, i, ent, disp, hsize_reg, hshift; + + // Set up the globals: g_init_bits - initial number of bits + g_init_bits = init_bits; + + // Set up the necessary values + clear_flg = false; + n_bits = g_init_bits; + maxcode = MAXCODE(n_bits); + + ClearCode = 1 << (init_bits - 1); + EOFCode = ClearCode + 1; + free_ent = ClearCode + 2; + + a_count = 0; // clear packet + + ent = nextPixel(); + + hshift = 0; + for (fcode = HSIZE; fcode < 65536; fcode *= 2) ++hshift; + hshift = 8 - hshift; // set hash code range bound + hsize_reg = HSIZE; + cl_hash(hsize_reg); // clear hash table + + output(ClearCode, outs); + + outer_loop: while ((c = nextPixel()) != EOF) { + fcode = (c << BITS) + ent; + i = (c << hshift) ^ ent; // xor hashing + if (htab[i] === fcode) { + ent = codetab[i]; + continue; + } else if (htab[i] >= 0) { // non-empty slot + disp = hsize_reg - i; // secondary hash (after G. Knott) + if (i === 0) disp = 1; + do { + if ((i -= disp) < 0) i += hsize_reg; + if (htab[i] === fcode) { + ent = codetab[i]; + continue outer_loop; + } + } while (htab[i] >= 0); + } + output(ent, outs); + ent = c; + if (free_ent < 1 << BITS) { + codetab[i] = free_ent++; // code -> hashtable + htab[i] = fcode; + } else { + cl_block(outs); + } + } + + // Put out the final code. + output(ent, outs); + output(EOFCode, outs); + } + + function encode(outs) { + outs.writeByte(initCodeSize); // write "initial code size" byte + remaining = width * height; // reset navigation variables + curPixel = 0; + compress(initCodeSize + 1, outs); // compress and write the pixel data + outs.writeByte(0); // write block terminator + } + + // Flush the packet to disk, and reset the accumulator + function flush_char(outs) { + if (a_count > 0) { + outs.writeByte(a_count); + outs.writeBytes(accum, 0, a_count); + a_count = 0; + } + } + + function MAXCODE(n_bits) { + return (1 << n_bits) - 1; + } + + // Return the next pixel from the image + function nextPixel() { + if (remaining === 0) return EOF; + --remaining; + var pix = pixels[curPixel++]; + return pix & 0xff; + } + + function output(code, outs) { + cur_accum &= masks[cur_bits]; + + if (cur_bits > 0) cur_accum |= (code << cur_bits); + else cur_accum = code; + + cur_bits += n_bits; + + while (cur_bits >= 8) { + char_out((cur_accum & 0xff), outs); + cur_accum >>= 8; + cur_bits -= 8; + } + + // If the next entry is going to be too big for the code size, + // then increase it, if possible. + if (free_ent > maxcode || clear_flg) { + if (clear_flg) { + maxcode = MAXCODE(n_bits = g_init_bits); + clear_flg = false; + } else { + ++n_bits; + if (n_bits == BITS) maxcode = 1 << BITS; + else maxcode = MAXCODE(n_bits); + } + } + + if (code == EOFCode) { + // At EOF, write the rest of the buffer. + while (cur_bits > 0) { + char_out((cur_accum & 0xff), outs); + cur_accum >>= 8; + cur_bits -= 8; + } + flush_char(outs); + } + } + + this.encode = encode; +} + +module.exports = LZWEncoder; + +},{}],125:[function(require,module,exports){ +/* NeuQuant Neural-Net Quantization Algorithm + * ------------------------------------------ + * + * Copyright (c) 1994 Anthony Dekker + * + * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. + * See "Kohonen neural networks for optimal colour quantization" + * in "Network: Computation in Neural Systems" Vol. 5 (1994) pp 351-367. + * for a discussion of the algorithm. + * See also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML + * + * Any party obtaining a copy of these files from the author, directly or + * indirectly, is granted, free of charge, a full and unrestricted irrevocable, + * world-wide, paid up, royalty-free, nonexclusive right and license to deal + * in this software and documentation files (the "Software"), including without + * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons who receive + * copies from any such party to do so, with the only requirement being + * that this copyright notice remain intact. + * + * (JavaScript port 2012 by Johan Nordberg) + */ + +var ncycles = 100; // number of learning cycles +var netsize = 256; // number of colors used +var maxnetpos = netsize - 1; + +// defs for freq and bias +var netbiasshift = 4; // bias for colour values +var intbiasshift = 16; // bias for fractions +var intbias = (1 << intbiasshift); +var gammashift = 10; +var gamma = (1 << gammashift); +var betashift = 10; +var beta = (intbias >> betashift); /* beta = 1/1024 */ +var betagamma = (intbias << (gammashift - betashift)); + +// defs for decreasing radius factor +var initrad = (netsize >> 3); // for 256 cols, radius starts +var radiusbiasshift = 6; // at 32.0 biased by 6 bits +var radiusbias = (1 << radiusbiasshift); +var initradius = (initrad * radiusbias); //and decreases by a +var radiusdec = 30; // factor of 1/30 each cycle + +// defs for decreasing alpha factor +var alphabiasshift = 10; // alpha starts at 1.0 +var initalpha = (1 << alphabiasshift); +var alphadec; // biased by 10 bits + +/* radbias and alpharadbias used for radpower calculation */ +var radbiasshift = 8; +var radbias = (1 << radbiasshift); +var alpharadbshift = (alphabiasshift + radbiasshift); +var alpharadbias = (1 << alpharadbshift); + +// four primes near 500 - assume no image has a length so large that it is +// divisible by all four primes +var prime1 = 499; +var prime2 = 491; +var prime3 = 487; +var prime4 = 503; +var minpicturebytes = (3 * prime4); + +/* + Constructor: NeuQuant + + Arguments: + + pixels - array of pixels in RGB format + samplefac - sampling factor 1 to 30 where lower is better quality + + > + > pixels = [r, g, b, r, g, b, r, g, b, ..] + > +*/ +function NeuQuant(pixels, samplefac) { + var network; // int[netsize][4] + var netindex; // for network lookup - really 256 + + // bias and freq arrays for learning + var bias; + var freq; + var radpower; + + /* + Private Method: init + + sets up arrays + */ + function init() { + network = []; + netindex = new Int32Array(256); + bias = new Int32Array(netsize); + freq = new Int32Array(netsize); + radpower = new Int32Array(netsize >> 3); + + var i, v; + for (i = 0; i < netsize; i++) { + v = (i << (netbiasshift + 8)) / netsize; + network[i] = new Float64Array([v, v, v, 0]); + //network[i] = [v, v, v, 0] + freq[i] = intbias / netsize; + bias[i] = 0; + } + } + + /* + Private Method: unbiasnet + + unbiases network to give byte values 0..255 and record position i to prepare for sort + */ + function unbiasnet() { + for (var i = 0; i < netsize; i++) { + network[i][0] >>= netbiasshift; + network[i][1] >>= netbiasshift; + network[i][2] >>= netbiasshift; + network[i][3] = i; // record color number + } + } + + /* + Private Method: altersingle + + moves neuron *i* towards biased (b,g,r) by factor *alpha* + */ + function altersingle(alpha, i, b, g, r) { + network[i][0] -= (alpha * (network[i][0] - b)) / initalpha; + network[i][1] -= (alpha * (network[i][1] - g)) / initalpha; + network[i][2] -= (alpha * (network[i][2] - r)) / initalpha; + } + + /* + Private Method: alterneigh + + moves neurons in *radius* around index *i* towards biased (b,g,r) by factor *alpha* + */ + function alterneigh(radius, i, b, g, r) { + var lo = Math.abs(i - radius); + var hi = Math.min(i + radius, netsize); + + var j = i + 1; + var k = i - 1; + var m = 1; + + var p, a; + while ((j < hi) || (k > lo)) { + a = radpower[m++]; + + if (j < hi) { + p = network[j++]; + p[0] -= (a * (p[0] - b)) / alpharadbias; + p[1] -= (a * (p[1] - g)) / alpharadbias; + p[2] -= (a * (p[2] - r)) / alpharadbias; + } + + if (k > lo) { + p = network[k--]; + p[0] -= (a * (p[0] - b)) / alpharadbias; + p[1] -= (a * (p[1] - g)) / alpharadbias; + p[2] -= (a * (p[2] - r)) / alpharadbias; + } + } + } + + /* + Private Method: contest + + searches for biased BGR values + */ + function contest(b, g, r) { + /* + finds closest neuron (min dist) and updates freq + finds best neuron (min dist-bias) and returns position + for frequently chosen neurons, freq[i] is high and bias[i] is negative + bias[i] = gamma * ((1 / netsize) - freq[i]) + */ + + var bestd = ~(1 << 31); + var bestbiasd = bestd; + var bestpos = -1; + var bestbiaspos = bestpos; + + var i, n, dist, biasdist, betafreq; + for (i = 0; i < netsize; i++) { + n = network[i]; + + dist = Math.abs(n[0] - b) + Math.abs(n[1] - g) + Math.abs(n[2] - r); + if (dist < bestd) { + bestd = dist; + bestpos = i; + } + + biasdist = dist - ((bias[i]) >> (intbiasshift - netbiasshift)); + if (biasdist < bestbiasd) { + bestbiasd = biasdist; + bestbiaspos = i; + } + + betafreq = (freq[i] >> betashift); + freq[i] -= betafreq; + bias[i] += (betafreq << gammashift); + } + + freq[bestpos] += beta; + bias[bestpos] -= betagamma; + + return bestbiaspos; + } + + /* + Private Method: inxbuild + + sorts network and builds netindex[0..255] + */ + function inxbuild() { + var i, j, p, q, smallpos, smallval, previouscol = 0, startpos = 0; + for (i = 0; i < netsize; i++) { + p = network[i]; + smallpos = i; + smallval = p[1]; // index on g + // find smallest in i..netsize-1 + for (j = i + 1; j < netsize; j++) { + q = network[j]; + if (q[1] < smallval) { // index on g + smallpos = j; + smallval = q[1]; // index on g + } + } + q = network[smallpos]; + // swap p (i) and q (smallpos) entries + if (i != smallpos) { + j = q[0]; q[0] = p[0]; p[0] = j; + j = q[1]; q[1] = p[1]; p[1] = j; + j = q[2]; q[2] = p[2]; p[2] = j; + j = q[3]; q[3] = p[3]; p[3] = j; + } + // smallval entry is now in position i + + if (smallval != previouscol) { + netindex[previouscol] = (startpos + i) >> 1; + for (j = previouscol + 1; j < smallval; j++) + netindex[j] = i; + previouscol = smallval; + startpos = i; + } + } + netindex[previouscol] = (startpos + maxnetpos) >> 1; + for (j = previouscol + 1; j < 256; j++) + netindex[j] = maxnetpos; // really 256 + } + + /* + Private Method: inxsearch + + searches for BGR values 0..255 and returns a color index + */ + function inxsearch(b, g, r) { + var a, p, dist; + + var bestd = 1000; // biggest possible dist is 256*3 + var best = -1; + + var i = netindex[g]; // index on g + var j = i - 1; // start at netindex[g] and work outwards + + while ((i < netsize) || (j >= 0)) { + if (i < netsize) { + p = network[i]; + dist = p[1] - g; // inx key + if (dist >= bestd) i = netsize; // stop iter + else { + i++; + if (dist < 0) dist = -dist; + a = p[0] - b; if (a < 0) a = -a; + dist += a; + if (dist < bestd) { + a = p[2] - r; if (a < 0) a = -a; + dist += a; + if (dist < bestd) { + bestd = dist; + best = p[3]; + } + } + } + } + if (j >= 0) { + p = network[j]; + dist = g - p[1]; // inx key - reverse dif + if (dist >= bestd) j = -1; // stop iter + else { + j--; + if (dist < 0) dist = -dist; + a = p[0] - b; if (a < 0) a = -a; + dist += a; + if (dist < bestd) { + a = p[2] - r; if (a < 0) a = -a; + dist += a; + if (dist < bestd) { + bestd = dist; + best = p[3]; + } + } + } + } + } + + return best; + } + + /* + Private Method: learn + + "Main Learning Loop" + */ + function learn() { + var i; + + var lengthcount = pixels.length; + var alphadec = 30 + ((samplefac - 1) / 3); + var samplepixels = lengthcount / (3 * samplefac); + var delta = ~~(samplepixels / ncycles); + var alpha = initalpha; + var radius = initradius; + + var rad = radius >> radiusbiasshift; + + if (rad <= 1) rad = 0; + for (i = 0; i < rad; i++) + radpower[i] = alpha * (((rad * rad - i * i) * radbias) / (rad * rad)); + + var step; + if (lengthcount < minpicturebytes) { + samplefac = 1; + step = 3; + } else if ((lengthcount % prime1) !== 0) { + step = 3 * prime1; + } else if ((lengthcount % prime2) !== 0) { + step = 3 * prime2; + } else if ((lengthcount % prime3) !== 0) { + step = 3 * prime3; + } else { + step = 3 * prime4; + } + + var b, g, r, j; + var pix = 0; // current pixel + + i = 0; + while (i < samplepixels) { + b = (pixels[pix] & 0xff) << netbiasshift; + g = (pixels[pix + 1] & 0xff) << netbiasshift; + r = (pixels[pix + 2] & 0xff) << netbiasshift; + + j = contest(b, g, r); + + altersingle(alpha, j, b, g, r); + if (rad !== 0) alterneigh(rad, j, b, g, r); // alter neighbours + + pix += step; + if (pix >= lengthcount) pix -= lengthcount; + + i++; + + if (delta === 0) delta = 1; + if (i % delta === 0) { + alpha -= alpha / alphadec; + radius -= radius / radiusdec; + rad = radius >> radiusbiasshift; + + if (rad <= 1) rad = 0; + for (j = 0; j < rad; j++) + radpower[j] = alpha * (((rad * rad - j * j) * radbias) / (rad * rad)); + } + } + } + + /* + Method: buildColormap + + 1. initializes network + 2. trains it + 3. removes misconceptions + 4. builds colorindex + */ + function buildColormap() { + init(); + learn(); + unbiasnet(); + inxbuild(); + } + this.buildColormap = buildColormap; + + /* + Method: getColormap + + builds colormap from the index + + returns array in the format: + + > + > [r, g, b, r, g, b, r, g, b, ..] + > + */ + function getColormap() { + var map = []; + var index = []; + + for (var i = 0; i < netsize; i++) + index[network[i][3]] = i; + + var k = 0; + for (var l = 0; l < netsize; l++) { + var j = index[l]; + map[k++] = (network[j][0]); + map[k++] = (network[j][1]); + map[k++] = (network[j][2]); + } + return map; + } + this.getColormap = getColormap; + + /* + Method: lookupRGB + + looks for the closest *r*, *g*, *b* color in the map and + returns its index + */ + this.lookupRGB = inxsearch; +} + +module.exports = NeuQuant; + +},{}],126:[function(require,module,exports){ +arguments[4][41][0].apply(exports,arguments) +},{"./_stream_readable":128,"./_stream_writable":130,"_process":432,"core-util-is":47,"dup":41,"inherits":360}],127:[function(require,module,exports){ +arguments[4][42][0].apply(exports,arguments) +},{"./_stream_transform":129,"core-util-is":47,"dup":42,"inherits":360}],128:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +module.exports = Readable; + +/**/ +var isArray = require('isarray'); +/**/ + + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Readable.ReadableState = ReadableState; + +var EE = require('events').EventEmitter; + +/**/ +if (!EE.listenerCount) EE.listenerCount = function(emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +var Stream = require('stream'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var StringDecoder; + + +/**/ +var debug = require('util'); +if (debug && debug.debuglog) { + debug = debug.debuglog('stream'); +} else { + debug = function () {}; +} +/**/ + + +util.inherits(Readable, Stream); + +function ReadableState(options, stream) { + var Duplex = require('./_stream_duplex'); + + options = options || {}; + + // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.buffer = []; + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + + + // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.readableObjectMode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // when piping, we only care about 'readable' events that happen + // after read()ing all the bytes and not getting any pushback. + this.ranOut = false; + + // the number of writers that are awaiting a drain event in .pipe()s + this.awaitDrain = 0; + + // if true, a maybeReadMore has been scheduled + this.readingMore = false; + + this.decoder = null; + this.encoding = null; + if (options.encoding) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + var Duplex = require('./_stream_duplex'); + + if (!(this instanceof Readable)) + return new Readable(options); + + this._readableState = new ReadableState(options, this); + + // legacy + this.readable = true; + + Stream.call(this); +} + +// Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. +Readable.prototype.push = function(chunk, encoding) { + var state = this._readableState; + + if (util.isString(chunk) && !state.objectMode) { + encoding = encoding || state.defaultEncoding; + if (encoding !== state.encoding) { + chunk = new Buffer(chunk, encoding); + encoding = ''; + } + } + + return readableAddChunk(this, state, chunk, encoding, false); +}; + +// Unshift should *always* be something directly out of read() +Readable.prototype.unshift = function(chunk) { + var state = this._readableState; + return readableAddChunk(this, state, chunk, '', true); +}; + +function readableAddChunk(stream, state, chunk, encoding, addToFront) { + var er = chunkInvalid(state, chunk); + if (er) { + stream.emit('error', er); + } else if (util.isNullOrUndefined(chunk)) { + state.reading = false; + if (!state.ended) + onEofChunk(stream, state); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (state.ended && !addToFront) { + var e = new Error('stream.push() after EOF'); + stream.emit('error', e); + } else if (state.endEmitted && addToFront) { + var e = new Error('stream.unshift() after end event'); + stream.emit('error', e); + } else { + if (state.decoder && !addToFront && !encoding) + chunk = state.decoder.write(chunk); + + if (!addToFront) + state.reading = false; + + // if we want the data now, just emit it. + if (state.flowing && state.length === 0 && !state.sync) { + stream.emit('data', chunk); + stream.read(0); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) + state.buffer.unshift(chunk); + else + state.buffer.push(chunk); + + if (state.needReadable) + emitReadable(stream); + } + + maybeReadMore(stream, state); + } + } else if (!addToFront) { + state.reading = false; + } + + return needMoreData(state); +} + + + +// if it's past the high water mark, we can push in some more. +// Also, if we have no data yet, we can stand some +// more bytes. This is to work around cases where hwm=0, +// such as the repl. Also, if the push() triggered a +// readable event, and the user called read(largeNumber) such that +// needReadable was set, then we ought to push more, so that another +// 'readable' event will be triggered. +function needMoreData(state) { + return !state.ended && + (state.needReadable || + state.length < state.highWaterMark || + state.length === 0); +} + +// backwards compatibility. +Readable.prototype.setEncoding = function(enc) { + if (!StringDecoder) + StringDecoder = require('string_decoder/').StringDecoder; + this._readableState.decoder = new StringDecoder(enc); + this._readableState.encoding = enc; + return this; +}; + +// Don't raise the hwm > 128MB +var MAX_HWM = 0x800000; +function roundUpToNextPowerOf2(n) { + if (n >= MAX_HWM) { + n = MAX_HWM; + } else { + // Get the next highest power of 2 + n--; + for (var p = 1; p < 32; p <<= 1) n |= n >> p; + n++; + } + return n; +} + +function howMuchToRead(n, state) { + if (state.length === 0 && state.ended) + return 0; + + if (state.objectMode) + return n === 0 ? 0 : 1; + + if (isNaN(n) || util.isNull(n)) { + // only flow one buffer at a time + if (state.flowing && state.buffer.length) + return state.buffer[0].length; + else + return state.length; + } + + if (n <= 0) + return 0; + + // If we're asking for more than the target buffer level, + // then raise the water mark. Bump up to the next highest + // power of 2, to prevent increasing it excessively in tiny + // amounts. + if (n > state.highWaterMark) + state.highWaterMark = roundUpToNextPowerOf2(n); + + // don't have that much. return null, unless we've ended. + if (n > state.length) { + if (!state.ended) { + state.needReadable = true; + return 0; + } else + return state.length; + } + + return n; +} + +// you can override either this method, or the async _read(n) below. +Readable.prototype.read = function(n) { + debug('read', n); + var state = this._readableState; + var nOrig = n; + + if (!util.isNumber(n) || n > 0) + state.emittedReadable = false; + + // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + if (n === 0 && + state.needReadable && + (state.length >= state.highWaterMark || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) + endReadable(this); + else + emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); + + // if we've ended, and we're now clear, then finish it up. + if (n === 0 && state.ended) { + if (state.length === 0) + endReadable(this); + return null; + } + + // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + + // if we need a readable event, then we need to do some reading. + var doRead = state.needReadable; + debug('need readable', doRead); + + // if we currently have less than the highWaterMark, then also read some + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } + + // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } + + if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; + // if the length is currently zero, then we *need* a readable event. + if (state.length === 0) + state.needReadable = true; + // call internal read method + this._read(state.highWaterMark); + state.sync = false; + } + + // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + if (doRead && !state.reading) + n = howMuchToRead(nOrig, state); + + var ret; + if (n > 0) + ret = fromList(n, state); + else + ret = null; + + if (util.isNull(ret)) { + state.needReadable = true; + n = 0; + } + + state.length -= n; + + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (state.length === 0 && !state.ended) + state.needReadable = true; + + // If we tried to read() past the EOF, then emit end on the next tick. + if (nOrig !== n && state.ended && state.length === 0) + endReadable(this); + + if (!util.isNull(ret)) + this.emit('data', ret); + + return ret; +}; + +function chunkInvalid(state, chunk) { + var er = null; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + er = new TypeError('Invalid non-string/buffer chunk'); + } + return er; +} + + +function onEofChunk(stream, state) { + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + state.ended = true; + + // emit 'readable' now to make sure it gets picked up. + emitReadable(stream); +} + +// Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. +function emitReadable(stream) { + var state = stream._readableState; + state.needReadable = false; + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + if (state.sync) + process.nextTick(function() { + emitReadable_(stream); + }); + else + emitReadable_(stream); + } +} + +function emitReadable_(stream) { + debug('emit readable'); + stream.emit('readable'); + flow(stream); +} + + +// at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(function() { + maybeReadMore_(stream, state); + }); + } +} + +function maybeReadMore_(stream, state) { + var len = state.length; + while (!state.reading && !state.flowing && !state.ended && + state.length < state.highWaterMark) { + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) + // didn't get any data, stop spinning. + break; + else + len = state.length; + } + state.readingMore = false; +} + +// abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. +Readable.prototype._read = function(n) { + this.emit('error', new Error('not implemented')); +}; + +Readable.prototype.pipe = function(dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + case 1: + state.pipes = [state.pipes, dest]; + break; + default: + state.pipes.push(dest); + break; + } + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + + var doEnd = (!pipeOpts || pipeOpts.end !== false) && + dest !== process.stdout && + dest !== process.stderr; + + var endFn = doEnd ? onend : cleanup; + if (state.endEmitted) + process.nextTick(endFn); + else + src.once('end', endFn); + + dest.on('unpipe', onunpipe); + function onunpipe(readable) { + debug('onunpipe'); + if (readable === src) { + cleanup(); + } + } + + function onend() { + debug('onend'); + dest.end(); + } + + // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + + function cleanup() { + debug('cleanup'); + // cleanup event handlers once the pipe is broken + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', cleanup); + src.removeListener('data', ondata); + + // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + if (state.awaitDrain && + (!dest._writableState || dest._writableState.needDrain)) + ondrain(); + } + + src.on('data', ondata); + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + if (false === ret) { + debug('false write response, pause', + src._readableState.awaitDrain); + src._readableState.awaitDrain++; + src.pause(); + } + } + + // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EE.listenerCount(dest, 'error') === 0) + dest.emit('error', er); + } + // This is a brutally ugly hack to make sure that our error handler + // is attached before any userland ones. NEVER DO THIS. + if (!dest._events || !dest._events.error) + dest.on('error', onerror); + else if (isArray(dest._events.error)) + dest._events.error.unshift(onerror); + else + dest._events.error = [onerror, dest._events.error]; + + + + // Both close and finish should trigger unpipe, but only once. + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + dest.once('close', onclose); + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } + + // tell the dest that it's being piped to + dest.emit('pipe', src); + + // start the flow if it hasn't been started already. + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function() { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) + state.awaitDrain--; + if (state.awaitDrain === 0 && EE.listenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + + +Readable.prototype.unpipe = function(dest) { + var state = this._readableState; + + // if we're not piping anywhere, then do nothing. + if (state.pipesCount === 0) + return this; + + // just one destination. most common case. + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) + return this; + + if (!dest) + dest = state.pipes; + + // got a match. + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) + dest.emit('unpipe', this); + return this; + } + + // slow case. multiple pipe destinations. + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) + dests[i].emit('unpipe', this); + return this; + } + + // try to find the right one. + var i = indexOf(state.pipes, dest); + if (i === -1) + return this; + + state.pipes.splice(i, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) + state.pipes = state.pipes[0]; + + dest.emit('unpipe', this); + + return this; +}; + +// set up data events if they are asked for +// Ensure readable listeners eventually get something +Readable.prototype.on = function(ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + + // If listening to data, and it has not explicitly been paused, + // then call resume to start the flow of data on the next tick. + if (ev === 'data' && false !== this._readableState.flowing) { + this.resume(); + } + + if (ev === 'readable' && this.readable) { + var state = this._readableState; + if (!state.readableListening) { + state.readableListening = true; + state.emittedReadable = false; + state.needReadable = true; + if (!state.reading) { + var self = this; + process.nextTick(function() { + debug('readable nexttick read 0'); + self.read(0); + }); + } else if (state.length) { + emitReadable(this, state); + } + } + } + + return res; +}; +Readable.prototype.addListener = Readable.prototype.on; + +// pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. +Readable.prototype.resume = function() { + var state = this._readableState; + if (!state.flowing) { + debug('resume'); + state.flowing = true; + if (!state.reading) { + debug('resume read 0'); + this.read(0); + } + resume(this, state); + } + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + process.nextTick(function() { + resume_(stream, state); + }); + } +} + +function resume_(stream, state) { + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) + stream.read(0); +} + +Readable.prototype.pause = function() { + debug('call pause flowing=%j', this._readableState.flowing); + if (false !== this._readableState.flowing) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + if (state.flowing) { + do { + var chunk = stream.read(); + } while (null !== chunk && state.flowing); + } +} + +// wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. +Readable.prototype.wrap = function(stream) { + var state = this._readableState; + var paused = false; + + var self = this; + stream.on('end', function() { + debug('wrapped end'); + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) + self.push(chunk); + } + + self.push(null); + }); + + stream.on('data', function(chunk) { + debug('wrapped data'); + if (state.decoder) + chunk = state.decoder.write(chunk); + if (!chunk || !state.objectMode && !chunk.length) + return; + + var ret = self.push(chunk); + if (!ret) { + paused = true; + stream.pause(); + } + }); + + // proxy all the other methods. + // important when wrapping filters and duplexes. + for (var i in stream) { + if (util.isFunction(stream[i]) && util.isUndefined(this[i])) { + this[i] = function(method) { return function() { + return stream[method].apply(stream, arguments); + }}(i); + } + } + + // proxy certain important events. + var events = ['error', 'close', 'destroy', 'pause', 'resume']; + forEach(events, function(ev) { + stream.on(ev, self.emit.bind(self, ev)); + }); + + // when we try to consume some more bytes, simply unpause the + // underlying stream. + self._read = function(n) { + debug('wrapped _read', n); + if (paused) { + paused = false; + stream.resume(); + } + }; + + return self; +}; + + + +// exposed for testing purposes only. +Readable._fromList = fromList; + +// Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +function fromList(n, state) { + var list = state.buffer; + var length = state.length; + var stringMode = !!state.decoder; + var objectMode = !!state.objectMode; + var ret; + + // nothing in the list, definitely empty. + if (list.length === 0) + return null; + + if (length === 0) + ret = null; + else if (objectMode) + ret = list.shift(); + else if (!n || n >= length) { + // read it all, truncate the array. + if (stringMode) + ret = list.join(''); + else + ret = Buffer.concat(list, length); + list.length = 0; + } else { + // read just some of it. + if (n < list[0].length) { + // just take a part of the first list item. + // slice is the same for buffers and strings. + var buf = list[0]; + ret = buf.slice(0, n); + list[0] = buf.slice(n); + } else if (n === list[0].length) { + // first list is a perfect match + ret = list.shift(); + } else { + // complex case. + // we have enough to cover it, but it spans past the first buffer. + if (stringMode) + ret = ''; + else + ret = new Buffer(n); + + var c = 0; + for (var i = 0, l = list.length; i < l && c < n; i++) { + var buf = list[0]; + var cpy = Math.min(n - c, buf.length); + + if (stringMode) + ret += buf.slice(0, cpy); + else + buf.copy(ret, c, 0, cpy); + + if (cpy < buf.length) + list[0] = buf.slice(cpy); + else + list.shift(); + + c += cpy; + } + } + } + + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + + // If we get here before consuming all the bytes, then that is a + // bug in node. Should never happen. + if (state.length > 0) + throw new Error('endReadable called on non-empty stream'); + + if (!state.endEmitted) { + state.ended = true; + process.nextTick(function() { + // Check that we didn't get one last unshift. + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + } + }); + } +} + +function forEach (xs, f) { + for (var i = 0, l = xs.length; i < l; i++) { + f(xs[i], i); + } +} + +function indexOf (xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + return -1; +} + +}).call(this,require('_process')) +},{"./_stream_duplex":126,"_process":432,"buffer":297,"core-util-is":47,"events":298,"inherits":360,"isarray":368,"stream":503,"string_decoder/":508,"util":34}],129:[function(require,module,exports){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + + +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + +module.exports = Transform; + +var Duplex = require('./_stream_duplex'); + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +util.inherits(Transform, Duplex); + + +function TransformState(options, stream) { + this.afterTransform = function(er, data) { + return afterTransform(stream, er, data); + }; + + this.needTransform = false; + this.transforming = false; + this.writecb = null; + this.writechunk = null; +} + +function afterTransform(stream, er, data) { + var ts = stream._transformState; + ts.transforming = false; + + var cb = ts.writecb; + + if (!cb) + return stream.emit('error', new Error('no writecb in Transform class')); + + ts.writechunk = null; + ts.writecb = null; + + if (!util.isNullOrUndefined(data)) + stream.push(data); + + if (cb) + cb(er); + + var rs = stream._readableState; + rs.reading = false; + if (rs.needReadable || rs.length < rs.highWaterMark) { + stream._read(rs.highWaterMark); + } +} + + +function Transform(options) { + if (!(this instanceof Transform)) + return new Transform(options); + + Duplex.call(this, options); + + this._transformState = new TransformState(options, this); + + // when the writable side finishes, then flush out anything remaining. + var stream = this; + + // start out asking for a readable event once data is transformed. + this._readableState.needReadable = true; + + // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + this._readableState.sync = false; + + this.once('prefinish', function() { + if (util.isFunction(this._flush)) + this._flush(function(er) { + done(stream, er); + }); + else + done(stream); + }); +} + +Transform.prototype.push = function(chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; + +// This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. +Transform.prototype._transform = function(chunk, encoding, cb) { + throw new Error('not implemented'); +}; + +Transform.prototype._write = function(chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || + rs.needReadable || + rs.length < rs.highWaterMark) + this._read(rs.highWaterMark); + } +}; + +// Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. +Transform.prototype._read = function(n) { + var ts = this._transformState; + + if (!util.isNull(ts.writechunk) && ts.writecb && !ts.transforming) { + ts.transforming = true; + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + + +function done(stream, er) { + if (er) + return stream.emit('error', er); + + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + var ws = stream._writableState; + var ts = stream._transformState; + + if (ws.length) + throw new Error('calling transform done when ws.length != 0'); + + if (ts.transforming) + throw new Error('calling transform done when still transforming'); + + return stream.push(null); +} + +},{"./_stream_duplex":126,"core-util-is":47,"inherits":360}],130:[function(require,module,exports){ +(function (process){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// A bit simpler than readable streams. +// Implement an async ._write(chunk, cb), and it'll handle all +// the drain event emission and buffering. + +module.exports = Writable; + +/**/ +var Buffer = require('buffer').Buffer; +/**/ + +Writable.WritableState = WritableState; + + +/**/ +var util = require('core-util-is'); +util.inherits = require('inherits'); +/**/ + +var Stream = require('stream'); + +util.inherits(Writable, Stream); + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; +} + +function WritableState(options, stream) { + var Duplex = require('./_stream_duplex'); + + options = options || {}; + + // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + var hwm = options.highWaterMark; + var defaultHwm = options.objectMode ? 16 : 16 * 1024; + this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + + // object stream flag to indicate whether or not this stream + // contains buffers or objects. + this.objectMode = !!options.objectMode; + + if (stream instanceof Duplex) + this.objectMode = this.objectMode || !!options.writableObjectMode; + + // cast to ints. + this.highWaterMark = ~~this.highWaterMark; + + this.needDrain = false; + // at the start of calling end() + this.ending = false; + // when end() has been called, and returned + this.ended = false; + // when 'finish' is emitted + this.finished = false; + + // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; + + // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + this.defaultEncoding = options.defaultEncoding || 'utf8'; + + // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + this.length = 0; + + // a flag to see when we're in the middle of a write. + this.writing = false; + + // when true all writes will be buffered until .uncork() call + this.corked = 0; + + // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + this.sync = true; + + // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + this.bufferProcessing = false; + + // the callback that's passed to _write(chunk,cb) + this.onwrite = function(er) { + onwrite(stream, er); + }; + + // the callback that the user supplies to write(chunk,encoding,cb) + this.writecb = null; + + // the amount that is being written when _write is called. + this.writelen = 0; + + this.buffer = []; + + // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + this.pendingcb = 0; + + // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + this.prefinished = false; + + // True if the error was already emitted and should not be thrown again + this.errorEmitted = false; +} + +function Writable(options) { + var Duplex = require('./_stream_duplex'); + + // Writable ctor is applied to Duplexes, though they're not + // instanceof Writable, they're instanceof Readable. + if (!(this instanceof Writable) && !(this instanceof Duplex)) + return new Writable(options); + + this._writableState = new WritableState(options, this); + + // legacy. + this.writable = true; + + Stream.call(this); +} + +// Otherwise people can pipe Writable streams, which is just wrong. +Writable.prototype.pipe = function() { + this.emit('error', new Error('Cannot pipe. Not readable.')); +}; + + +function writeAfterEnd(stream, state, cb) { + var er = new Error('write after end'); + // TODO: defer error events consistently everywhere, not just the cb + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); +} + +// If we get something that is not a buffer, string, null, or undefined, +// and we're not in objectMode, then that's an error. +// Otherwise stream chunks are all considered to be of length=1, and the +// watermarks determine how many objects to keep in the buffer, rather than +// how many bytes or characters. +function validChunk(stream, state, chunk, cb) { + var valid = true; + if (!util.isBuffer(chunk) && + !util.isString(chunk) && + !util.isNullOrUndefined(chunk) && + !state.objectMode) { + var er = new TypeError('Invalid non-string/buffer chunk'); + stream.emit('error', er); + process.nextTick(function() { + cb(er); + }); + valid = false; + } + return valid; +} + +Writable.prototype.write = function(chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (util.isBuffer(chunk)) + encoding = 'buffer'; + else if (!encoding) + encoding = state.defaultEncoding; + + if (!util.isFunction(cb)) + cb = function() {}; + + if (state.ended) + writeAfterEnd(this, state, cb); + else if (validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, chunk, encoding, cb); + } + + return ret; +}; + +Writable.prototype.cork = function() { + var state = this._writableState; + + state.corked++; +}; + +Writable.prototype.uncork = function() { + var state = this._writableState; + + if (state.corked) { + state.corked--; + + if (!state.writing && + !state.corked && + !state.finished && + !state.bufferProcessing && + state.buffer.length) + clearBuffer(this, state); + } +}; + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && + state.decodeStrings !== false && + util.isString(chunk)) { + chunk = new Buffer(chunk, encoding); + } + return chunk; +} + +// if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. +function writeOrBuffer(stream, state, chunk, encoding, cb) { + chunk = decodeChunk(state, chunk, encoding); + if (util.isBuffer(chunk)) + encoding = 'buffer'; + var len = state.objectMode ? 1 : chunk.length; + + state.length += len; + + var ret = state.length < state.highWaterMark; + // we must ensure that previous needDrain will not be reset to false. + if (!ret) + state.needDrain = true; + + if (state.writing || state.corked) + state.buffer.push(new WriteReq(chunk, encoding, cb)); + else + doWrite(stream, state, false, len, chunk, encoding, cb); + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (writev) + stream._writev(chunk, state.onwrite); + else + stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + if (sync) + process.nextTick(function() { + state.pendingcb--; + cb(er); + }); + else { + state.pendingcb--; + cb(er); + } + + stream._writableState.errorEmitted = true; + stream.emit('error', er); +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + + onwriteStateUpdate(state); + + if (er) + onwriteError(stream, state, sync, er, cb); + else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(stream, state); + + if (!finished && + !state.corked && + !state.bufferProcessing && + state.buffer.length) { + clearBuffer(stream, state); + } + + if (sync) { + process.nextTick(function() { + afterWrite(stream, state, finished, cb); + }); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) + onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} + +// Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} + + +// if there's something in the buffer waiting, then process it +function clearBuffer(stream, state) { + state.bufferProcessing = true; + + if (stream._writev && state.buffer.length > 1) { + // Fast case, write everything using _writev() + var cbs = []; + for (var c = 0; c < state.buffer.length; c++) + cbs.push(state.buffer[c].callback); + + // count the one we are adding, as well. + // TODO(isaacs) clean this up + state.pendingcb++; + doWrite(stream, state, true, state.length, state.buffer, '', function(err) { + for (var i = 0; i < cbs.length; i++) { + state.pendingcb--; + cbs[i](err); + } + }); + + // Clear buffer + state.buffer = []; + } else { + // Slow case, write chunks one-by-one + for (var c = 0; c < state.buffer.length; c++) { + var entry = state.buffer[c]; + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + + doWrite(stream, state, false, len, chunk, encoding, cb); + + // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + if (state.writing) { + c++; + break; + } + } + + if (c < state.buffer.length) + state.buffer = state.buffer.slice(c); + else + state.buffer.length = 0; + } + + state.bufferProcessing = false; +} + +Writable.prototype._write = function(chunk, encoding, cb) { + cb(new Error('not implemented')); + +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function(chunk, encoding, cb) { + var state = this._writableState; + + if (util.isFunction(chunk)) { + cb = chunk; + chunk = null; + encoding = null; + } else if (util.isFunction(encoding)) { + cb = encoding; + encoding = null; + } + + if (!util.isNullOrUndefined(chunk)) + this.write(chunk, encoding); + + // .end() fully uncorks + if (state.corked) { + state.corked = 1; + this.uncork(); + } + + // ignore unnecessary end() calls. + if (!state.ending && !state.finished) + endWritable(this, state, cb); +}; + + +function needFinish(stream, state) { + return (state.ending && + state.length === 0 && + !state.finished && + !state.writing); +} + +function prefinish(stream, state) { + if (!state.prefinished) { + state.prefinished = true; + stream.emit('prefinish'); + } +} + +function finishMaybe(stream, state) { + var need = needFinish(stream, state); + if (need) { + if (state.pendingcb === 0) { + prefinish(stream, state); + state.finished = true; + stream.emit('finish'); + } else + prefinish(stream, state); + } + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + if (cb) { + if (state.finished) + process.nextTick(cb); + else + stream.once('finish', cb); + } + state.ended = true; +} + +}).call(this,require('_process')) +},{"./_stream_duplex":126,"_process":432,"buffer":297,"core-util-is":47,"inherits":360,"stream":503}],131:[function(require,module,exports){ +(function (process){ +exports = module.exports = require('./lib/_stream_readable.js'); +exports.Stream = require('stream'); +exports.Readable = exports; +exports.Writable = require('./lib/_stream_writable.js'); +exports.Duplex = require('./lib/_stream_duplex.js'); +exports.Transform = require('./lib/_stream_transform.js'); +exports.PassThrough = require('./lib/_stream_passthrough.js'); +if (!process.browser && process.env.READABLE_STREAM === 'disable') { + module.exports = require('stream'); +} + +}).call(this,require('_process')) +},{"./lib/_stream_duplex.js":126,"./lib/_stream_passthrough.js":127,"./lib/_stream_readable.js":128,"./lib/_stream_transform.js":129,"./lib/_stream_writable.js":130,"_process":432,"stream":503}],132:[function(require,module,exports){ +/*Copyrights for code authored by Yahoo Inc. is licensed under the following terms: +MIT License +Copyright 2017 Yahoo Inc. +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +;(function(window, document, navigator, undefined) { +"use strict"; + +/* + utils.js + ======== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +var utils = { + URL: window.URL || window.webkitURL || window.mozURL || window.msURL, + getUserMedia: function () { + var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; + + return getUserMedia ? getUserMedia.bind(navigator) : getUserMedia; + }(), + requestAnimFrame: window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame, + requestTimeout: function requestTimeout(callback, delay) { + callback = callback || utils.noop; + delay = delay || 0; + + if (!utils.requestAnimFrame) { + return setTimeout(callback, delay); + } + + var start = new Date().getTime(); + var handle = new Object(); + var requestAnimFrame = utils.requestAnimFrame; + + var loop = function loop() { + var current = new Date().getTime(); + var delta = current - start; + + delta >= delay ? callback.call() : handle.value = requestAnimFrame(loop); + }; + + handle.value = requestAnimFrame(loop); + + return handle; + }, + Blob: window.Blob || window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder, + btoa: function () { + var btoa = window.btoa || function (input) { + var output = ''; + var i = 0; + var l = input.length; + var key = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + var chr1 = void 0; + var chr2 = void 0; + var chr3 = void 0; + var enc1 = void 0; + var enc2 = void 0; + var enc3 = void 0; + var enc4 = void 0; + + while (i < l) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = (chr1 & 3) << 4 | chr2 >> 4; + enc3 = (chr2 & 15) << 2 | chr3 >> 6; + enc4 = chr3 & 63; + + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + + output = output + key.charAt(enc1) + key.charAt(enc2) + key.charAt(enc3) + key.charAt(enc4); + } + + return output; + }; + + return btoa ? btoa.bind(window) : utils.noop; + }(), + isObject: function isObject(obj) { + return obj && Object.prototype.toString.call(obj) === '[object Object]'; + }, + isEmptyObject: function isEmptyObject(obj) { + return utils.isObject(obj) && !Object.keys(obj).length; + }, + isArray: function isArray(arr) { + return arr && Array.isArray(arr); + }, + isFunction: function isFunction(func) { + return func && typeof func === 'function'; + }, + isElement: function isElement(elem) { + return elem && elem.nodeType === 1; + }, + isString: function isString(value) { + return typeof value === 'string' || Object.prototype.toString.call(value) === '[object String]'; + }, + isSupported: { + canvas: function canvas() { + var el = document.createElement('canvas'); + + return el && el.getContext && el.getContext('2d'); + }, + webworkers: function webworkers() { + return window.Worker; + }, + blob: function blob() { + return utils.Blob; + }, + Uint8Array: function Uint8Array() { + return window.Uint8Array; + }, + Uint32Array: function Uint32Array() { + return window.Uint32Array; + }, + videoCodecs: function () { + var testEl = document.createElement('video'); + var supportObj = { + 'mp4': false, + 'h264': false, + 'ogv': false, + 'ogg': false, + 'webm': false + }; + + try { + if (testEl && testEl.canPlayType) { + // Check for MPEG-4 support + supportObj.mp4 = testEl.canPlayType('video/mp4; codecs="mp4v.20.8"') !== ''; + + // Check for h264 support + supportObj.h264 = (testEl.canPlayType('video/mp4; codecs="avc1.42E01E"') || testEl.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')) !== ''; + + // Check for Ogv support + supportObj.ogv = testEl.canPlayType('video/ogg; codecs="theora"') !== ''; + + // Check for Ogg support + supportObj.ogg = testEl.canPlayType('video/ogg; codecs="theora"') !== ''; + + // Check for Webm support + supportObj.webm = testEl.canPlayType('video/webm; codecs="vp8, vorbis"') !== -1; + } + } catch (e) {} + + return supportObj; + }() + }, + noop: function noop() {}, + each: function each(collection, callback) { + var x = void 0; + var len = void 0; + + if (utils.isArray(collection)) { + x = -1; + len = collection.length; + + while (++x < len) { + if (callback(x, collection[x]) === false) { + break; + } + } + } else if (utils.isObject(collection)) { + for (x in collection) { + if (collection.hasOwnProperty(x)) { + if (callback(x, collection[x]) === false) { + break; + } + } + } + } + }, + mergeOptions: function mergeOptions(defaultOptions, userOptions) { + if (!utils.isObject(defaultOptions) || !utils.isObject(userOptions) || !Object.keys) { + return; + } + + var newObj = {}; + + utils.each(defaultOptions, function (key, val) { + newObj[key] = defaultOptions[key]; + }); + + utils.each(userOptions, function (key, val) { + var currentUserOption = userOptions[key]; + + if (!utils.isObject(currentUserOption)) { + newObj[key] = currentUserOption; + } else { + if (!defaultOptions[key]) { + newObj[key] = currentUserOption; + } else { + newObj[key] = utils.mergeOptions(defaultOptions[key], currentUserOption); + } + } + }); + + return newObj; + }, + setCSSAttr: function setCSSAttr(elem, attr, val) { + if (!utils.isElement(elem)) { + return; + } + + if (utils.isString(attr) && utils.isString(val)) { + elem.style[attr] = val; + } else if (utils.isObject(attr)) { + utils.each(attr, function (key, val) { + elem.style[key] = val; + }); + } + }, + removeElement: function removeElement(node) { + if (!utils.isElement(node)) { + return; + } + if (node.parentNode) { + node.parentNode.removeChild(node); + } + }, + createWebWorker: function createWebWorker(content) { + if (!utils.isString(content)) { + return {}; + } + + try { + var blob = new utils.Blob([content], { + 'type': 'text/javascript' + }); + var objectUrl = utils.URL.createObjectURL(blob); + var worker = new Worker(objectUrl); + + return { + 'objectUrl': objectUrl, + 'worker': worker + }; + } catch (e) { + return '' + e; + } + }, + getExtension: function getExtension(src) { + return src.substr(src.lastIndexOf('.') + 1, src.length); + }, + getFontSize: function getFontSize() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + if (!document.body || options.resizeFont === false) { + return options.fontSize; + } + + var text = options.text; + var containerWidth = options.gifWidth; + var fontSize = parseInt(options.fontSize, 10); + var minFontSize = parseInt(options.minFontSize, 10); + var div = document.createElement('div'); + var span = document.createElement('span'); + + div.setAttribute('width', containerWidth); + div.appendChild(span); + + span.innerHTML = text; + span.style.fontSize = fontSize + 'px'; + span.style.textIndent = '-9999px'; + span.style.visibility = 'hidden'; + + document.body.appendChild(span); + + while (span.offsetWidth > containerWidth && fontSize >= minFontSize) { + span.style.fontSize = --fontSize + 'px'; + } + + document.body.removeChild(span); + + return fontSize + 'px'; + }, + webWorkerError: false +}; + + + +var utils$2 = Object.freeze({ + default: utils +}); + +/* + error.js + ======== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +var error = { + validate: function validate(skipObj) { + skipObj = utils.isObject(skipObj) ? skipObj : {}; + + var errorObj = {}; + + utils.each(error.validators, function (indece, currentValidator) { + var errorCode = currentValidator.errorCode; + + if (!skipObj[errorCode] && !currentValidator.condition) { + errorObj = currentValidator; + errorObj.error = true; + + return false; + } + }); + + delete errorObj.condition; + + return errorObj; + }, + isValid: function isValid(skipObj) { + var errorObj = error.validate(skipObj); + var isValid = errorObj.error !== true ? true : false; + + return isValid; + }, + validators: [{ + condition: utils.isFunction(utils.getUserMedia), + errorCode: 'getUserMedia', + errorMsg: 'The getUserMedia API is not supported in your browser' + }, { + condition: utils.isSupported.canvas(), + errorCode: 'canvas', + errorMsg: 'Canvas elements are not supported in your browser' + }, { + condition: utils.isSupported.webworkers(), + errorCode: 'webworkers', + errorMsg: 'The Web Workers API is not supported in your browser' + }, { + condition: utils.isFunction(utils.URL), + errorCode: 'window.URL', + errorMsg: 'The window.URL API is not supported in your browser' + }, { + condition: utils.isSupported.blob(), + errorCode: 'window.Blob', + errorMsg: 'The window.Blob File API is not supported in your browser' + }, { + condition: utils.isSupported.Uint8Array(), + errorCode: 'window.Uint8Array', + errorMsg: 'The window.Uint8Array function constructor is not supported in your browser' + }, { + condition: utils.isSupported.Uint32Array(), + errorCode: 'window.Uint32Array', + errorMsg: 'The window.Uint32Array function constructor is not supported in your browser' + }], + messages: { + videoCodecs: { + errorCode: 'videocodec', + errorMsg: 'The video codec you are trying to use is not supported in your browser' + } + } +}; + + + +var error$2 = Object.freeze({ + default: error +}); + +/* + defaultOptions.js + ================= +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Helpers +var noop = function noop() {}; + +var defaultOptions = { + sampleInterval: 10, + numWorkers: 2, + filter: '', + gifWidth: 200, + gifHeight: 200, + interval: 0.1, + numFrames: 10, + frameDuration: 1, + keepCameraOn: false, + images: [], + video: null, + webcamVideoElement: null, + cameraStream: null, + text: '', + fontWeight: 'normal', + fontSize: '16px', + minFontSize: '10px', + resizeFont: false, + fontFamily: 'sans-serif', + fontColor: '#ffffff', + textAlign: 'center', + textBaseline: 'bottom', + textXCoordinate: null, + textYCoordinate: null, + progressCallback: noop, + completeCallback: noop, + saveRenderingContexts: false, + savedRenderingContexts: [], + crossOrigin: 'Anonymous' +}; + + + +var defaultOptions$2 = Object.freeze({ + default: defaultOptions +}); + +/* + isSupported.js + ============== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +function isSupported() { + return error.isValid(); +} + +/* + isWebCamGIFSupported.js + ======================= +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +function isWebCamGIFSupported() { + return error.isValid(); +} + +/* + isSupported.js + ============== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +function isSupported$1() { + var options = { + getUserMedia: true + }; + + return error.isValid(options); +} + +/* + isExistingVideoGIFSupported.js + ============================== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +function isExistingVideoGIFSupported(codecs) { + var hasValidCodec = false; + + if (utils.isArray(codecs) && codecs.length) { + utils.each(codecs, function (indece, currentCodec) { + if (utils.isSupported.videoCodecs[currentCodec]) { + hasValidCodec = true; + } + }); + + if (!hasValidCodec) { + return false; + } + } else if (utils.isString(codecs) && codecs.length) { + if (!utils.isSupported.videoCodecs[codecs]) { + return false; + } + } + + return error.isValid({ + 'getUserMedia': true + }); +} + +/* + NeuQuant.js + =========== +*/ + +/* + * NeuQuant Neural-Net Quantization Algorithm + * ------------------------------------------ + * + * Copyright (c) 1994 Anthony Dekker + * + * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994. See + * "Kohonen neural networks for optimal colour quantization" in "Network: + * Computation in Neural Systems" Vol. 5 (1994) pp 351-367. for a discussion of + * the algorithm. + * + * Any party obtaining a copy of these files from the author, directly or + * indirectly, is granted, free of charge, a full and unrestricted irrevocable, + * world-wide, paid up, royalty-free, nonexclusive right and license to deal in + * this software and documentation files (the "Software"), including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons who + * receive copies from any such party to do so, with the only requirement being + * that this copyright notice remain intact. + */ + +/* + * This class handles Neural-Net quantization algorithm + * @author Kevin Weiner (original Java version - kweiner@fmsware.com) + * @author Thibault Imbert (AS3 version - bytearray.org) + * @version 0.1 AS3 implementation + * @version 0.2 JS->AS3 "translation" by antimatter15 + * @version 0.3 JS clean up + using modern JS idioms by sole - http://soledadpenades.com + * Also implement fix in color conversion described at http://stackoverflow.com/questions/16371712/neuquant-js-javascript-color-quantization-hidden-bug-in-js-conversion + */ + +function NeuQuant() { + var netsize = 256; // number of colours used + + // four primes near 500 - assume no image has a length so large + // that it is divisible by all four primes + var prime1 = 499; + var prime2 = 491; + var prime3 = 487; + var prime4 = 503; + + // minimum size for input image + var minpicturebytes = 3 * prime4; + + // Network Definitions + + var maxnetpos = netsize - 1; + var netbiasshift = 4; // bias for colour values + var ncycles = 100; // no. of learning cycles + + // defs for freq and bias + var intbiasshift = 16; // bias for fractions + var intbias = 1 << intbiasshift; + var gammashift = 10; // gamma = 1024 + var gamma = 1 << gammashift; + var betashift = 10; + var beta = intbias >> betashift; // beta = 1/1024 + var betagamma = intbias << gammashift - betashift; + + // defs for decreasing radius factor + // For 256 colors, radius starts at 32.0 biased by 6 bits + // and decreases by a factor of 1/30 each cycle + var initrad = netsize >> 3; + var radiusbiasshift = 6; + var radiusbias = 1 << radiusbiasshift; + var initradius = initrad * radiusbias; + var radiusdec = 30; + + // defs for decreasing alpha factor + // Alpha starts at 1.0 biased by 10 bits + var alphabiasshift = 10; + var initalpha = 1 << alphabiasshift; + var alphadec; + + // radbias and alpharadbias used for radpower calculation + var radbiasshift = 8; + var radbias = 1 << radbiasshift; + var alpharadbshift = alphabiasshift + radbiasshift; + var alpharadbias = 1 << alpharadbshift; + + // Input image + var thepicture; + // Height * Width * 3 + var lengthcount; + // Sampling factor 1..30 + var samplefac; + + // The network itself + var network; + var netindex = []; + + // for network lookup - really 256 + var bias = []; + + // bias and freq arrays for learning + var freq = []; + var radpower = []; + + function NeuQuantConstructor(thepic, len, sample) { + + var i; + var p; + + thepicture = thepic; + lengthcount = len; + samplefac = sample; + + network = new Array(netsize); + + for (i = 0; i < netsize; i++) { + network[i] = new Array(4); + p = network[i]; + p[0] = p[1] = p[2] = (i << netbiasshift + 8) / netsize | 0; + freq[i] = intbias / netsize | 0; // 1 / netsize + bias[i] = 0; + } + } + + function colorMap() { + var map = []; + var index = new Array(netsize); + for (var i = 0; i < netsize; i++) { + index[network[i][3]] = i; + }var k = 0; + for (var l = 0; l < netsize; l++) { + var j = index[l]; + map[k++] = network[j][0]; + map[k++] = network[j][1]; + map[k++] = network[j][2]; + } + return map; + } + + // Insertion sort of network and building of netindex[0..255] + // (to do after unbias) + function inxbuild() { + var i; + var j; + var smallpos; + var smallval; + var p; + var q; + var previouscol; + var startpos; + + previouscol = 0; + startpos = 0; + + for (i = 0; i < netsize; i++) { + + p = network[i]; + smallpos = i; + smallval = p[1]; // index on g + // find smallest in i..netsize-1 + for (j = i + 1; j < netsize; j++) { + + q = network[j]; + + if (q[1] < smallval) { + // index on g + smallpos = j; + smallval = q[1]; // index on g + } + } + + q = network[smallpos]; + + // swap p (i) and q (smallpos) entries + if (i != smallpos) { + j = q[0]; + q[0] = p[0]; + p[0] = j; + j = q[1]; + q[1] = p[1]; + p[1] = j; + j = q[2]; + q[2] = p[2]; + p[2] = j; + j = q[3]; + q[3] = p[3]; + p[3] = j; + } + + // smallval entry is now in position i + if (smallval != previouscol) { + + netindex[previouscol] = startpos + i >> 1; + + for (j = previouscol + 1; j < smallval; j++) { + netindex[j] = i; + } + + previouscol = smallval; + startpos = i; + } + } + + netindex[previouscol] = startpos + maxnetpos >> 1; + for (j = previouscol + 1; j < 256; j++) { + netindex[j] = maxnetpos; // really 256 + } + } + + // Main Learning Loop + + function learn() { + var i; + var j; + var b; + var g; + var r; + var radius; + var rad; + var alpha; + var step; + var delta; + var samplepixels; + var p; + var pix; + var lim; + + if (lengthcount < minpicturebytes) { + samplefac = 1; + } + + alphadec = 30 + (samplefac - 1) / 3; + p = thepicture; + pix = 0; + lim = lengthcount; + samplepixels = lengthcount / (3 * samplefac); + delta = samplepixels / ncycles | 0; + alpha = initalpha; + radius = initradius; + + rad = radius >> radiusbiasshift; + if (rad <= 1) { + rad = 0; + } + + for (i = 0; i < rad; i++) { + radpower[i] = alpha * ((rad * rad - i * i) * radbias / (rad * rad)); + } + + if (lengthcount < minpicturebytes) { + step = 3; + } else if (lengthcount % prime1 !== 0) { + step = 3 * prime1; + } else { + + if (lengthcount % prime2 !== 0) { + step = 3 * prime2; + } else { + if (lengthcount % prime3 !== 0) { + step = 3 * prime3; + } else { + step = 3 * prime4; + } + } + } + + i = 0; + + while (i < samplepixels) { + + b = (p[pix + 0] & 0xff) << netbiasshift; + g = (p[pix + 1] & 0xff) << netbiasshift; + r = (p[pix + 2] & 0xff) << netbiasshift; + j = contest(b, g, r); + + altersingle(alpha, j, b, g, r); + + if (rad !== 0) { + // Alter neighbours + alterneigh(rad, j, b, g, r); + } + + pix += step; + + if (pix >= lim) { + pix -= lengthcount; + } + + i++; + + if (delta === 0) { + delta = 1; + } + + if (i % delta === 0) { + alpha -= alpha / alphadec; + radius -= radius / radiusdec; + rad = radius >> radiusbiasshift; + + if (rad <= 1) { + rad = 0; + } + + for (j = 0; j < rad; j++) { + radpower[j] = alpha * ((rad * rad - j * j) * radbias / (rad * rad)); + } + } + } + } + + // Search for BGR values 0..255 (after net is unbiased) and return colour index + function map(b, g, r) { + var i; + var j; + var dist; + var a; + var bestd; + var p; + var best; + + // Biggest possible distance is 256 * 3 + bestd = 1000; + best = -1; + i = netindex[g]; // index on g + j = i - 1; // start at netindex[g] and work outwards + + while (i < netsize || j >= 0) { + + if (i < netsize) { + + p = network[i]; + + dist = p[1] - g; // inx key + + if (dist >= bestd) { + i = netsize; // stop iter + } else { + + i++; + + if (dist < 0) { + dist = -dist; + } + + a = p[0] - b; + + if (a < 0) { + a = -a; + } + + dist += a; + + if (dist < bestd) { + a = p[2] - r; + + if (a < 0) { + a = -a; + } + + dist += a; + + if (dist < bestd) { + bestd = dist; + best = p[3]; + } + } + } + } + + if (j >= 0) { + + p = network[j]; + + dist = g - p[1]; // inx key - reverse dif + + if (dist >= bestd) { + j = -1; // stop iter + } else { + + j--; + if (dist < 0) { + dist = -dist; + } + a = p[0] - b; + if (a < 0) { + a = -a; + } + dist += a; + + if (dist < bestd) { + a = p[2] - r; + if (a < 0) { + a = -a; + } + dist += a; + if (dist < bestd) { + bestd = dist; + best = p[3]; + } + } + } + } + } + + return best; + } + + function process() { + learn(); + unbiasnet(); + inxbuild(); + return colorMap(); + } + + // Unbias network to give byte values 0..255 and record position i + // to prepare for sort + function unbiasnet() { + var i; + var j; + + for (i = 0; i < netsize; i++) { + network[i][0] >>= netbiasshift; + network[i][1] >>= netbiasshift; + network[i][2] >>= netbiasshift; + network[i][3] = i; // record colour no + } + } + + // Move adjacent neurons by precomputed alpha*(1-((i-j)^2/[r]^2)) + // in radpower[|i-j|] + function alterneigh(rad, i, b, g, r) { + + var j; + var k; + var lo; + var hi; + var a; + var m; + + var p; + + lo = i - rad; + if (lo < -1) { + lo = -1; + } + + hi = i + rad; + + if (hi > netsize) { + hi = netsize; + } + + j = i + 1; + k = i - 1; + m = 1; + + while (j < hi || k > lo) { + + a = radpower[m++]; + + if (j < hi) { + + p = network[j++]; + + try { + + p[0] -= a * (p[0] - b) / alpharadbias | 0; + p[1] -= a * (p[1] - g) / alpharadbias | 0; + p[2] -= a * (p[2] - r) / alpharadbias | 0; + } catch (e) {} + } + + if (k > lo) { + + p = network[k--]; + + try { + + p[0] -= a * (p[0] - b) / alpharadbias | 0; + p[1] -= a * (p[1] - g) / alpharadbias | 0; + p[2] -= a * (p[2] - r) / alpharadbias | 0; + } catch (e) {} + } + } + } + + // Move neuron i towards biased (b,g,r) by factor alpha + function altersingle(alpha, i, b, g, r) { + + // alter hit neuron + var n = network[i]; + var alphaMult = alpha / initalpha; + n[0] -= alphaMult * (n[0] - b) | 0; + n[1] -= alphaMult * (n[1] - g) | 0; + n[2] -= alphaMult * (n[2] - r) | 0; + } + + // Search for biased BGR values + function contest(b, g, r) { + + // finds closest neuron (min dist) and updates freq + // finds best neuron (min dist-bias) and returns position + // for frequently chosen neurons, freq[i] is high and bias[i] is negative + // bias[i] = gamma*((1/netsize)-freq[i]) + + var i; + var dist; + var a; + var biasdist; + var betafreq; + var bestpos; + var bestbiaspos; + var bestd; + var bestbiasd; + var n; + + bestd = ~(1 << 31); + bestbiasd = bestd; + bestpos = -1; + bestbiaspos = bestpos; + + for (i = 0; i < netsize; i++) { + + n = network[i]; + dist = n[0] - b; + + if (dist < 0) { + dist = -dist; + } + + a = n[1] - g; + + if (a < 0) { + a = -a; + } + + dist += a; + + a = n[2] - r; + + if (a < 0) { + a = -a; + } + + dist += a; + + if (dist < bestd) { + bestd = dist; + bestpos = i; + } + + biasdist = dist - (bias[i] >> intbiasshift - netbiasshift); + + if (biasdist < bestbiasd) { + bestbiasd = biasdist; + bestbiaspos = i; + } + + betafreq = freq[i] >> betashift; + freq[i] -= betafreq; + bias[i] += betafreq << gammashift; + } + + freq[bestpos] += beta; + bias[bestpos] -= betagamma; + return bestbiaspos; + } + + NeuQuantConstructor.apply(this, arguments); + + var exports = {}; + exports.map = map; + exports.process = process; + + return exports; +} + +/* + processFrameWorker.js + ===================== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +function workerCode() { + var self = this; + + try { + self.onmessage = function (ev) { + var data = ev.data || {}; + var response; + + if (data.gifshot) { + response = workerMethods.run(data); + postMessage(response); + } + }; + } catch (e) {} + + var workerMethods = { + dataToRGB: function dataToRGB(data, width, height) { + var length = width * height * 4; + var i = 0; + var rgb = []; + + while (i < length) { + rgb.push(data[i++]); + rgb.push(data[i++]); + rgb.push(data[i++]); + i++; // for the alpha channel which we don't care about + } + + return rgb; + }, + componentizedPaletteToArray: function componentizedPaletteToArray(paletteRGB) { + paletteRGB = paletteRGB || []; + + var paletteArray = []; + + for (var i = 0; i < paletteRGB.length; i += 3) { + var r = paletteRGB[i]; + var g = paletteRGB[i + 1]; + var b = paletteRGB[i + 2]; + + paletteArray.push(r << 16 | g << 8 | b); + } + + return paletteArray; + }, + // This is the "traditional" Animated_GIF style of going from RGBA to indexed color frames + 'processFrameWithQuantizer': function processFrameWithQuantizer(imageData, width, height, sampleInterval) { + var rgbComponents = this.dataToRGB(imageData, width, height); + var nq = new NeuQuant(rgbComponents, rgbComponents.length, sampleInterval); + var paletteRGB = nq.process(); + var paletteArray = new Uint32Array(this.componentizedPaletteToArray(paletteRGB)); + var numberPixels = width * height; + var indexedPixels = new Uint8Array(numberPixels); + var k = 0; + + for (var i = 0; i < numberPixels; i++) { + var r = rgbComponents[k++]; + var g = rgbComponents[k++]; + var b = rgbComponents[k++]; + + indexedPixels[i] = nq.map(r, g, b); + } + + return { + pixels: indexedPixels, + palette: paletteArray + }; + }, + 'run': function run(frame) { + frame = frame || {}; + + var _frame = frame, + height = _frame.height, + palette = _frame.palette, + sampleInterval = _frame.sampleInterval, + width = _frame.width; + + var imageData = frame.data; + + return this.processFrameWithQuantizer(imageData, width, height, sampleInterval); + } + }; + + return workerMethods; +} + +/* + gifWriter.js + ============ +*/ + +// (c) Dean McNamee , 2013. +// +// https://github.com/deanm/omggif +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// omggif is a JavaScript implementation of a GIF 89a encoder and decoder, +// including animation and compression. It does not rely on any specific +// underlying system, so should run in the browser, Node, or Plask. + +function gifWriter(buf, width, height, gopts) { + var p = 0; + + gopts = gopts === undefined ? {} : gopts; + var loop_count = gopts.loop === undefined ? null : gopts.loop; + var global_palette = gopts.palette === undefined ? null : gopts.palette; + + if (width <= 0 || height <= 0 || width > 65535 || height > 65535) throw "Width/Height invalid."; + + function check_palette_and_num_colors(palette) { + var num_colors = palette.length; + + if (num_colors < 2 || num_colors > 256 || num_colors & num_colors - 1) throw "Invalid code/color length, must be power of 2 and 2 .. 256."; + return num_colors; + } + + // - Header. + buf[p++] = 0x47; + buf[p++] = 0x49; + buf[p++] = 0x46; // GIF + buf[p++] = 0x38; + buf[p++] = 0x39; + buf[p++] = 0x61; // 89a + + // Handling of Global Color Table (palette) and background index. + var gp_num_colors_pow2 = 0; + var background = 0; + + // - Logical Screen Descriptor. + // NOTE(deanm): w/h apparently ignored by implementations, but set anyway. + buf[p++] = width & 0xff; + buf[p++] = width >> 8 & 0xff; + buf[p++] = height & 0xff; + buf[p++] = height >> 8 & 0xff; + // NOTE: Indicates 0-bpp original color resolution (unused?). + buf[p++] = (global_palette !== null ? 0x80 : 0) | // Global Color Table Flag. + gp_num_colors_pow2; // NOTE: No sort flag (unused?). + buf[p++] = background; // Background Color Index. + buf[p++] = 0; // Pixel aspect ratio (unused?). + + if (loop_count !== null) { + // Netscape block for looping. + if (loop_count < 0 || loop_count > 65535) throw "Loop count invalid."; + + // Extension code, label, and length. + buf[p++] = 0x21; + buf[p++] = 0xff; + buf[p++] = 0x0b; + // NETSCAPE2.0 + buf[p++] = 0x4e; + buf[p++] = 0x45; + buf[p++] = 0x54; + buf[p++] = 0x53; + buf[p++] = 0x43; + buf[p++] = 0x41; + buf[p++] = 0x50; + buf[p++] = 0x45; + buf[p++] = 0x32; + buf[p++] = 0x2e; + buf[p++] = 0x30; + // Sub-block + buf[p++] = 0x03; + buf[p++] = 0x01; + buf[p++] = loop_count & 0xff; + buf[p++] = loop_count >> 8 & 0xff; + buf[p++] = 0x00; // Terminator. + } + + var ended = false; + + this.addFrame = function (x, y, w, h, indexed_pixels, opts) { + if (ended === true) { + --p; + ended = false; + } // Un-end. + + opts = opts === undefined ? {} : opts; + + // TODO(deanm): Bounds check x, y. Do they need to be within the virtual + // canvas width/height, I imagine? + if (x < 0 || y < 0 || x > 65535 || y > 65535) throw "x/y invalid."; + + if (w <= 0 || h <= 0 || w > 65535 || h > 65535) throw "Width/Height invalid."; + + if (indexed_pixels.length < w * h) throw "Not enough pixels for the frame size."; + + var using_local_palette = true; + var palette = opts.palette; + if (palette === undefined || palette === null) { + using_local_palette = false; + palette = global_palette; + } + + if (palette === undefined || palette === null) throw "Must supply either a local or global palette."; + + var num_colors = check_palette_and_num_colors(palette); + + // Compute the min_code_size (power of 2), destroying num_colors. + var min_code_size = 0; + while (num_colors >>= 1) { + ++min_code_size; + }num_colors = 1 << min_code_size; // Now we can easily get it back. + + var delay = opts.delay === undefined ? 0 : opts.delay; + + // From the spec: + // 0 - No disposal specified. The decoder is + // not required to take any action. + // 1 - Do not dispose. The graphic is to be left + // in place. + // 2 - Restore to background color. The area used by the + // graphic must be restored to the background color. + // 3 - Restore to previous. The decoder is required to + // restore the area overwritten by the graphic with + // what was there prior to rendering the graphic. + // 4-7 - To be defined. + // NOTE(deanm): Dispose background doesn't really work, apparently most + // browsers ignore the background palette index and clear to transparency. + var disposal = opts.disposal === undefined ? 0 : opts.disposal; + if (disposal < 0 || disposal > 3) // 4-7 is reserved. + throw "Disposal out of range."; + + var use_transparency = false; + var transparent_index = 0; + if (opts.transparent !== undefined && opts.transparent !== null) { + use_transparency = true; + transparent_index = opts.transparent; + if (transparent_index < 0 || transparent_index >= num_colors) throw "Transparent color index."; + } + + if (disposal !== 0 || use_transparency || delay !== 0) { + // - Graphics Control Extension + buf[p++] = 0x21; + buf[p++] = 0xf9; // Extension / Label. + buf[p++] = 4; // Byte size. + + buf[p++] = disposal << 2 | (use_transparency === true ? 1 : 0); + buf[p++] = delay & 0xff; + buf[p++] = delay >> 8 & 0xff; + buf[p++] = transparent_index; // Transparent color index. + buf[p++] = 0; // Block Terminator. + } + + // - Image Descriptor + buf[p++] = 0x2c; // Image Seperator. + buf[p++] = x & 0xff; + buf[p++] = x >> 8 & 0xff; // Left. + buf[p++] = y & 0xff; + buf[p++] = y >> 8 & 0xff; // Top. + buf[p++] = w & 0xff; + buf[p++] = w >> 8 & 0xff; + buf[p++] = h & 0xff; + buf[p++] = h >> 8 & 0xff; + // NOTE: No sort flag (unused?). + // TODO(deanm): Support interlace. + buf[p++] = using_local_palette === true ? 0x80 | min_code_size - 1 : 0; + + // - Local Color Table + if (using_local_palette === true) { + for (var i = 0, il = palette.length; i < il; ++i) { + var rgb = palette[i]; + buf[p++] = rgb >> 16 & 0xff; + buf[p++] = rgb >> 8 & 0xff; + buf[p++] = rgb & 0xff; + } + } + + p = GifWriterOutputLZWCodeStream(buf, p, min_code_size < 2 ? 2 : min_code_size, indexed_pixels); + }; + + this.end = function () { + if (ended === false) { + buf[p++] = 0x3b; // Trailer. + ended = true; + } + return p; + }; + + // Main compression routine, palette indexes -> LZW code stream. + // |index_stream| must have at least one entry. + function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) { + buf[p++] = min_code_size; + var cur_subblock = p++; // Pointing at the length field. + + var clear_code = 1 << min_code_size; + var code_mask = clear_code - 1; + var eoi_code = clear_code + 1; + var next_code = eoi_code + 1; + + var cur_code_size = min_code_size + 1; // Number of bits per code. + var cur_shift = 0; + // We have at most 12-bit codes, so we should have to hold a max of 19 + // bits here (and then we would write out). + var cur = 0; + + function emit_bytes_to_buffer(bit_block_size) { + while (cur_shift >= bit_block_size) { + buf[p++] = cur & 0xff; + cur >>= 8; + cur_shift -= 8; + if (p === cur_subblock + 256) { + // Finished a subblock. + buf[cur_subblock] = 255; + cur_subblock = p++; + } + } + } + + function emit_code(c) { + cur |= c << cur_shift; + cur_shift += cur_code_size; + emit_bytes_to_buffer(8); + } + + // I am not an expert on the topic, and I don't want to write a thesis. + // However, it is good to outline here the basic algorithm and the few data + // structures and optimizations here that make this implementation fast. + // The basic idea behind LZW is to build a table of previously seen runs + // addressed by a short id (herein called output code). All data is + // referenced by a code, which represents one or more values from the + // original input stream. All input bytes can be referenced as the same + // value as an output code. So if you didn't want any compression, you + // could more or less just output the original bytes as codes (there are + // some details to this, but it is the idea). In order to achieve + // compression, values greater then the input range (codes can be up to + // 12-bit while input only 8-bit) represent a sequence of previously seen + // inputs. The decompressor is able to build the same mapping while + // decoding, so there is always a shared common knowledge between the + // encoding and decoder, which is also important for "timing" aspects like + // how to handle variable bit width code encoding. + // + // One obvious but very important consequence of the table system is there + // is always a unique id (at most 12-bits) to map the runs. 'A' might be + // 4, then 'AA' might be 10, 'AAA' 11, 'AAAA' 12, etc. This relationship + // can be used for an effecient lookup strategy for the code mapping. We + // need to know if a run has been seen before, and be able to map that run + // to the output code. Since we start with known unique ids (input bytes), + // and then from those build more unique ids (table entries), we can + // continue this chain (almost like a linked list) to always have small + // integer values that represent the current byte chains in the encoder. + // This means instead of tracking the input bytes (AAAABCD) to know our + // current state, we can track the table entry for AAAABC (it is guaranteed + // to exist by the nature of the algorithm) and the next character D. + // Therefor the tuple of (table_entry, byte) is guaranteed to also be + // unique. This allows us to create a simple lookup key for mapping input + // sequences to codes (table indices) without having to store or search + // any of the code sequences. So if 'AAAA' has a table entry of 12, the + // tuple of ('AAAA', K) for any input byte K will be unique, and can be our + // key. This leads to a integer value at most 20-bits, which can always + // fit in an SMI value and be used as a fast sparse array / object key. + + // Output code for the current contents of the index buffer. + var ib_code = index_stream[0] & code_mask; // Load first input index. + var code_table = {}; // Key'd on our 20-bit "tuple". + + emit_code(clear_code); // Spec says first code should be a clear code. + + // First index already loaded, process the rest of the stream. + for (var i = 1, il = index_stream.length; i < il; ++i) { + var k = index_stream[i] & code_mask; + var cur_key = ib_code << 8 | k; // (prev, k) unique tuple. + var cur_code = code_table[cur_key]; // buffer + k. + + // Check if we have to create a new code table entry. + if (cur_code === undefined) { + // We don't have buffer + k. + // Emit index buffer (without k). + // This is an inline version of emit_code, because this is the core + // writing routine of the compressor (and V8 cannot inline emit_code + // because it is a closure here in a different context). Additionally + // we can call emit_byte_to_buffer less often, because we can have + // 30-bits (from our 31-bit signed SMI), and we know our codes will only + // be 12-bits, so can safely have 18-bits there without overflow. + // emit_code(ib_code); + cur |= ib_code << cur_shift; + cur_shift += cur_code_size; + while (cur_shift >= 8) { + buf[p++] = cur & 0xff; + cur >>= 8; + cur_shift -= 8; + if (p === cur_subblock + 256) { + // Finished a subblock. + buf[cur_subblock] = 255; + cur_subblock = p++; + } + } + + if (next_code === 4096) { + // Table full, need a clear. + emit_code(clear_code); + next_code = eoi_code + 1; + cur_code_size = min_code_size + 1; + code_table = {}; + } else { + // Table not full, insert a new entry. + // Increase our variable bit code sizes if necessary. This is a bit + // tricky as it is based on "timing" between the encoding and + // decoder. From the encoders perspective this should happen after + // we've already emitted the index buffer and are about to create the + // first table entry that would overflow our current code bit size. + if (next_code >= 1 << cur_code_size) ++cur_code_size; + code_table[cur_key] = next_code++; // Insert into code table. + } + + ib_code = k; // Index buffer to single input k. + } else { + ib_code = cur_code; // Index buffer to sequence in code table. + } + } + + emit_code(ib_code); // There will still be something in the index buffer. + emit_code(eoi_code); // End Of Information. + + // Flush / finalize the sub-blocks stream to the buffer. + emit_bytes_to_buffer(1); + + // Finish the sub-blocks, writing out any unfinished lengths and + // terminating with a sub-block of length 0. If we have already started + // but not yet used a sub-block it can just become the terminator. + if (cur_subblock + 1 === p) { + // Started but unused. + buf[cur_subblock] = 0; + } else { + // Started and used, write length and additional terminator block. + buf[cur_subblock] = p - cur_subblock - 1; + buf[p++] = 0; + } + return p; + } +} + +/* + animatedGIF.js + ============== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +// Helpers +var noop$2 = function noop() {}; + +var AnimatedGIF = function AnimatedGIF(options) { + this.canvas = null; + this.ctx = null; + this.repeat = 0; + this.frames = []; + this.numRenderedFrames = 0; + this.onRenderCompleteCallback = noop$2; + this.onRenderProgressCallback = noop$2; + this.workers = []; + this.availableWorkers = []; + this.generatingGIF = false; + this.options = options; + + // Constructs and initializes the the web workers appropriately + this.initializeWebWorkers(options); +}; + +AnimatedGIF.prototype = { + 'workerMethods': workerCode(), + 'initializeWebWorkers': function initializeWebWorkers(options) { + var self = this; + var processFrameWorkerCode = NeuQuant.toString() + '(' + workerCode.toString() + '());'; + var webWorkerObj = void 0; + var objectUrl = void 0; + var webWorker = void 0; + var numWorkers = void 0; + var x = -1; + var workerError = ''; + + numWorkers = options.numWorkers; + + while (++x < numWorkers) { + webWorkerObj = utils.createWebWorker(processFrameWorkerCode); + + if (utils.isObject(webWorkerObj)) { + objectUrl = webWorkerObj.objectUrl; + webWorker = webWorkerObj.worker; + + self.workers.push({ + worker: webWorker, + objectUrl: objectUrl + }); + + self.availableWorkers.push(webWorker); + } else { + workerError = webWorkerObj; + utils.webWorkerError = !!webWorkerObj; + } + } + + this.workerError = workerError; + this.canvas = document.createElement('canvas'); + this.canvas.width = options.gifWidth; + this.canvas.height = options.gifHeight; + this.ctx = this.canvas.getContext('2d'); + this.frames = []; + }, + // Return a worker for processing a frame + getWorker: function getWorker() { + return this.availableWorkers.pop(); + }, + // Restores a worker to the pool + freeWorker: function freeWorker(worker) { + this.availableWorkers.push(worker); + }, + byteMap: function () { + var byteMap = []; + + for (var i = 0; i < 256; i++) { + byteMap[i] = String.fromCharCode(i); + } + + return byteMap; + }(), + bufferToString: function bufferToString(buffer) { + var numberValues = buffer.length; + var str = ''; + var x = -1; + + while (++x < numberValues) { + str += this.byteMap[buffer[x]]; + } + + return str; + }, + onFrameFinished: function onFrameFinished(progressCallback) { + // The GIF is not written until we're done with all the frames + // because they might not be processed in the same order + var self = this; + var frames = self.frames; + var options = self.options; + var hasExistingImages = !!(options.images || []).length; + var allDone = frames.every(function (frame) { + return !frame.beingProcessed && frame.done; + }); + + self.numRenderedFrames++; + + if (hasExistingImages) { + progressCallback(self.numRenderedFrames / frames.length); + } + + self.onRenderProgressCallback(self.numRenderedFrames * 0.75 / frames.length); + + if (allDone) { + if (!self.generatingGIF) { + self.generateGIF(frames, self.onRenderCompleteCallback); + } + } else { + utils.requestTimeout(function () { + self.processNextFrame(); + }, 1); + } + }, + processFrame: function processFrame(position) { + var AnimatedGifContext = this; + var options = this.options; + var _options = this.options, + progressCallback = _options.progressCallback, + sampleInterval = _options.sampleInterval; + + var frames = this.frames; + var frame = void 0; + var worker = void 0; + var done = function done() { + var ev = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var data = ev.data; + + // Delete original data, and free memory + delete frame.data; + + frame.pixels = Array.prototype.slice.call(data.pixels); + frame.palette = Array.prototype.slice.call(data.palette); + frame.done = true; + frame.beingProcessed = false; + + AnimatedGifContext.freeWorker(worker); + + AnimatedGifContext.onFrameFinished(progressCallback); + }; + + frame = frames[position]; + + if (frame.beingProcessed || frame.done) { + this.onFrameFinished(); + + return; + } + + frame.sampleInterval = sampleInterval; + frame.beingProcessed = true; + frame.gifshot = true; + + worker = this.getWorker(); + + if (worker) { + // Process the frame in a web worker + worker.onmessage = done; + worker.postMessage(frame); + } else { + // Process the frame in the current thread + done({ + 'data': AnimatedGifContext.workerMethods.run(frame) + }); + } + }, + startRendering: function startRendering(completeCallback) { + this.onRenderCompleteCallback = completeCallback; + + for (var i = 0; i < this.options.numWorkers && i < this.frames.length; i++) { + this.processFrame(i); + } + }, + processNextFrame: function processNextFrame() { + var position = -1; + + for (var i = 0; i < this.frames.length; i++) { + var frame = this.frames[i]; + + if (!frame.done && !frame.beingProcessed) { + position = i; + break; + } + } + + if (position >= 0) { + this.processFrame(position); + } + }, + // Takes the already processed data in frames and feeds it to a new + // GifWriter instance in order to get the binary GIF file + generateGIF: function generateGIF(frames, callback) { + // TODO: Weird: using a simple JS array instead of a typed array, + // the files are WAY smaller o_o. Patches/explanations welcome! + var buffer = []; // new Uint8Array(width * height * frames.length * 5); + var gifOptions = { + loop: this.repeat + }; + var options = this.options; + var interval = options.interval; + + var frameDuration = options.frameDuration; + var existingImages = options.images; + var hasExistingImages = !!existingImages.length; + var height = options.gifHeight; + var width = options.gifWidth; + var gifWriter$$1 = new gifWriter(buffer, width, height, gifOptions); + var onRenderProgressCallback = this.onRenderProgressCallback; + var delay = hasExistingImages ? interval * 100 : 0; + var bufferToString = void 0; + var gif = void 0; + + this.generatingGIF = true; + + utils.each(frames, function (iterator, frame) { + var framePalette = frame.palette; + + onRenderProgressCallback(0.75 + 0.25 * frame.position * 1.0 / frames.length); + + for (var i = 0; i < frameDuration; i++) { + gifWriter$$1.addFrame(0, 0, width, height, frame.pixels, { + palette: framePalette, + delay: delay + }); + } + }); + + gifWriter$$1.end(); + + onRenderProgressCallback(1.0); + + this.frames = []; + + this.generatingGIF = false; + + if (utils.isFunction(callback)) { + bufferToString = this.bufferToString(buffer); + gif = 'data:image/gif;base64,' + utils.btoa(bufferToString); + + callback(gif); + } + }, + // From GIF: 0 = loop forever, null = not looping, n > 0 = loop n times and stop + setRepeat: function setRepeat(r) { + this.repeat = r; + }, + addFrame: function addFrame(element, gifshotOptions) { + gifshotOptions = utils.isObject(gifshotOptions) ? gifshotOptions : {}; + + var self = this; + var ctx = self.ctx; + var options = self.options; + var width = options.gifWidth; + var height = options.gifHeight; + var fontSize = utils.getFontSize(gifshotOptions); + var _gifshotOptions = gifshotOptions, + filter = _gifshotOptions.filter, + fontColor = _gifshotOptions.fontColor, + fontFamily = _gifshotOptions.fontFamily, + fontWeight = _gifshotOptions.fontWeight, + gifHeight = _gifshotOptions.gifHeight, + gifWidth = _gifshotOptions.gifWidth, + text = _gifshotOptions.text, + textAlign = _gifshotOptions.textAlign, + textBaseline = _gifshotOptions.textBaseline; + + var textXCoordinate = gifshotOptions.textXCoordinate ? gifshotOptions.textXCoordinate : textAlign === 'left' ? 1 : textAlign === 'right' ? width : width / 2; + var textYCoordinate = gifshotOptions.textYCoordinate ? gifshotOptions.textYCoordinate : textBaseline === 'top' ? 1 : textBaseline === 'center' ? height / 2 : height; + var font = fontWeight + ' ' + fontSize + ' ' + fontFamily; + var imageData = void 0; + + try { + ctx.filter = filter; + + ctx.drawImage(element, 0, 0, width, height); + + if (text) { + ctx.font = font; + ctx.fillStyle = fontColor; + ctx.textAlign = textAlign; + ctx.textBaseline = textBaseline; + ctx.fillText(text, textXCoordinate, textYCoordinate); + } + + imageData = ctx.getImageData(0, 0, width, height); + + self.addFrameImageData(imageData); + } catch (e) { + return '' + e; + } + }, + addFrameImageData: function addFrameImageData() { + var imageData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var frames = this.frames; + var imageDataArray = imageData.data; + + this.frames.push({ + 'data': imageDataArray, + 'width': imageData.width, + 'height': imageData.height, + 'palette': null, + 'dithering': null, + 'done': false, + 'beingProcessed': false, + 'position': frames.length + }); + }, + onRenderProgress: function onRenderProgress(callback) { + this.onRenderProgressCallback = callback; + }, + isRendering: function isRendering() { + return this.generatingGIF; + }, + getBase64GIF: function getBase64GIF(completeCallback) { + var self = this; + var onRenderComplete = function onRenderComplete(gif) { + self.destroyWorkers(); + + utils.requestTimeout(function () { + completeCallback(gif); + }, 0); + }; + + self.startRendering(onRenderComplete); + }, + destroyWorkers: function destroyWorkers() { + if (this.workerError) { + return; + } + + var workers = this.workers; + + // Explicitly ask web workers to die so they are explicitly GC'ed + utils.each(workers, function (iterator, workerObj) { + var worker = workerObj.worker; + var objectUrl = workerObj.objectUrl; + + worker.terminate(); + utils.URL.revokeObjectURL(objectUrl); + }); + } +}; + +/* + getBase64GIF.js + =============== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +function getBase64GIF(animatedGifInstance, callback) { + // This is asynchronous, rendered with WebWorkers + animatedGifInstance.getBase64GIF(function (image) { + callback({ + error: false, + errorCode: '', + errorMsg: '', + image: image + }); + }); +} + +/* + existingImages.js + ================= +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +function existingImages() { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var self = this; + var callback = obj.callback, + images = obj.images, + options = obj.options; + + var imagesLength = obj.imagesLength; + var skipObj = { + 'getUserMedia': true, + 'window.URL': true + }; + var errorObj = error.validate(skipObj); + var loadedImages = []; + var loadedImagesLength = 0; + var tempImage = void 0; + var ag = void 0; + + if (errorObj.error) { + return callback(errorObj); + } + + // change workerPath to point to where Animated_GIF.worker.js is + ag = new AnimatedGIF(options); + + utils.each(images, function (index, image) { + var currentImage = image; + + if (image.src) { + currentImage = currentImage.src; + } + if (utils.isElement(currentImage)) { + if (options.crossOrigin) { + currentImage.crossOrigin = options.crossOrigin; + } + + loadedImages[index] = currentImage; + loadedImagesLength += 1; + + if (loadedImagesLength === imagesLength) { + addLoadedImagesToGif(); + } + } else if (utils.isString(currentImage)) { + tempImage = new Image(); + + if (options.crossOrigin) { + tempImage.crossOrigin = options.crossOrigin; + } + + (function (tempImage) { + if (image.text) { + tempImage.text = image.text; + } + + tempImage.onerror = function (e) { + var obj = void 0; + + --imagesLength; // skips over images that error out + + if (imagesLength === 0) { + obj = {}; + obj.error = 'None of the requested images was capable of being retrieved'; + + return callback(obj); + } + }; + + tempImage.onload = function (e) { + if (image.text) { + loadedImages[index] = { + img: tempImage, + text: tempImage.text + }; + } else { + loadedImages[index] = tempImage; + } + + loadedImagesLength += 1; + + if (loadedImagesLength === imagesLength) { + addLoadedImagesToGif(); + } + + utils.removeElement(tempImage); + }; + + tempImage.src = currentImage; + })(tempImage); + + utils.setCSSAttr(tempImage, { + position: 'fixed', + opacity: '0' + }); + + document.body.appendChild(tempImage); + } + }); + + function addLoadedImagesToGif() { + utils.each(loadedImages, function (index, loadedImage) { + if (loadedImage) { + if (loadedImage.text) { + ag.addFrame(loadedImage.img, options, loadedImage.text); + } else { + ag.addFrame(loadedImage, options); + } + } + }); + + getBase64GIF(ag, callback); + } +} + +/* + screenShot.js + ============= +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +// Helpers +var noop$3 = function noop() {}; + +var screenShot = { + getGIF: function getGIF() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var callback = arguments[1]; + + callback = utils.isFunction(callback) ? callback : noop$3; + + var canvas = document.createElement('canvas'); + var context = void 0; + var existingImages = options.images; + var hasExistingImages = !!existingImages.length; + var cameraStream = options.cameraStream, + crop = options.crop, + filter = options.filter, + fontColor = options.fontColor, + fontFamily = options.fontFamily, + fontWeight = options.fontWeight, + keepCameraOn = options.keepCameraOn, + numWorkers = options.numWorkers, + progressCallback = options.progressCallback, + saveRenderingContexts = options.saveRenderingContexts, + savedRenderingContexts = options.savedRenderingContexts, + text = options.text, + textAlign = options.textAlign, + textBaseline = options.textBaseline, + videoElement = options.videoElement, + videoHeight = options.videoHeight, + videoWidth = options.videoWidth, + webcamVideoElement = options.webcamVideoElement; + + var gifWidth = Number(options.gifWidth); + var gifHeight = Number(options.gifHeight); + var interval = Number(options.interval); + var sampleInterval = Number(options.sampleInterval); + var waitBetweenFrames = hasExistingImages ? 0 : interval * 1000; + var renderingContextsToSave = []; + var numFrames = savedRenderingContexts.length ? savedRenderingContexts.length : options.numFrames; + var pendingFrames = numFrames; + var ag = new AnimatedGIF(options); + var fontSize = utils.getFontSize(options); + var textXCoordinate = options.textXCoordinate ? options.textXCoordinate : textAlign === 'left' ? 1 : textAlign === 'right' ? gifWidth : gifWidth / 2; + var textYCoordinate = options.textYCoordinate ? options.textYCoordinate : textBaseline === 'top' ? 1 : textBaseline === 'center' ? gifHeight / 2 : gifHeight; + var font = fontWeight + ' ' + fontSize + ' ' + fontFamily; + var sourceX = crop ? Math.floor(crop.scaledWidth / 2) : 0; + var sourceWidth = crop ? videoWidth - crop.scaledWidth : 0; + var sourceY = crop ? Math.floor(crop.scaledHeight / 2) : 0; + var sourceHeight = crop ? videoHeight - crop.scaledHeight : 0; + var captureFrames = function captureSingleFrame() { + var framesLeft = pendingFrames - 1; + + if (savedRenderingContexts.length) { + context.putImageData(savedRenderingContexts[numFrames - pendingFrames], 0, 0); + + finishCapture(); + } else { + drawVideo(); + } + + function drawVideo() { + try { + // Makes sure the canvas video heights/widths are in bounds + if (sourceWidth > videoWidth) { + sourceWidth = videoWidth; + } + + if (sourceHeight > videoHeight) { + sourceHeight = videoHeight; + } + + if (sourceX < 0) { + sourceX = 0; + } + + if (sourceY < 0) { + sourceY = 0; + } + + context.filter = filter; + + context.drawImage(videoElement, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, gifWidth, gifHeight); + + finishCapture(); + } catch (e) { + // There is a Firefox bug that sometimes throws NS_ERROR_NOT_AVAILABLE and + // and IndexSizeError errors when drawing a video element to the canvas + if (e.name === 'NS_ERROR_NOT_AVAILABLE') { + // Wait 100ms before trying again + utils.requestTimeout(drawVideo, 100); + } else { + throw e; + } + } + } + + function finishCapture() { + var imageData = void 0; + + if (saveRenderingContexts) { + renderingContextsToSave.push(context.getImageData(0, 0, gifWidth, gifHeight)); + } + + // If there is text to display, make sure to display it on the canvas after the image is drawn + if (text) { + context.font = font; + context.fillStyle = fontColor; + context.textAlign = textAlign; + context.textBaseline = textBaseline; + context.fillText(text, textXCoordinate, textYCoordinate); + } + + imageData = context.getImageData(0, 0, gifWidth, gifHeight); + + ag.addFrameImageData(imageData); + + pendingFrames = framesLeft; + + // Call back with an r value indicating how far along we are in capture + progressCallback((numFrames - pendingFrames) / numFrames); + + if (framesLeft > 0) { + // test + utils.requestTimeout(captureSingleFrame, waitBetweenFrames); + } + + if (!pendingFrames) { + ag.getBase64GIF(function (image) { + callback({ + 'error': false, + 'errorCode': '', + 'errorMsg': '', + 'image': image, + 'cameraStream': cameraStream, + 'videoElement': videoElement, + 'webcamVideoElement': webcamVideoElement, + 'savedRenderingContexts': renderingContextsToSave, + 'keepCameraOn': keepCameraOn + }); + }); + } + } + }; + + numFrames = numFrames !== undefined ? numFrames : 10; + interval = interval !== undefined ? interval : 0.1; // In seconds + + canvas.width = gifWidth; + canvas.height = gifHeight; + context = canvas.getContext('2d'); + + (function capture() { + if (!savedRenderingContexts.length && videoElement.currentTime === 0) { + utils.requestTimeout(capture, 100); + + return; + } + + captureFrames(); + })(); + }, + getCropDimensions: function getCropDimensions() { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + var width = obj.videoWidth; + var height = obj.videoHeight; + var gifWidth = obj.gifWidth; + var gifHeight = obj.gifHeight; + var result = { + width: 0, + height: 0, + scaledWidth: 0, + scaledHeight: 0 + }; + + if (width > height) { + result.width = Math.round(width * (gifHeight / height)) - gifWidth; + result.scaledWidth = Math.round(result.width * (height / gifHeight)); + } else { + result.height = Math.round(height * (gifWidth / width)) - gifHeight; + result.scaledHeight = Math.round(result.height * (width / gifWidth)); + } + + return result; + } +}; + +/* + videoStream.js + ============== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +var videoStream = { + loadedData: false, + defaultVideoDimensions: { + width: 640, + height: 480 + }, + findVideoSize: function findVideoSizeMethod(obj) { + findVideoSizeMethod.attempts = findVideoSizeMethod.attempts || 0; + + var cameraStream = obj.cameraStream, + completedCallback = obj.completedCallback, + videoElement = obj.videoElement; + + + if (!videoElement) { + return; + } + + if (videoElement.videoWidth > 0 && videoElement.videoHeight > 0) { + videoElement.removeEventListener('loadeddata', videoStream.findVideoSize); + + completedCallback({ + videoElement: videoElement, + cameraStream: cameraStream, + videoWidth: videoElement.videoWidth, + videoHeight: videoElement.videoHeight + }); + } else { + if (findVideoSizeMethod.attempts < 10) { + findVideoSizeMethod.attempts += 1; + + utils.requestTimeout(function () { + videoStream.findVideoSize(obj); + }, 400); + } else { + completedCallback({ + videoElement: videoElement, + cameraStream: cameraStream, + videoWidth: videoStream.defaultVideoDimensions.width, + videoHeight: videoStream.defaultVideoDimensions.height + }); + } + } + }, + onStreamingTimeout: function onStreamingTimeout(callback) { + if (utils.isFunction(callback)) { + callback({ + error: true, + errorCode: 'getUserMedia', + errorMsg: 'There was an issue with the getUserMedia API - Timed out while trying to start streaming', + image: null, + cameraStream: {} + }); + } + }, + stream: function stream(obj) { + var existingVideo = utils.isArray(obj.existingVideo) ? obj.existingVideo[0] : obj.existingVideo; + var cameraStream = obj.cameraStream, + completedCallback = obj.completedCallback, + streamedCallback = obj.streamedCallback, + videoElement = obj.videoElement; + + + if (utils.isFunction(streamedCallback)) { + streamedCallback(); + } + + if (existingVideo) { + if (utils.isString(existingVideo)) { + videoElement.src = existingVideo; + videoElement.innerHTML = ''; + } else if (existingVideo instanceof Blob) { + try { + videoElement.src = utils.URL.createObjectURL(existingVideo); + } catch (e) {} + + videoElement.innerHTML = ''; + } + } else if (videoElement.mozSrcObject) { + videoElement.mozSrcObject = cameraStream; + } else if (utils.URL) { + try { + videoElement.srcObject = cameraStream; + videoElement.src = utils.URL.createObjectURL(cameraStream); + } catch (e) { + videoElement.srcObject = cameraStream; + } + } + + videoElement.play(); + + utils.requestTimeout(function checkLoadedData() { + checkLoadedData.count = checkLoadedData.count || 0; + + if (videoStream.loadedData === true) { + videoStream.findVideoSize({ + videoElement: videoElement, + cameraStream: cameraStream, + completedCallback: completedCallback + }); + + videoStream.loadedData = false; + } else { + checkLoadedData.count += 1; + + if (checkLoadedData.count > 10) { + videoStream.findVideoSize({ + videoElement: videoElement, + cameraStream: cameraStream, + completedCallback: completedCallback + }); + } else { + checkLoadedData(); + } + } + }, 0); + }, + startStreaming: function startStreaming(obj) { + var errorCallback = utils.isFunction(obj.error) ? obj.error : utils.noop; + var streamedCallback = utils.isFunction(obj.streamed) ? obj.streamed : utils.noop; + var completedCallback = utils.isFunction(obj.completed) ? obj.completed : utils.noop; + var crossOrigin = obj.crossOrigin, + existingVideo = obj.existingVideo, + lastCameraStream = obj.lastCameraStream, + options = obj.options, + webcamVideoElement = obj.webcamVideoElement; + + var videoElement = utils.isElement(existingVideo) ? existingVideo : webcamVideoElement ? webcamVideoElement : document.createElement('video'); + var cameraStream = void 0; + + if (crossOrigin) { + videoElement.crossOrigin = options.crossOrigin; + } + + videoElement.autoplay = true; + videoElement.loop = true; + videoElement.muted = true; + videoElement.addEventListener('loadeddata', function (event) { + videoStream.loadedData = true; + if (options.offset) { + videoElement.currentTime = options.offset; + } + }); + + if (existingVideo) { + videoStream.stream({ + videoElement: videoElement, + existingVideo: existingVideo, + completedCallback: completedCallback + }); + } else if (lastCameraStream) { + videoStream.stream({ + videoElement: videoElement, + cameraStream: lastCameraStream, + streamedCallback: streamedCallback, + completedCallback: completedCallback + }); + } else { + utils.getUserMedia({ + video: true + }, function (stream) { + videoStream.stream({ + videoElement: videoElement, + cameraStream: stream, + streamedCallback: streamedCallback, + completedCallback: completedCallback + }); + }, errorCallback); + } + }, + startVideoStreaming: function startVideoStreaming(callback) { + var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + var timeoutLength = options.timeout !== undefined ? options.timeout : 0; + var originalCallback = options.callback; + var webcamVideoElement = options.webcamVideoElement; + var noGetUserMediaSupportTimeout = void 0; + + // Some browsers apparently have support for video streaming because of the + // presence of the getUserMedia function, but then do not answer our + // calls for streaming. + // So we'll set up this timeout and if nothing happens after a while, we'll + // conclude that there's no actual getUserMedia support. + if (timeoutLength > 0) { + noGetUserMediaSupportTimeout = utils.requestTimeout(function () { + videoStream.onStreamingTimeout(originalCallback); + }, 10000); + } + + videoStream.startStreaming({ + error: function error() { + originalCallback({ + error: true, + errorCode: 'getUserMedia', + errorMsg: 'There was an issue with the getUserMedia API - the user probably denied permission', + image: null, + cameraStream: {} + }); + }, + streamed: function streamed() { + // The streaming started somehow, so we can assume there is getUserMedia support + clearTimeout(noGetUserMediaSupportTimeout); + }, + completed: function completed() { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var cameraStream = obj.cameraStream, + videoElement = obj.videoElement, + videoHeight = obj.videoHeight, + videoWidth = obj.videoWidth; + + + callback({ + cameraStream: cameraStream, + videoElement: videoElement, + videoHeight: videoHeight, + videoWidth: videoWidth + }); + }, + lastCameraStream: options.lastCameraStream, + webcamVideoElement: webcamVideoElement, + crossOrigin: options.crossOrigin, + options: options + }); + }, + stopVideoStreaming: function stopVideoStreaming(obj) { + obj = utils.isObject(obj) ? obj : {}; + + var _obj = obj, + keepCameraOn = _obj.keepCameraOn, + videoElement = _obj.videoElement, + webcamVideoElement = _obj.webcamVideoElement; + + var cameraStream = obj.cameraStream || {}; + var cameraStreamTracks = cameraStream.getTracks ? cameraStream.getTracks() || [] : []; + var hasCameraStreamTracks = !!cameraStreamTracks.length; + var firstCameraStreamTrack = cameraStreamTracks[0]; + + if (!keepCameraOn && hasCameraStreamTracks) { + if (utils.isFunction(firstCameraStreamTrack.stop)) { + // Stops the camera stream + firstCameraStreamTrack.stop(); + } + } + + if (utils.isElement(videoElement) && !webcamVideoElement) { + // Pauses the video, revokes the object URL (freeing up memory), and remove the video element + videoElement.pause(); + + // Destroys the object url + if (utils.isFunction(utils.URL.revokeObjectURL) && !utils.webWorkerError) { + if (videoElement.src) { + utils.URL.revokeObjectURL(videoElement.src); + } + } + + // Removes the video element from the DOM + utils.removeElement(videoElement); + } + } +}; + +/* + stopVideoStreaming.js + ===================== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +function stopVideoStreaming(options) { + options = utils.isObject(options) ? options : {}; + + videoStream.stopVideoStreaming(options); +} + +/* + createAndGetGIF.js + ================== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +function createAndGetGIF(obj, callback) { + var options = obj.options || {}; + + var images = options.images, + video = options.video; + + var gifWidth = Number(options.gifWidth); + var gifHeight = Number(options.gifHeight); + var numFrames = Number(options.numFrames); + var cameraStream = obj.cameraStream, + videoElement = obj.videoElement, + videoWidth = obj.videoWidth, + videoHeight = obj.videoHeight; + + var cropDimensions = screenShot.getCropDimensions({ + videoWidth: videoWidth, + videoHeight: videoHeight, + gifHeight: gifHeight, + gifWidth: gifWidth + }); + var completeCallback = callback; + + options.crop = cropDimensions; + options.videoElement = videoElement; + options.videoWidth = videoWidth; + options.videoHeight = videoHeight; + options.cameraStream = cameraStream; + + if (!utils.isElement(videoElement)) { + return; + } + + videoElement.width = gifWidth + cropDimensions.width; + videoElement.height = gifHeight + cropDimensions.height; + + if (!options.webcamVideoElement) { + utils.setCSSAttr(videoElement, { + position: 'fixed', + opacity: '0' + }); + + document.body.appendChild(videoElement); + } + + // Firefox doesn't seem to obey autoplay if the element is not in the DOM when the content + // is loaded, so we must manually trigger play after adding it, or the video will be frozen + videoElement.play(); + + screenShot.getGIF(options, function (obj) { + if ((!images || !images.length) && (!video || !video.length)) { + stopVideoStreaming(obj); + } + + completeCallback(obj); + }); +} + +/* + existingVideo.js + ================ +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +function existingVideo() { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var callback = obj.callback, + existingVideo = obj.existingVideo, + options = obj.options; + + var skipObj = { + getUserMedia: true, + 'window.URL': true + }; + var errorObj = error.validate(skipObj); + var loadedImages = 0; + var videoType = void 0; + var videoSrc = void 0; + var tempImage = void 0; + var ag = void 0; + + if (errorObj.error) { + return callback(errorObj); + } + + if (utils.isElement(existingVideo) && existingVideo.src) { + videoSrc = existingVideo.src; + videoType = utils.getExtension(videoSrc); + + if (!utils.isSupported.videoCodecs[videoType]) { + return callback(error.messages.videoCodecs); + } + } else if (utils.isArray(existingVideo)) { + utils.each(existingVideo, function (iterator, videoSrc) { + if (videoSrc instanceof Blob) { + videoType = videoSrc.type.substr(videoSrc.type.lastIndexOf('/') + 1, videoSrc.length); + } else { + videoType = videoSrc.substr(videoSrc.lastIndexOf('.') + 1, videoSrc.length); + } + + if (utils.isSupported.videoCodecs[videoType]) { + existingVideo = videoSrc; + + return false; + } + }); + } + + videoStream.startStreaming({ + completed: function completed(obj) { + obj.options = options || {}; + + createAndGetGIF(obj, callback); + }, + existingVideo: existingVideo, + crossOrigin: options.crossOrigin, + options: options + }); +} + +/* + existingWebcam.js + ================= +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +function existingWebcam() { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var callback = obj.callback, + lastCameraStream = obj.lastCameraStream, + options = obj.options, + webcamVideoElement = obj.webcamVideoElement; + + + if (!isWebCamGIFSupported()) { + return callback(error.validate()); + } + + if (options.savedRenderingContexts.length) { + screenShot.getGIF(options, function (obj) { + callback(obj); + }); + + return; + } + + videoStream.startVideoStreaming(function () { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + + obj.options = options || {}; + + createAndGetGIF(obj, callback); + }, { + lastCameraStream: lastCameraStream, + callback: callback, + webcamVideoElement: webcamVideoElement, + crossOrigin: options.crossOrigin + }); +} + +/* + createGIF.js + ============ +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +function createGIF(userOptions, callback) { + callback = utils.isFunction(userOptions) ? userOptions : callback; + userOptions = utils.isObject(userOptions) ? userOptions : {}; + + if (!utils.isFunction(callback)) { + return; + } + + var options = utils.mergeOptions(defaultOptions, userOptions) || {}; + var lastCameraStream = userOptions.cameraStream; + var images = options.images; + var imagesLength = images ? images.length : 0; + var video = options.video; + var webcamVideoElement = options.webcamVideoElement; + + options = utils.mergeOptions(options, { + 'gifWidth': Math.floor(options.gifWidth), + 'gifHeight': Math.floor(options.gifHeight) + }); + + // If the user would like to create a GIF from an existing image(s) + if (imagesLength) { + existingImages({ + 'images': images, + 'imagesLength': imagesLength, + 'callback': callback, + 'options': options + }); + } else if (video) { + // If the user would like to create a GIF from an existing HTML5 video + existingVideo({ + 'existingVideo': video, + callback: callback, + options: options + }); + } else { + // If the user would like to create a GIF from a webcam stream + existingWebcam({ + lastCameraStream: lastCameraStream, + callback: callback, + webcamVideoElement: webcamVideoElement, + options: options + }); + } +} + +/* + takeSnapShot.js + =============== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +function takeSnapShot(userOptions, callback) { + callback = utils.isFunction(userOptions) ? userOptions : callback; + userOptions = utils.isObject(userOptions) ? userOptions : {}; + + if (!utils.isFunction(callback)) { + return; + } + + var mergedOptions = utils.mergeOptions(defaultOptions, userOptions); + var options = utils.mergeOptions(mergedOptions, { + 'interval': .1, + 'numFrames': 1, + 'gifWidth': Math.floor(mergedOptions.gifWidth), + 'gifHeight': Math.floor(mergedOptions.gifHeight) + }); + + createGIF(options, callback); +} + +/* + API.js + ====== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. +*/ + +// Dependencies +var API = { + 'utils': utils$2, + 'error': error$2, + 'defaultOptions': defaultOptions$2, + 'createGIF': createGIF, + 'takeSnapShot': takeSnapShot, + 'stopVideoStreaming': stopVideoStreaming, + 'isSupported': isSupported, + 'isWebCamGIFSupported': isWebCamGIFSupported, + 'isExistingVideoGIFSupported': isExistingVideoGIFSupported, + 'isExistingImagesGIFSupported': isSupported$1, + 'VERSION': '0.4.5' +}; + +/* + index.js + ======== +*/ + +/* Copyright 2017 Yahoo Inc. + * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms. + */ + +// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, and plain browser loading +if (typeof define === 'function' && define.amd) { + define([], function () { + return API; + }); +} else if (typeof exports !== 'undefined') { + module.exports = API; +} else { + window.gifshot = API; +} +}(typeof window !== "undefined" ? window : {}, typeof document !== "undefined" ? document : { createElement: function() {} }, typeof window !== "undefined" ? window.navigator : {})); + +},{}],133:[function(require,module,exports){ +/** + * + * @param {WebGLRenderingContext} gl + * @param {IGLWiretapOptions} [options] + * @returns {GLWiretapProxy} + */ +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() { // need arguments from this, fyi + switch (property) { + case 'getError': + if (throwGetError) { + recording.push(`${indent}if (${contextName}.getError() !== ${contextName}.NONE) throw new Error('error');`); + } else { + recording.push(`${indent}${contextName}.getError();`); // flush out errors + } + 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; + } +} + +/** + * + * @param extension + * @param {IGLExtensionWiretapOptions} options + * @returns {*} + */ +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; + } +} + +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; + } +} + +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}`); + } +} + +function trackablePrimitive(value) { + // wrapped in object, so track-able + return new value.constructor(value); +} + +if (typeof module !== 'undefined') { + module.exports = { glWiretap, glExtensionWiretap }; +} + +if (typeof window !== 'undefined') { + glWiretap.glExtensionWiretap = glExtensionWiretap; + window.glWiretap = glWiretap; +} + +},{}],134:[function(require,module,exports){ +if (typeof WebGLRenderingContext !== 'undefined') { + module.exports = require('./src/javascript/browser-index') +} else { + module.exports = require('./src/javascript/node-index') +} + +},{"./src/javascript/browser-index":136,"./src/javascript/node-index":149}],135:[function(require,module,exports){ +module.exports={ + "_from": "gl@4.8.0", + "_id": "gl@4.8.0", + "_inBundle": false, + "_integrity": "sha512-aH73Ilq5cnfa9hF829UqWMjZBdYbIC7aNHYYpisZMN9QJttj8p/nyhxcJ1aGDTwjoL1keR3oN5nkNnAlNSuVcw==", + "_location": "/gl", + "_phantomChildren": { + "abbrev": "1.1.1", + "aws-sign2": "0.7.0", + "aws4": "1.8.0", + "caseless": "0.12.0", + "combined-stream": "1.0.7", + "env-paths": "2.2.0", + "extend": "3.0.2", + "fast-json-stable-stringify": "2.0.0", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "fs.realpath": "1.0.0", + "har-schema": "2.0.0", + "http-signature": "1.2.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "is-typedarray": "1.0.0", + "isexe": "2.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.20", + "minimatch": "3.0.4", + "npmlog": "4.1.2", + "oauth-sign": "0.9.0", + "once": "1.4.0", + "path-is-absolute": "1.0.1", + "performance-now": "2.1.0", + "psl": "1.1.29", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tunnel-agent": "0.6.0", + "uri-js": "4.2.2", + "uuid": "3.3.2" + }, + "_requested": { + "type": "version", + "registry": true, + "raw": "gl@4.8.0", + "name": "gl", + "escapedName": "gl", + "rawSpec": "4.8.0", + "saveSpec": null, + "fetchSpec": "4.8.0" + }, + "_requiredBy": [ + "/gpu.js" + ], + "_resolved": "https://registry.npmjs.org/gl/-/gl-4.8.0.tgz", + "_shasum": "2bf8702d11ae5a76412f3731f3ed652bd77d043b", + "_spec": "gl@4.8.0", + "_where": "/mnt/Data/.My_Projects/githubProjects/image-sequencer/node_modules/gpu.js", + "author": { + "name": "Mikola Lysenko" + }, + "browser": "browser_index.js", + "bugs": { + "url": "https://github.com/stackgl/headless-gl/issues" + }, + "bundleDependencies": false, + "dependencies": { + "bindings": "^1.5.0", + "bit-twiddle": "^1.0.2", + "glsl-tokenizer": "^2.0.2", + "nan": "^2.14.1", + "node-abi": "^2.18.0", + "node-gyp": "^7.1.0", + "prebuild-install": "^5.3.5" + }, + "deprecated": false, + "description": "Creates a WebGL context without a window", + "devDependencies": { + "angle-normals": "^1.0.0", + "bunny": "^1.0.1", + "faucet": "0.0.1", + "gl-conformance": "^2.0.9", + "prebuild": "^10.0.1", + "snazzy": "^8.0.0", + "standard": "^14.3.4", + "tape": "^5.0.1" + }, + "directories": { + "test": "test" + }, + "engines": { + "node": ">=8.0.0" + }, + "gypfile": true, + "homepage": "https://github.com/stackgl/headless-gl#readme", + "keywords": [ + "webgl", + "opengl", + "gl", + "headless", + "server", + "gpgpu" + ], + "license": "BSD-2-Clause", + "main": "index.js", + "name": "gl", + "repository": { + "type": "git", + "url": "git://github.com/stackgl/headless-gl.git" + }, + "scripts": { + "install": "prebuild-install || node-gyp rebuild", + "prebuild": "prebuild --all --strip", + "rebuild": "node-gyp rebuild --verbose", + "test": "standard | snazzy && tape test/*.js | faucet" + }, + "version": "4.8.0" +} + +},{}],136:[function(require,module,exports){ +function createContext (width, height, options) { + width = width | 0 + height = height | 0 + if (!(width > 0 && height > 0)) { + return null + } + + const canvas = document.createElement('canvas') + if (!canvas) { + return null + } + let gl + canvas.width = width + canvas.height = height + + try { + gl = canvas.getContext('webgl', options) + } catch (e) { + try { + gl = canvas.getContext('experimental-webgl', options) + } catch (e) { + return null + } + } + + const _getExtension = gl.getExtension + const extDestroy = { + destroy: function () { + const loseContext = _getExtension.call(gl, 'WEBGL_lose_context') + if (loseContext) { + loseContext.loseContext() + } + } + } + + const extResize = { + resize: function (w, h) { + canvas.width = w + canvas.height = h + } + } + + const _supportedExtensions = gl.getSupportedExtensions().slice() + _supportedExtensions.push( + 'STACKGL_destroy_context', + 'STACKGL_resize_drawingbuffer') + gl.getSupportedExtensions = function () { + return _supportedExtensions.slice() + } + + gl.getExtension = function (extName) { + const name = extName.toLowerCase() + if (name === 'stackgl_resize_drawingbuffer') { + return extResize + } + if (name === 'stackgl_destroy_context') { + return extDestroy + } + return _getExtension.call(gl, extName) + } + + return gl || null +} + +module.exports = createContext + +},{}],137:[function(require,module,exports){ +const { gl } = require('../native-gl') +const { vertexCount } = require('../utils') + +class ANGLEInstancedArrays { + constructor (ctx) { + this.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88fe + this.ctx = ctx + + this._drawArraysInstanced = gl._drawArraysInstanced.bind(ctx) + this._drawElementsInstanced = gl._drawElementsInstanced.bind(ctx) + this._vertexAttribDivisor = gl._vertexAttribDivisor.bind(ctx) + } + + drawArraysInstancedANGLE (mode, first, count, primCount) { + const { ctx } = this + mode |= 0 + first |= 0 + count |= 0 + primCount |= 0 + if (first < 0 || count < 0 || primCount < 0) { + ctx.setError(gl.INVALID_VALUE) + return + } + if (!ctx._checkStencilState()) { + return + } + const reducedCount = vertexCount(mode, count) + if (reducedCount < 0) { + ctx.setError(gl.INVALID_ENUM) + return + } + if (!ctx._framebufferOk()) { + return + } + if (count === 0 || primCount === 0) { + return + } + let maxIndex = first + if (count > 0) { + maxIndex = (count + first - 1) >>> 0 + } + if (this.checkInstancedVertexAttribState(maxIndex, primCount)) { + return this._drawArraysInstanced(mode, first, reducedCount, primCount) + } + } + + drawElementsInstancedANGLE (mode, count, type, ioffset, primCount) { + const { ctx } = this + mode |= 0 + count |= 0 + type |= 0 + ioffset |= 0 + primCount |= 0 + + if (count < 0 || ioffset < 0 || primCount < 0) { + ctx.setError(gl.INVALID_VALUE) + return + } + + if (!ctx._checkStencilState()) { + return + } + + const elementBuffer = ctx._activeElementArrayBuffer + if (!elementBuffer) { + ctx.setError(gl.INVALID_OPERATION) + return + } + + // Unpack element data + let elementData = null + let offset = ioffset + if (type === gl.UNSIGNED_SHORT) { + if (offset % 2) { + ctx.setError(gl.INVALID_OPERATION) + return + } + offset >>= 1 + elementData = new Uint16Array(elementBuffer._elements.buffer) + } else if (ctx._extensions.oes_element_index_uint && type === gl.UNSIGNED_INT) { + if (offset % 4) { + ctx.setError(gl.INVALID_OPERATION) + return + } + offset >>= 2 + elementData = new Uint32Array(elementBuffer._elements.buffer) + } else if (type === gl.UNSIGNED_BYTE) { + elementData = elementBuffer._elements + } else { + ctx.setError(gl.INVALID_ENUM) + return + } + + let reducedCount = count + switch (mode) { + case gl.TRIANGLES: + if (count % 3) { + reducedCount -= (count % 3) + } + break + case gl.LINES: + if (count % 2) { + reducedCount -= (count % 2) + } + break + case gl.POINTS: + break + case gl.LINE_LOOP: + case gl.LINE_STRIP: + if (count < 2) { + ctx.setError(gl.INVALID_OPERATION) + return + } + break + case gl.TRIANGLE_FAN: + case gl.TRIANGLE_STRIP: + if (count < 3) { + ctx.setError(gl.INVALID_OPERATION) + return + } + break + default: + ctx.setError(gl.INVALID_ENUM) + return + } + + if (!ctx._framebufferOk()) { + return + } + + if (count === 0 || primCount === 0) { + this.checkInstancedVertexAttribState(0, 0) + return + } + + if ((count + offset) >>> 0 > elementData.length) { + ctx.setError(gl.INVALID_OPERATION) + return + } + + // Compute max index + let maxIndex = -1 + for (let i = offset; i < offset + count; ++i) { + maxIndex = Math.max(maxIndex, elementData[i]) + } + + if (maxIndex < 0) { + this.checkInstancedVertexAttribState(0, 0) + return + } + + if (this.checkInstancedVertexAttribState(maxIndex, primCount)) { + if (reducedCount > 0) { + this._drawElementsInstanced(mode, reducedCount, type, ioffset, primCount) + } + } + } + + vertexAttribDivisorANGLE (index, divisor) { + const { ctx } = this + index |= 0 + divisor |= 0 + if (divisor < 0 || + index < 0 || index >= ctx._vertexAttribs.length) { + ctx.setError(gl.INVALID_VALUE) + return + } + const attrib = ctx._vertexAttribs[index] + attrib._divisor = divisor + this._vertexAttribDivisor(index, divisor) + } + + checkInstancedVertexAttribState (maxIndex, primCount) { + const { ctx } = this + const program = ctx._activeProgram + if (!program) { + ctx.setError(gl.INVALID_OPERATION) + return false + } + + const attribs = ctx._vertexAttribs + let hasZero = false + for (let i = 0; i < attribs.length; ++i) { + const attrib = attribs[i] + if (attrib._isPointer) { + const buffer = attrib._pointerBuffer + if (program._attributes.indexOf(i) >= 0) { + if (!buffer) { + ctx.setError(gl.INVALID_OPERATION) + return false + } + let maxByte = 0 + if (attrib._divisor === 0) { + hasZero = true + maxByte = attrib._pointerStride * maxIndex + + attrib._pointerSize + + attrib._pointerOffset + } else { + maxByte = attrib._pointerStride * (Math.ceil(primCount / attrib._divisor) - 1) + + attrib._pointerSize + + attrib._pointerOffset + } + if (maxByte > buffer._size) { + ctx.setError(gl.INVALID_OPERATION) + return false + } + } + } + } + + if (!hasZero) { + ctx.setError(gl.INVALID_OPERATION) + return false + } + + return true + } +} + +function getANGLEInstancedArrays (ctx) { + return new ANGLEInstancedArrays(ctx) +} + +module.exports = { ANGLEInstancedArrays, getANGLEInstancedArrays } + +},{"../native-gl":148,"../utils":150}],138:[function(require,module,exports){ +class EXTBlendMinMax { + constructor () { + this.MIN_EXT = 0x8007 + this.MAX_EXT = 0x8008 + } +} + +function getEXTBlendMinMax (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('EXT_blend_minmax') >= 0) { + result = new EXTBlendMinMax() + } + + return result +} + +module.exports = { getEXTBlendMinMax, EXTBlendMinMax } + +},{}],139:[function(require,module,exports){ +class EXTTextureFilterAnisotropic { + constructor () { + this.TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE + this.MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF + } +} + +function getEXTTextureFilterAnisotropic (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('EXT_texture_filter_anisotropic') >= 0) { + result = new EXTTextureFilterAnisotropic() + } + + return result +} + +module.exports = { getEXTTextureFilterAnisotropic, EXTTextureFilterAnisotropic } + +},{}],140:[function(require,module,exports){ +class OESElementIndexUint {} + +function getOESElementIndexUint (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('OES_element_index_uint') >= 0) { + result = new OESElementIndexUint() + } + + return result +} + +module.exports = { getOESElementIndexUint, OESElementIndexUint } + +},{}],141:[function(require,module,exports){ +class OESStandardDerivatives { + constructor () { + this.FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B + } +} + +function getOESStandardDerivatives (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('OES_standard_derivatives') >= 0) { + result = new OESStandardDerivatives() + } + + return result +} + +module.exports = { getOESStandardDerivatives, OESStandardDerivatives } + +},{}],142:[function(require,module,exports){ +class OESTextureFloatLinear {} + +function getOESTextureFloatLinear (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('OES_texture_float_linear') >= 0) { + result = new OESTextureFloatLinear() + } + + return result +} + +module.exports = { getOESTextureFloatLinear, OESTextureFloatLinear } + +},{}],143:[function(require,module,exports){ +class OESTextureFloat {} + +function getOESTextureFloat (context) { + let result = null + const exts = context.getSupportedExtensions() + + if (exts && exts.indexOf('OES_texture_float') >= 0) { + result = new OESTextureFloat() + } + + return result +} + +module.exports = { getOESTextureFloat, OESTextureFloat } + +},{}],144:[function(require,module,exports){ +class STACKGLDestroyContext { + constructor (ctx) { + this.destroy = ctx.destroy.bind(ctx) + } +} + +function getSTACKGLDestroyContext (ctx) { + return new STACKGLDestroyContext(ctx) +} + +module.exports = { getSTACKGLDestroyContext, STACKGLDestroyContext } + +},{}],145:[function(require,module,exports){ +class STACKGLResizeDrawingBuffer { + constructor (ctx) { + this.resize = ctx.resize.bind(ctx) + } +} + +function getSTACKGLResizeDrawingBuffer (ctx) { + return new STACKGLResizeDrawingBuffer(ctx) +} + +module.exports = { getSTACKGLResizeDrawingBuffer, STACKGLResizeDrawingBuffer } + +},{}],146:[function(require,module,exports){ +const { gl } = require('../native-gl') + +class WebGLDrawBuffers { + constructor (ctx) { + this.ctx = ctx + const exts = ctx.getSupportedExtensions() + + if (exts && exts.indexOf('WEBGL_draw_buffers') >= 0) { + Object.assign(this, ctx.extWEBGL_draw_buffers()) + this._buffersState = [ctx.BACK] + this._maxDrawBuffers = ctx._getParameterDirect(this.MAX_DRAW_BUFFERS_WEBGL) + this._ALL_ATTACHMENTS = [] + this._ALL_COLOR_ATTACHMENTS = [] + const allColorAttachments = [ + this.COLOR_ATTACHMENT0_WEBGL, + this.COLOR_ATTACHMENT1_WEBGL, + this.COLOR_ATTACHMENT2_WEBGL, + this.COLOR_ATTACHMENT3_WEBGL, + this.COLOR_ATTACHMENT4_WEBGL, + this.COLOR_ATTACHMENT5_WEBGL, + this.COLOR_ATTACHMENT6_WEBGL, + this.COLOR_ATTACHMENT7_WEBGL, + this.COLOR_ATTACHMENT8_WEBGL, + this.COLOR_ATTACHMENT9_WEBGL, + this.COLOR_ATTACHMENT10_WEBGL, + this.COLOR_ATTACHMENT11_WEBGL, + this.COLOR_ATTACHMENT12_WEBGL, + this.COLOR_ATTACHMENT13_WEBGL, + this.COLOR_ATTACHMENT14_WEBGL, + this.COLOR_ATTACHMENT15_WEBGL + ] + while (this._ALL_ATTACHMENTS.length < this._maxDrawBuffers) { + const colorAttachment = allColorAttachments.shift() + this._ALL_ATTACHMENTS.push(colorAttachment) + this._ALL_COLOR_ATTACHMENTS.push(colorAttachment) + } + this._ALL_ATTACHMENTS.push( + gl.DEPTH_ATTACHMENT, + gl.STENCIL_ATTACHMENT, + gl.DEPTH_STENCIL_ATTACHMENT + ) + } + } + + drawBuffersWEBGL (buffers) { + const { ctx } = this + if (buffers.length < 1) { + ctx.setError(gl.INVALID_OPERATION) + return + } + if (buffers.length === 1 && buffers[0] === gl.BACK) { + this._buffersState = buffers + ctx.drawBuffersWEBGL([this.COLOR_ATTACHMENT0_WEBGL]) + return + } else if (!ctx._activeFramebuffer) { + if (buffers.length > 1) { + ctx.setError(gl.INVALID_OPERATION) + return + } + for (let i = 0; i < buffers.length; i++) { + if (buffers[i] > gl.NONE) { + ctx.setError(gl.INVALID_OPERATION) + return + } + } + } + this._buffersState = buffers + ctx.drawBuffersWEBGL(buffers) + } +} + +function getWebGLDrawBuffers (ctx) { + const exts = ctx.getSupportedExtensions() + + if (exts && exts.indexOf('WEBGL_draw_buffers') >= 0) { + return new WebGLDrawBuffers(ctx) + } else { + return null + } +} + +module.exports = { + getWebGLDrawBuffers, + WebGLDrawBuffers +} + +},{"../native-gl":148}],147:[function(require,module,exports){ +class Linkable { + constructor (_) { + this._ = _ + this._references = [] + this._refCount = 0 + this._pendingDelete = false + this._binding = 0 + } + + _link (b) { + this._references.push(b) + b._refCount += 1 + return true + } + + _unlink (b) { + let idx = this._references.indexOf(b) + if (idx < 0) { + return false + } + while (idx >= 0) { + this._references[idx] = this._references[this._references.length - 1] + this._references.pop() + b._refCount -= 1 + b._checkDelete() + idx = this._references.indexOf(b) + } + return true + } + + _linked (b) { + return this._references.indexOf(b) >= 0 + } + + _checkDelete () { + if (this._refCount <= 0 && + this._pendingDelete && + this._ !== 0) { + while (this._references.length > 0) { + this._unlink(this._references[0]) + } + this._performDelete() + this._ = 0 + } + } + + _performDelete () {} +} + +module.exports = { Linkable } + +},{}],148:[function(require,module,exports){ +(function (process){ +const NativeWebGL = require('bindings')('webgl') +const { WebGLRenderingContext: NativeWebGLRenderingContext } = NativeWebGL +process.on('exit', NativeWebGL.cleanup) + +const gl = NativeWebGLRenderingContext.prototype + +// from binding.gyp +delete gl['1.0.0'] + +// from binding.gyp +delete NativeWebGLRenderingContext['1.0.0'] + +module.exports = { gl, NativeWebGL, NativeWebGLRenderingContext } + +}).call(this,require('_process')) +},{"_process":432,"bindings":30}],149:[function(require,module,exports){ +const bits = require('bit-twiddle') +const { WebGLContextAttributes } = require('./webgl-context-attributes') +const { WebGLRenderingContext, wrapContext } = require('./webgl-rendering-context') +const { WebGLTextureUnit } = require('./webgl-texture-unit') +const { WebGLVertexAttribute } = require('./webgl-vertex-attribute') + +let CONTEXT_COUNTER = 0 + +function flag (options, name, dflt) { + if (!options || !(typeof options === 'object') || !(name in options)) { + return dflt + } + return !!options[name] +} + +function createContext (width, height, options) { + width = width | 0 + height = height | 0 + if (!(width > 0 && height > 0)) { + return null + } + + const contextAttributes = new WebGLContextAttributes( + flag(options, 'alpha', true), + flag(options, 'depth', true), + flag(options, 'stencil', false), + false, // flag(options, 'antialias', true), + flag(options, 'premultipliedAlpha', true), + flag(options, 'preserveDrawingBuffer', false), + flag(options, 'preferLowPowerToHighPerformance', false), + flag(options, 'failIfMajorPerformanceCaveat', false)) + + // Can only use premultipliedAlpha if alpha is set + contextAttributes.premultipliedAlpha = + contextAttributes.premultipliedAlpha && contextAttributes.alpha + + let ctx + try { + ctx = new WebGLRenderingContext( + 1, + 1, + contextAttributes.alpha, + contextAttributes.depth, + contextAttributes.stencil, + contextAttributes.antialias, + contextAttributes.premultipliedAlpha, + contextAttributes.preserveDrawingBuffer, + contextAttributes.preferLowPowerToHighPerformance, + contextAttributes.failIfMajorPerformanceCaveat) + } catch (e) {} + if (!ctx) { + return null + } + + ctx.drawingBufferWidth = width + ctx.drawingBufferHeight = height + + ctx._ = CONTEXT_COUNTER++ + + ctx._contextAttributes = contextAttributes + + ctx._extensions = {} + ctx._programs = {} + ctx._shaders = {} + ctx._buffers = {} + ctx._textures = {} + ctx._framebuffers = {} + ctx._renderbuffers = {} + + ctx._activeProgram = null + ctx._activeFramebuffer = null + ctx._activeArrayBuffer = null + ctx._activeElementArrayBuffer = null + ctx._activeRenderbuffer = null + ctx._checkStencil = false + ctx._stencilState = true + + // Initialize texture units + const numTextures = ctx.getParameter(ctx.MAX_COMBINED_TEXTURE_IMAGE_UNITS) + ctx._textureUnits = new Array(numTextures) + for (let i = 0; i < numTextures; ++i) { + ctx._textureUnits[i] = new WebGLTextureUnit(i) + } + ctx._activeTextureUnit = 0 + ctx.activeTexture(ctx.TEXTURE0) + + ctx._errorStack = [] + + // Initialize vertex attributes + const numAttribs = ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS) + ctx._vertexAttribs = new Array(numAttribs) + for (let i = 0; i < numAttribs; ++i) { + ctx._vertexAttribs[i] = new WebGLVertexAttribute(ctx, i) + } + + // Store limits + ctx._maxTextureSize = ctx.getParameter(ctx.MAX_TEXTURE_SIZE) + ctx._maxTextureLevel = bits.log2(bits.nextPow2(ctx._maxTextureSize)) + ctx._maxCubeMapSize = ctx.getParameter(ctx.MAX_CUBE_MAP_TEXTURE_SIZE) + ctx._maxCubeMapLevel = bits.log2(bits.nextPow2(ctx._maxCubeMapSize)) + + // Unpack alignment + ctx._unpackAlignment = 4 + ctx._packAlignment = 4 + + // Allocate framebuffer + ctx._allocateDrawingBuffer(width, height) + + const attrib0Buffer = ctx.createBuffer() + ctx._attrib0Buffer = attrib0Buffer + + // Initialize defaults + ctx.bindBuffer(ctx.ARRAY_BUFFER, null) + ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null) + ctx.bindFramebuffer(ctx.FRAMEBUFFER, null) + ctx.bindRenderbuffer(ctx.RENDERBUFFER, null) + + // Set viewport and scissor + ctx.viewport(0, 0, width, height) + ctx.scissor(0, 0, width, height) + + // Clear buffers + ctx.clearDepth(1) + ctx.clearColor(0, 0, 0, 0) + ctx.clearStencil(0) + ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT) + + return wrapContext(ctx) +} + +module.exports = createContext + +},{"./webgl-context-attributes":153,"./webgl-rendering-context":158,"./webgl-texture-unit":161,"./webgl-vertex-attribute":164,"bit-twiddle":31}],150:[function(require,module,exports){ +(function (Buffer){ +const { gl } = require('./native-gl') + +const { WebGLUniformLocation } = require('./webgl-uniform-location') + +function bindPublics (props, wrapper, privateInstance, privateMethods) { + for (let i = 0; i < props.length; i++) { + const prop = props[i] + const value = privateInstance[prop] + if (typeof value === 'function') { + if (privateMethods.indexOf(prop) === -1) { + wrapper[prop] = value.bind(privateInstance) + } + } else { + if (prop[0] === '_' || + prop[0] === '0' || + prop[0] === '1') { + continue + } + wrapper[prop] = value + } + } +} + +function checkObject (object) { + return typeof object === 'object' || + (object === undefined) +} + +function checkUniform (program, location) { + return location instanceof WebGLUniformLocation && + location._program === program && + location._linkCount === program._linkCount +} + +function isTypedArray (data) { + return data instanceof Uint8Array || + data instanceof Uint8ClampedArray || + data instanceof Int8Array || + data instanceof Uint16Array || + data instanceof Int16Array || + data instanceof Uint32Array || + data instanceof Int32Array || + data instanceof Float32Array || + data instanceof Float64Array +} + +// Don't allow: ", $, `, @, \, ', \0 +function isValidString (str) { + // Remove comments first + const c = str.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '') + return !(/["$`@\\'\0]/.test(c)) +} + +function vertexCount (primitive, count) { + switch (primitive) { + case gl.TRIANGLES: + return count - (count % 3) + case gl.LINES: + return count - (count % 2) + case gl.LINE_LOOP: + case gl.POINTS: + return count + case gl.TRIANGLE_FAN: + case gl.LINE_STRIP: + if (count < 2) { + return 0 + } + return count + case gl.TRIANGLE_STRIP: + if (count < 3) { + return 0 + } + return count + default: + return -1 + } +} + +function typeSize (type) { + switch (type) { + case gl.UNSIGNED_BYTE: + case gl.BYTE: + return 1 + case gl.UNSIGNED_SHORT: + case gl.SHORT: + return 2 + case gl.UNSIGNED_INT: + case gl.INT: + case gl.FLOAT: + return 4 + } + return 0 +} + +function uniformTypeSize (type) { + switch (type) { + case gl.BOOL_VEC4: + case gl.INT_VEC4: + case gl.FLOAT_VEC4: + return 4 + + case gl.BOOL_VEC3: + case gl.INT_VEC3: + case gl.FLOAT_VEC3: + return 3 + + case gl.BOOL_VEC2: + case gl.INT_VEC2: + case gl.FLOAT_VEC2: + return 2 + + case gl.BOOL: + case gl.INT: + case gl.FLOAT: + case gl.SAMPLER_2D: + case gl.SAMPLER_CUBE: + return 1 + + default: + return 0 + } +} + +function unpackTypedArray (array) { + return (new Uint8Array(array.buffer)).subarray( + array.byteOffset, + array.byteLength + array.byteOffset) +} + +function extractImageData (pixels) { + if (typeof pixels === 'object' && typeof pixels.width !== 'undefined' && typeof pixels.height !== 'undefined') { + if (typeof pixels.data !== 'undefined') { + return pixels + } + + let context = null + + if (typeof pixels.getContext === 'function') { + context = pixels.getContext('2d') + } else if (typeof pixels.src !== 'undefined' && typeof document === 'object' && typeof document.createElement === 'function') { + const canvas = document.createElement('canvas') + + if (typeof canvas === 'object' && typeof canvas.getContext === 'function') { + context = canvas.getContext('2d') + + if (context !== null) { + context.drawImage(pixels, 0, 0) + } + } + } + + if (context !== null) { + return context.getImageData(0, 0, pixels.width, pixels.height) + } + } + + return null +} + +function formatSize (internalFormat) { + switch (internalFormat) { + case gl.ALPHA: + case gl.LUMINANCE: + return 1 + case gl.LUMINANCE_ALPHA: + return 2 + case gl.RGB: + return 3 + case gl.RGBA: + return 4 + } + return 0 +} + +function convertPixels (pixels) { + if (typeof pixels === 'object' && pixels !== null) { + if (pixels instanceof ArrayBuffer) { + return new Uint8Array(pixels) + } else if (pixels instanceof Uint8Array || + pixels instanceof Uint16Array || + pixels instanceof Uint8ClampedArray || + pixels instanceof Float32Array) { + return unpackTypedArray(pixels) + } else if (pixels instanceof Buffer) { + return new Uint8Array(pixels) + } + } + return null +} + +function checkFormat (format) { + return ( + format === gl.ALPHA || + format === gl.LUMINANCE_ALPHA || + format === gl.LUMINANCE || + format === gl.RGB || + format === gl.RGBA) +} + +function validCubeTarget (target) { + return target === gl.TEXTURE_CUBE_MAP_POSITIVE_X || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_X || + target === gl.TEXTURE_CUBE_MAP_POSITIVE_Y || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_Y || + target === gl.TEXTURE_CUBE_MAP_POSITIVE_Z || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_Z +} + +module.exports = { + bindPublics, + checkObject, + isTypedArray, + isValidString, + vertexCount, + typeSize, + uniformTypeSize, + unpackTypedArray, + extractImageData, + formatSize, + checkFormat, + checkUniform, + convertPixels, + validCubeTarget +} + +}).call(this,require("buffer").Buffer) +},{"./native-gl":148,"./webgl-uniform-location":163,"buffer":297}],151:[function(require,module,exports){ +class WebGLActiveInfo { + constructor (_) { + this.size = _.size + this.type = _.type + this.name = _.name + } +} +module.exports = { WebGLActiveInfo } + +},{}],152:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLBuffer extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._size = 0 + this._elements = new Uint8Array(0) + } + + _performDelete () { + const ctx = this._ctx + delete ctx._buffers[this._ | 0] + gl.deleteBuffer.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLBuffer } + +},{"./linkable":147,"./native-gl":148}],153:[function(require,module,exports){ +class WebGLContextAttributes { + constructor ( + alpha, + depth, + stencil, + antialias, + premultipliedAlpha, + preserveDrawingBuffer, + preferLowPowerToHighPerformance, + failIfMajorPerformanceCaveat) { + this.alpha = alpha + this.depth = depth + this.stencil = stencil + this.antialias = antialias + this.premultipliedAlpha = premultipliedAlpha + this.preserveDrawingBuffer = preserveDrawingBuffer + this.preferLowPowerToHighPerformance = preferLowPowerToHighPerformance + this.failIfMajorPerformanceCaveat = failIfMajorPerformanceCaveat + } +} + +module.exports = { WebGLContextAttributes } + +},{}],154:[function(require,module,exports){ +class WebGLDrawingBufferWrapper { + constructor (framebuffer, color, depthStencil) { + this._framebuffer = framebuffer + this._color = color + this._depthStencil = depthStencil + } +} + +module.exports = { WebGLDrawingBufferWrapper } + +},{}],155:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLFramebuffer extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._binding = 0 + + this._width = 0 + this._height = 0 + this._status = null + + this._attachments = {} + this._attachments[gl.COLOR_ATTACHMENT0] = null + this._attachments[gl.DEPTH_ATTACHMENT] = null + this._attachments[gl.STENCIL_ATTACHMENT] = null + this._attachments[gl.DEPTH_STENCIL_ATTACHMENT] = null + + this._attachmentLevel = {} + this._attachmentLevel[gl.COLOR_ATTACHMENT0] = 0 + this._attachmentLevel[gl.DEPTH_ATTACHMENT] = 0 + this._attachmentLevel[gl.STENCIL_ATTACHMENT] = 0 + this._attachmentLevel[gl.DEPTH_STENCIL_ATTACHMENT] = 0 + + this._attachmentFace = {} + this._attachmentFace[gl.COLOR_ATTACHMENT0] = 0 + this._attachmentFace[gl.DEPTH_ATTACHMENT] = 0 + this._attachmentFace[gl.STENCIL_ATTACHMENT] = 0 + this._attachmentFace[gl.DEPTH_STENCIL_ATTACHMENT] = 0 + + if (ctx._extensions.webgl_draw_buffers) { + const { webgl_draw_buffers } = ctx._extensions // eslint-disable-line + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT1_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT2_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT3_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT4_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT5_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT6_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT7_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT8_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT9_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT10_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT11_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT12_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT13_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT14_WEBGL] = null + this._attachments[webgl_draw_buffers.COLOR_ATTACHMENT15_WEBGL] = null + this._attachments[gl.NONE] = null + this._attachments[gl.BACK] = null + + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT1_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT2_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT3_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT4_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT5_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT6_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT7_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT8_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT9_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT10_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT11_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT12_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT13_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT14_WEBGL] = 0 + this._attachmentLevel[webgl_draw_buffers.COLOR_ATTACHMENT15_WEBGL] = 0 + this._attachmentLevel[gl.NONE] = null + this._attachmentLevel[gl.BACK] = null + + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT1_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT2_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT3_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT4_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT5_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT6_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT7_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT8_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT9_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT10_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT11_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT12_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT13_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT14_WEBGL] = 0 + this._attachmentFace[webgl_draw_buffers.COLOR_ATTACHMENT15_WEBGL] = 0 + this._attachmentFace[gl.NONE] = null + this._attachmentFace[gl.BACK] = null + } + } + + _clearAttachment (attachment) { + const object = this._attachments[attachment] + if (!object) { + return + } + this._attachments[attachment] = null + this._unlink(object) + } + + _setAttachment (object, attachment) { + const prevObject = this._attachments[attachment] + if (prevObject === object) { + return + } + + this._clearAttachment(attachment) + if (!object) { + return + } + + this._attachments[attachment] = object + + this._link(object) + } + + _performDelete () { + const ctx = this._ctx + delete ctx._framebuffers[this._ | 0] + gl.deleteFramebuffer.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLFramebuffer } + +},{"./linkable":147,"./native-gl":148}],156:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLProgram extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._linkCount = 0 + this._linkStatus = false + this._linkInfoLog = 'not linked' + this._attributes = [] + this._uniforms = [] + } + + _performDelete () { + const ctx = this._ctx + delete ctx._programs[this._ | 0] + gl.deleteProgram.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLProgram } + +},{"./linkable":147,"./native-gl":148}],157:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLRenderbuffer extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._binding = 0 + this._width = 0 + this._height = 0 + this._format = 0 + } + + _performDelete () { + const ctx = this._ctx + delete ctx._renderbuffers[this._ | 0] + gl.deleteRenderbuffer.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLRenderbuffer } + +},{"./linkable":147,"./native-gl":148}],158:[function(require,module,exports){ +const bits = require('bit-twiddle') +const tokenize = require('glsl-tokenizer/string') +const HEADLESS_VERSION = require('../../package.json').version +const { gl, NativeWebGLRenderingContext, NativeWebGL } = require('./native-gl') +const { getANGLEInstancedArrays } = require('./extensions/angle-instanced-arrays') +const { getOESElementIndexUint } = require('./extensions/oes-element-index-unit') +const { getOESStandardDerivatives } = require('./extensions/oes-standard-derivatives') +const { getOESTextureFloat } = require('./extensions/oes-texture-float') +const { getOESTextureFloatLinear } = require('./extensions/oes-texture-float-linear') +const { getSTACKGLDestroyContext } = require('./extensions/stackgl-destroy-context') +const { getSTACKGLResizeDrawingBuffer } = require('./extensions/stackgl-resize-drawing-buffer') +const { getWebGLDrawBuffers } = require('./extensions/webgl-draw-buffers') +const { getEXTBlendMinMax } = require('./extensions/ext-blend-minmax') +const { getEXTTextureFilterAnisotropic } = require('./extensions/ext-texture-filter-anisotropic') +const { + bindPublics, + checkObject, + checkUniform, + formatSize, + isValidString, + typeSize, + uniformTypeSize, + extractImageData, + vertexCount, + isTypedArray, + unpackTypedArray, + convertPixels, + checkFormat, + validCubeTarget +} = require('./utils') + +const { WebGLActiveInfo } = require('./webgl-active-info') +const { WebGLFramebuffer } = require('./webgl-framebuffer') +const { WebGLBuffer } = require('./webgl-buffer') +const { WebGLDrawingBufferWrapper } = require('./webgl-drawing-buffer-wrapper') +const { WebGLProgram } = require('./webgl-program') +const { WebGLRenderbuffer } = require('./webgl-renderbuffer') +const { WebGLShader } = require('./webgl-shader') +const { WebGLShaderPrecisionFormat } = require('./webgl-shader-precision-format') +const { WebGLTexture } = require('./webgl-texture') +const { WebGLUniformLocation } = require('./webgl-uniform-location') + +// These are defined by the WebGL spec +const MAX_UNIFORM_LENGTH = 256 +const MAX_ATTRIBUTE_LENGTH = 256 + +const DEFAULT_ATTACHMENTS = [ + gl.COLOR_ATTACHMENT0, + gl.DEPTH_ATTACHMENT, + gl.STENCIL_ATTACHMENT, + gl.DEPTH_STENCIL_ATTACHMENT +] + +const DEFAULT_COLOR_ATTACHMENTS = [gl.COLOR_ATTACHMENT0] + +const availableExtensions = { + angle_instanced_arrays: getANGLEInstancedArrays, + oes_element_index_uint: getOESElementIndexUint, + oes_texture_float: getOESTextureFloat, + oes_texture_float_linear: getOESTextureFloatLinear, + oes_standard_derivatives: getOESStandardDerivatives, + stackgl_destroy_context: getSTACKGLDestroyContext, + stackgl_resize_drawingbuffer: getSTACKGLResizeDrawingBuffer, + webgl_draw_buffers: getWebGLDrawBuffers, + ext_blend_minmax: getEXTBlendMinMax, + ext_texture_filter_anisotropic: getEXTTextureFilterAnisotropic +} + +const privateMethods = [ + 'resize', + 'destroy' +] + +function wrapContext (ctx) { + const wrapper = new WebGLRenderingContext() + bindPublics(Object.keys(ctx), wrapper, ctx, privateMethods) + bindPublics(Object.keys(ctx.constructor.prototype), wrapper, ctx, privateMethods) + bindPublics(Object.getOwnPropertyNames(ctx), wrapper, ctx, privateMethods) + bindPublics(Object.getOwnPropertyNames(ctx.constructor.prototype), wrapper, ctx, privateMethods) + + Object.defineProperties(wrapper, { + drawingBufferWidth: { + get () { return ctx.drawingBufferWidth }, + set (value) { ctx.drawingBufferWidth = value } + }, + drawingBufferHeight: { + get () { return ctx.drawingBufferHeight }, + set (value) { ctx.drawingBufferHeight = value } + } + }) + + return wrapper +} + +// We need to wrap some of the native WebGL functions to handle certain error codes and check input values +class WebGLRenderingContext extends NativeWebGLRenderingContext { + _checkDimensions ( + target, + width, + height, + level) { + if (level < 0 || + width < 0 || + height < 0) { + this.setError(gl.INVALID_VALUE) + return false + } + if (target === gl.TEXTURE_2D) { + if (width > this._maxTextureSize || + height > this._maxTextureSize || + level > this._maxTextureLevel) { + this.setError(gl.INVALID_VALUE) + return false + } + } else if (this._validCubeTarget(target)) { + if (width > this._maxCubeMapSize || + height > this._maxCubeMapSize || + level > this._maxCubeMapLevel) { + this.setError(gl.INVALID_VALUE) + return false + } + } else { + this.setError(gl.INVALID_ENUM) + return false + } + return true + } + + _checkLocation (location) { + if (!(location instanceof WebGLUniformLocation)) { + this.setError(gl.INVALID_VALUE) + return false + } else if (location._program._ctx !== this || + location._linkCount !== location._program._linkCount) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + + _checkLocationActive (location) { + if (!location) { + return false + } else if (!this._checkLocation(location)) { + return false + } else if (location._program !== this._activeProgram) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + + _checkOwns (object) { + return typeof object === 'object' && + object._ctx === this + } + + _checkShaderSource (shader) { + const source = shader._source + const tokens = tokenize(source) + + let errorStatus = false + const errorLog = [] + + for (let i = 0; i < tokens.length; ++i) { + const tok = tokens[i] + switch (tok.type) { + case 'ident': + if (!this._validGLSLIdentifier(tok.data)) { + errorStatus = true + errorLog.push(tok.line + ':' + tok.column + + ' invalid identifier - ' + tok.data) + } + break + case 'preprocessor': { + const bodyToks = tokenize(tok.data.match(/^\s*#\s*(.*)$/)[1]) + for (let j = 0; j < bodyToks.length; ++j) { + const btok = bodyToks[j] + if (btok.type === 'ident' || btok.type === undefined) { + if (!this._validGLSLIdentifier(btok.data)) { + errorStatus = true + errorLog.push(tok.line + ':' + btok.column + + ' invalid identifier - ' + btok.data) + } + } + } + break + } + case 'keyword': + switch (tok.data) { + case 'do': + errorStatus = true + errorLog.push(tok.line + ':' + tok.column + ' do not supported') + break + } + break + case 'builtin': + switch (tok.data) { + case 'dFdx': + case 'dFdy': + case 'fwidth': + if (!this._extensions.oes_standard_derivatives) { + errorStatus = true + errorLog.push(tok.line + ':' + tok.column + ' ' + tok.data + ' not supported') + } + break + } + } + } + + if (errorStatus) { + shader._compileInfo = errorLog.join('\n') + } + return !errorStatus + } + + _checkStencilState () { + if (!this._checkStencil) { + return this._stencilState + } + this._checkStencil = false + this._stencilState = true + if (this.getParameter(gl.STENCIL_WRITEMASK) !== + this.getParameter(gl.STENCIL_BACK_WRITEMASK) || + this.getParameter(gl.STENCIL_VALUE_MASK) !== + this.getParameter(gl.STENCIL_BACK_VALUE_MASK) || + this.getParameter(gl.STENCIL_REF) !== + this.getParameter(gl.STENCIL_BACK_REF)) { + this.setError(gl.INVALID_OPERATION) + this._stencilState = false + } + return this._stencilState + } + + _checkTextureTarget (target) { + const unit = this._getActiveTextureUnit() + let tex = null + if (target === gl.TEXTURE_2D) { + tex = unit._bind2D + } else if (target === gl.TEXTURE_CUBE_MAP) { + tex = unit._bindCube + } else { + this.setError(gl.INVALID_ENUM) + return false + } + if (!tex) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + + _checkWrapper (object, Wrapper) { + if (!this._checkValid(object, Wrapper)) { + this.setError(gl.INVALID_VALUE) + return false + } else if (!this._checkOwns(object)) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + + _checkValid (object, Type) { + return object instanceof Type && object._ !== 0 + } + + _checkVertexAttribState (maxIndex) { + const program = this._activeProgram + if (!program) { + this.setError(gl.INVALID_OPERATION) + return false + } + const attribs = this._vertexAttribs + for (let i = 0; i < attribs.length; ++i) { + const attrib = attribs[i] + if (attrib._isPointer) { + const buffer = attrib._pointerBuffer + if (!buffer) { + this.setError(gl.INVALID_OPERATION) + return false + } + if (program._attributes.indexOf(i) >= 0) { + let maxByte = 0 + if (attrib._divisor) { + maxByte = attrib._pointerSize + + attrib._pointerOffset + } else { + maxByte = attrib._pointerStride * maxIndex + + attrib._pointerSize + + attrib._pointerOffset + } + if (maxByte > buffer._size) { + this.setError(gl.INVALID_OPERATION) + return false + } + } + } + } + return true + } + + _checkVertexIndex (index) { + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return false + } + return true + } + + _computePixelSize (type, internalFormat) { + const pixelSize = formatSize(internalFormat) + if (pixelSize === 0) { + this.setError(gl.INVALID_ENUM) + return 0 + } + switch (type) { + case gl.UNSIGNED_BYTE: + return pixelSize + case gl.UNSIGNED_SHORT_5_6_5: + if (internalFormat !== gl.RGB) { + this.setError(gl.INVALID_OPERATION) + break + } + return 2 + case gl.UNSIGNED_SHORT_4_4_4_4: + case gl.UNSIGNED_SHORT_5_5_5_1: + if (internalFormat !== gl.RGBA) { + this.setError(gl.INVALID_OPERATION) + break + } + return 2 + case gl.FLOAT: + return 1 + } + this.setError(gl.INVALID_ENUM) + return 0 + } + + _computeRowStride (width, pixelSize) { + let rowStride = width * pixelSize + if (rowStride % this._unpackAlignment) { + rowStride += this._unpackAlignment - (rowStride % this._unpackAlignment) + } + return rowStride + } + + _fixupLink (program) { + if (!super.getProgramParameter(program._, gl.LINK_STATUS)) { + program._linkInfoLog = super.getProgramInfoLog(program) + return false + } + + // Record attribute attributeLocations + const numAttribs = this.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES) + const names = new Array(numAttribs) + program._attributes.length = numAttribs + for (let i = 0; i < numAttribs; ++i) { + names[i] = this.getActiveAttrib(program, i).name + program._attributes[i] = this.getAttribLocation(program, names[i]) | 0 + } + + // Check attribute names + for (let i = 0; i < names.length; ++i) { + if (names[i].length > MAX_ATTRIBUTE_LENGTH) { + program._linkInfoLog = 'attribute ' + names[i] + ' is too long' + return false + } + } + + for (let i = 0; i < numAttribs; ++i) { + super.bindAttribLocation( + program._ | 0, + program._attributes[i], + names[i]) + } + + super.linkProgram(program._ | 0) + + const numUniforms = this.getProgramParameter(program, gl.ACTIVE_UNIFORMS) + program._uniforms.length = numUniforms + for (let i = 0; i < numUniforms; ++i) { + program._uniforms[i] = this.getActiveUniform(program, i) + } + + // Check attribute and uniform name lengths + for (let i = 0; i < program._uniforms.length; ++i) { + if (program._uniforms[i].name.length > MAX_UNIFORM_LENGTH) { + program._linkInfoLog = 'uniform ' + program._uniforms[i].name + ' is too long' + return false + } + } + + program._linkInfoLog = '' + return true + } + + _framebufferOk () { + const framebuffer = this._activeFramebuffer + if (framebuffer && + this._preCheckFramebufferStatus(framebuffer) !== gl.FRAMEBUFFER_COMPLETE) { + this.setError(gl.INVALID_FRAMEBUFFER_OPERATION) + return false + } + return true + } + + _getActiveBuffer (target) { + if (target === gl.ARRAY_BUFFER) { + return this._activeArrayBuffer + } else if (target === gl.ELEMENT_ARRAY_BUFFER) { + return this._activeElementArrayBuffer + } + return null + } + + _getActiveTextureUnit () { + return this._textureUnits[this._activeTextureUnit] + } + + _getActiveTexture (target) { + const activeUnit = this._getActiveTextureUnit() + if (target === gl.TEXTURE_2D) { + return activeUnit._bind2D + } else if (target === gl.TEXTURE_CUBE_MAP) { + return activeUnit._bindCube + } + return null + } + + _getAttachments () { + return this._extensions.webgl_draw_buffers ? this._extensions.webgl_draw_buffers._ALL_ATTACHMENTS : DEFAULT_ATTACHMENTS + } + + _getColorAttachments () { + return this._extensions.webgl_draw_buffers ? this._extensions.webgl_draw_buffers._ALL_COLOR_ATTACHMENTS : DEFAULT_COLOR_ATTACHMENTS + } + + _getParameterDirect (pname) { + return super.getParameter(pname) + } + + _getTexImage (target) { + const unit = this._getActiveTextureUnit() + if (target === gl.TEXTURE_2D) { + return unit._bind2D + } else if (validCubeTarget(target)) { + return unit._bindCube + } + this.setError(gl.INVALID_ENUM) + return null + } + + _preCheckFramebufferStatus (framebuffer) { + const attachments = framebuffer._attachments + const width = [] + const height = [] + const depthAttachment = attachments[gl.DEPTH_ATTACHMENT] + const depthStencilAttachment = attachments[gl.DEPTH_STENCIL_ATTACHMENT] + const stencilAttachment = attachments[gl.STENCIL_ATTACHMENT] + + if ((depthStencilAttachment && (stencilAttachment || depthAttachment)) || + (stencilAttachment && depthAttachment)) { + return gl.FRAMEBUFFER_UNSUPPORTED + } + + const colorAttachments = this._getColorAttachments() + let colorAttachmentCount = 0 + for (const attachmentEnum in attachments) { + if (attachments[attachmentEnum] && colorAttachments.indexOf(attachmentEnum * 1) !== -1) { + colorAttachmentCount++ + } + } + if (colorAttachmentCount === 0) { + return gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + } + + if (depthStencilAttachment instanceof WebGLTexture) { + return gl.FRAMEBUFFER_UNSUPPORTED + } else if (depthStencilAttachment instanceof WebGLRenderbuffer) { + if (depthStencilAttachment._format !== gl.DEPTH_STENCIL) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + width.push(depthStencilAttachment._width) + height.push(depthStencilAttachment._height) + } + + if (depthAttachment instanceof WebGLTexture) { + return gl.FRAMEBUFFER_UNSUPPORTED + } else if (depthAttachment instanceof WebGLRenderbuffer) { + if (depthAttachment._format !== gl.DEPTH_COMPONENT16) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + width.push(depthAttachment._width) + height.push(depthAttachment._height) + } + + if (stencilAttachment instanceof WebGLTexture) { + return gl.FRAMEBUFFER_UNSUPPORTED + } else if (stencilAttachment instanceof WebGLRenderbuffer) { + if (stencilAttachment._format !== gl.STENCIL_INDEX8) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + width.push(stencilAttachment._width) + height.push(stencilAttachment._height) + } + + let colorAttached = false + for (let i = 0; i < colorAttachments.length; ++i) { + const colorAttachment = attachments[colorAttachments[i]] + if (colorAttachment instanceof WebGLTexture) { + if (colorAttachment._format !== gl.RGBA || + !(colorAttachment._type === gl.UNSIGNED_BYTE || colorAttachment._type === gl.FLOAT)) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + colorAttached = true + const level = framebuffer._attachmentLevel[gl.COLOR_ATTACHMENT0] + width.push(colorAttachment._levelWidth[level]) + height.push(colorAttachment._levelHeight[level]) + } else if (colorAttachment instanceof WebGLRenderbuffer) { + const format = colorAttachment._format + if (format !== gl.RGBA4 && + format !== gl.RGB565 && + format !== gl.RGB5_A1) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + colorAttached = true + width.push(colorAttachment._width) + height.push(colorAttachment._height) + } + } + + if (!colorAttached && + !stencilAttachment && + !depthAttachment && + !depthStencilAttachment) { + return gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT + } + + if (width.length <= 0 || height.length <= 0) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + + for (let i = 1; i < width.length; ++i) { + if (width[i - 1] !== width[i] || + height[i - 1] !== height[i]) { + return gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS + } + } + + if (width[0] === 0 || height[0] === 0) { + return gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT + } + + framebuffer._width = width[0] + framebuffer._height = height[0] + + return gl.FRAMEBUFFER_COMPLETE + } + + _isConstantBlendFunc (factor) { + return ( + factor === gl.CONSTANT_COLOR || + factor === gl.ONE_MINUS_CONSTANT_COLOR || + factor === gl.CONSTANT_ALPHA || + factor === gl.ONE_MINUS_CONSTANT_ALPHA) + } + + _isObject (object, method, Wrapper) { + if (!(object === null || object === undefined) && + !(object instanceof Wrapper)) { + throw new TypeError(method + '(' + Wrapper.name + ')') + } + if (this._checkValid(object, Wrapper) && this._checkOwns(object)) { + return true + } + return false + } + + _resizeDrawingBuffer (width, height) { + const prevFramebuffer = this._activeFramebuffer + const prevTexture = this._getActiveTexture(gl.TEXTURE_2D) + const prevRenderbuffer = this._activeRenderbuffer + + const contextAttributes = this._contextAttributes + + const drawingBuffer = this._drawingBuffer + super.bindFramebuffer(gl.FRAMEBUFFER, drawingBuffer._framebuffer) + const attachments = this._getAttachments() + // Clear all attachments + for (let i = 0; i < attachments.length; ++i) { + super.framebufferTexture2D( + gl.FRAMEBUFFER, + attachments[i], + gl.TEXTURE_2D, + 0, + 0) + } + + // Update color attachment + super.bindTexture(gl.TEXTURE_2D, drawingBuffer._color) + const colorFormat = contextAttributes.alpha ? gl.RGBA : gl.RGB + super.texImage2D( + gl.TEXTURE_2D, + 0, + colorFormat, + width, + height, + 0, + colorFormat, + gl.UNSIGNED_BYTE, + null) + super.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) + super.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) + super.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + drawingBuffer._color, + 0) + + // Update depth-stencil attachments if needed + let storage = 0 + let attachment = 0 + if (contextAttributes.depth && contextAttributes.stencil) { + storage = gl.DEPTH_STENCIL + attachment = gl.DEPTH_STENCIL_ATTACHMENT + } else if (contextAttributes.depth) { + storage = 0x81A7 + attachment = gl.DEPTH_ATTACHMENT + } else if (contextAttributes.stencil) { + storage = gl.STENCIL_INDEX8 + attachment = gl.STENCIL_ATTACHMENT + } + + if (storage) { + super.bindRenderbuffer( + gl.RENDERBUFFER, + drawingBuffer._depthStencil) + super.renderbufferStorage( + gl.RENDERBUFFER, + storage, + width, + height) + super.framebufferRenderbuffer( + gl.FRAMEBUFFER, + attachment, + gl.RENDERBUFFER, + drawingBuffer._depthStencil) + } + + // Restore previous binding state + this.bindFramebuffer(gl.FRAMEBUFFER, prevFramebuffer) + this.bindTexture(gl.TEXTURE_2D, prevTexture) + this.bindRenderbuffer(gl.RENDERBUFFER, prevRenderbuffer) + } + + _restoreError (lastError) { + const topError = this._errorStack.pop() + if (topError === gl.NO_ERROR) { + this.setError(lastError) + } else { + this.setError(topError) + } + } + + _saveError () { + this._errorStack.push(this.getError()) + } + + _switchActiveBuffer (active, buffer) { + if (active !== buffer) { + if (active) { + active._refCount -= 1 + active._checkDelete() + } + if (buffer) { + buffer._refCount += 1 + } + } + } + + _switchActiveProgram (active) { + if (active) { + active._refCount -= 1 + active._checkDelete() + } + } + + _tryDetachFramebuffer (framebuffer, renderbuffer) { + // FIXME: Does the texture get unbound from *all* framebuffers, or just the + // active FBO? + if (framebuffer && framebuffer._linked(renderbuffer)) { + const attachments = this._getAttachments() + const framebufferAttachments = Object.keys(framebuffer._attachments) + for (let i = 0; i < framebufferAttachments.length; ++i) { + if (framebuffer._attachments[attachments[i]] === renderbuffer) { + this.framebufferTexture2D( + gl.FRAMEBUFFER, + attachments[i] | 0, + gl.TEXTURE_2D, + null) + } + } + } + } + + _updateFramebufferAttachments (framebuffer) { + const prevStatus = framebuffer._status + const attachments = this._getAttachments() + framebuffer._status = this._preCheckFramebufferStatus(framebuffer) + if (framebuffer._status !== gl.FRAMEBUFFER_COMPLETE) { + if (prevStatus === gl.FRAMEBUFFER_COMPLETE) { + for (let i = 0; i < attachments.length; ++i) { + const attachmentEnum = attachments[i] + super.framebufferTexture2D( + gl.FRAMEBUFFER, + attachmentEnum, + framebuffer._attachmentFace[attachmentEnum], + 0, + framebuffer._attachmentLevel[attachmentEnum]) + } + } + return + } + + for (let i = 0; i < attachments.length; ++i) { + const attachmentEnum = attachments[i] + super.framebufferTexture2D( + gl.FRAMEBUFFER, + attachmentEnum, + framebuffer._attachmentFace[attachmentEnum], + 0, + framebuffer._attachmentLevel[attachmentEnum]) + } + + for (let i = 0; i < attachments.length; ++i) { + const attachmentEnum = attachments[i] + const attachment = framebuffer._attachments[attachmentEnum] + if (attachment instanceof WebGLTexture) { + super.framebufferTexture2D( + gl.FRAMEBUFFER, + attachmentEnum, + framebuffer._attachmentFace[attachmentEnum], + attachment._ | 0, + framebuffer._attachmentLevel[attachmentEnum]) + } else if (attachment instanceof WebGLRenderbuffer) { + super.framebufferRenderbuffer( + gl.FRAMEBUFFER, + attachmentEnum, + gl.RENDERBUFFER, + attachment._ | 0) + } + } + } + + _validBlendFunc (factor) { + return factor === gl.ZERO || + factor === gl.ONE || + factor === gl.SRC_COLOR || + factor === gl.ONE_MINUS_SRC_COLOR || + factor === gl.DST_COLOR || + factor === gl.ONE_MINUS_DST_COLOR || + factor === gl.SRC_ALPHA || + factor === gl.ONE_MINUS_SRC_ALPHA || + factor === gl.DST_ALPHA || + factor === gl.ONE_MINUS_DST_ALPHA || + factor === gl.SRC_ALPHA_SATURATE || + factor === gl.CONSTANT_COLOR || + factor === gl.ONE_MINUS_CONSTANT_COLOR || + factor === gl.CONSTANT_ALPHA || + factor === gl.ONE_MINUS_CONSTANT_ALPHA + } + + _validBlendMode (mode) { + return mode === gl.FUNC_ADD || + mode === gl.FUNC_SUBTRACT || + mode === gl.FUNC_REVERSE_SUBTRACT || + (this._extensions.ext_blend_minmax && ( + mode === this._extensions.ext_blend_minmax.MIN_EXT || + mode === this._extensions.ext_blend_minmax.MAX_EXT)) + } + + _validCubeTarget (target) { + return target === gl.TEXTURE_CUBE_MAP_POSITIVE_X || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_X || + target === gl.TEXTURE_CUBE_MAP_POSITIVE_Y || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_Y || + target === gl.TEXTURE_CUBE_MAP_POSITIVE_Z || + target === gl.TEXTURE_CUBE_MAP_NEGATIVE_Z + } + + _validFramebufferAttachment (attachment) { + switch (attachment) { + case gl.DEPTH_ATTACHMENT: + case gl.STENCIL_ATTACHMENT: + case gl.DEPTH_STENCIL_ATTACHMENT: + case gl.COLOR_ATTACHMENT0: + return true + } + + if (this._extensions.webgl_draw_buffers) { // eslint-disable-line + const { webgl_draw_buffers } = this._extensions; // eslint-disable-line + return attachment < (webgl_draw_buffers.COLOR_ATTACHMENT0_WEBGL + webgl_draw_buffers._maxDrawBuffers) // eslint-disable-line + } + + return false + } + + _validGLSLIdentifier (str) { + return !(str.indexOf('webgl_') === 0 || + str.indexOf('_webgl_') === 0 || + str.length > 256) + } + + _validTextureTarget (target) { + return target === gl.TEXTURE_2D || + target === gl.TEXTURE_CUBE_MAP + } + + _verifyTextureCompleteness (target, pname, param) { + const unit = this._getActiveTextureUnit() + let texture = null + if (target === gl.TEXTURE_2D) { + texture = unit._bind2D + } else if (this._validCubeTarget(target)) { + texture = unit._bindCube + } + + // oes_texture_float but not oes_texture_float_linear + if (this._extensions.oes_texture_float && !this._extensions.oes_texture_float_linear && texture && texture._type === gl.FLOAT && (pname === gl.TEXTURE_MAG_FILTER || pname === gl.TEXTURE_MIN_FILTER) && (param === gl.LINEAR || param === gl.LINEAR_MIPMAP_NEAREST || param === gl.NEAREST_MIPMAP_LINEAR || param === gl.LINEAR_MIPMAP_LINEAR)) { + texture._complete = false + this.bindTexture(target, texture) + return + } + + if (texture && texture._complete === false) { + texture._complete = true + this.bindTexture(target, texture) + } + } + + _wrapShader (type, source) { // eslint-disable-line + // the gl implementation seems to define `GL_OES_standard_derivatives` even when the extension is disabled + // this behaviour causes one conformance test ('GL_OES_standard_derivatives defined in shaders when extension is disabled') to fail + // by `undef`ing `GL_OES_standard_derivatives`, this appears to solve the issue + if (!this._extensions.oes_standard_derivatives && /#ifdef\s+GL_OES_standard_derivatives/.test(source)) { + source = '#undef GL_OES_standard_derivatives\n' + source + } + + return this._extensions.webgl_draw_buffers ? source : '#define gl_MaxDrawBuffers 1\n' + source // eslint-disable-line + } + + _beginAttrib0Hack () { + super.bindBuffer(gl.ARRAY_BUFFER, this._attrib0Buffer._) + super.bufferData( + gl.ARRAY_BUFFER, + this._vertexAttribs[0]._data, + gl.STREAM_DRAW) + super.enableVertexAttribArray(0) + super.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0) + super._vertexAttribDivisor(0, 1) + } + + _endAttrib0Hack () { + const attrib = this._vertexAttribs[0] + if (attrib._pointerBuffer) { + super.bindBuffer(gl.ARRAY_BUFFER, attrib._pointerBuffer._) + } else { + super.bindBuffer(gl.ARRAY_BUFFER, 0) + } + super.vertexAttribPointer( + 0, + attrib._inputSize, + attrib._pointerType, + attrib._pointerNormal, + attrib._inputStride, + attrib._pointerOffset) + super._vertexAttribDivisor(0, attrib._divisor) + super.disableVertexAttribArray(0) + if (this._activeArrayBuffer) { + super.bindBuffer(gl.ARRAY_BUFFER, this._activeArrayBuffer._) + } else { + super.bindBuffer(gl.ARRAY_BUFFER, 0) + } + } + + activeTexture (texture) { + texture |= 0 + const texNum = texture - gl.TEXTURE0 + if (texNum >= 0 && texNum < this._textureUnits.length) { + this._activeTextureUnit = texNum + return super.activeTexture(texture) + } + + this.setError(gl.INVALID_ENUM) + } + + attachShader (program, shader) { + if (!checkObject(program) || + !checkObject(shader)) { + throw new TypeError('attachShader(WebGLProgram, WebGLShader)') + } + if (!program || !shader) { + this.setError(gl.INVALID_VALUE) + return + } else if (program instanceof WebGLProgram && + shader instanceof WebGLShader && + this._checkOwns(program) && + this._checkOwns(shader)) { + if (!program._linked(shader)) { + this._saveError() + super.attachShader( + program._ | 0, + shader._ | 0) + const error = this.getError() + this._restoreError(error) + if (error === gl.NO_ERROR) { + program._link(shader) + } + return + } + } + this.setError(gl.INVALID_OPERATION) + } + + bindAttribLocation (program, index, name) { + if (!checkObject(program) || + typeof name !== 'string') { + throw new TypeError('bindAttribLocation(WebGLProgram, GLint, String)') + } + name += '' + if (!isValidString(name) || name.length > MAX_ATTRIBUTE_LENGTH) { + this.setError(gl.INVALID_VALUE) + } else if (/^_?webgl_a/.test(name)) { + this.setError(gl.INVALID_OPERATION) + } else if (this._checkWrapper(program, WebGLProgram)) { + return super.bindAttribLocation( + program._ | 0, + index | 0, + name) + } + } + + bindFramebuffer (target, framebuffer) { + if (!checkObject(framebuffer)) { + throw new TypeError('bindFramebuffer(GLenum, WebGLFramebuffer)') + } + if (target !== gl.FRAMEBUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + if (!framebuffer) { + super.bindFramebuffer( + gl.FRAMEBUFFER, + this._drawingBuffer._framebuffer) + } else if (framebuffer._pendingDelete) { + return + } else if (this._checkWrapper(framebuffer, WebGLFramebuffer)) { + super.bindFramebuffer( + gl.FRAMEBUFFER, + framebuffer._ | 0) + } else { + return + } + const activeFramebuffer = this._activeFramebuffer + if (activeFramebuffer !== framebuffer) { + if (activeFramebuffer) { + activeFramebuffer._refCount -= 1 + activeFramebuffer._checkDelete() + } + if (framebuffer) { + framebuffer._refCount += 1 + } + } + this._activeFramebuffer = framebuffer + if (framebuffer) { + this._updateFramebufferAttachments(framebuffer) + } + } + + bindBuffer (target, buffer) { + target |= 0 + if (!checkObject(buffer)) { + throw new TypeError('bindBuffer(GLenum, WebGLBuffer)') + } + if (target !== gl.ARRAY_BUFFER && + target !== gl.ELEMENT_ARRAY_BUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + if (!buffer) { + super.bindBuffer(target, 0) + } else if (buffer._pendingDelete) { + return + } else if (this._checkWrapper(buffer, WebGLBuffer)) { + if (buffer._binding && buffer._binding !== target) { + this.setError(gl.INVALID_OPERATION) + return + } + buffer._binding = target | 0 + + super.bindBuffer(target, buffer._ | 0) + } else { + return + } + + if (target === gl.ARRAY_BUFFER) { + this._switchActiveBuffer(this._activeArrayBuffer, buffer) + this._activeArrayBuffer = buffer + } else { + this._switchActiveBuffer(this._activeElementArrayBuffer, buffer) + this._activeElementArrayBuffer = buffer + } + } + + bindRenderbuffer (target, object) { + if (!checkObject(object)) { + throw new TypeError('bindRenderbuffer(GLenum, WebGLRenderbuffer)') + } + + if (target !== gl.RENDERBUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + if (!object) { + super.bindRenderbuffer( + target | 0, + 0) + } else if (object._pendingDelete) { + return + } else if (this._checkWrapper(object, WebGLRenderbuffer)) { + super.bindRenderbuffer( + target | 0, + object._ | 0) + } else { + return + } + const active = this._activeRenderbuffer + if (active !== object) { + if (active) { + active._refCount -= 1 + active._checkDelete() + } + if (object) { + object._refCount += 1 + } + } + this._activeRenderbuffer = object + } + + bindTexture (target, texture) { + target |= 0 + + if (!checkObject(texture)) { + throw new TypeError('bindTexture(GLenum, WebGLTexture)') + } + + if (!this._validTextureTarget(target)) { + this.setError(gl.INVALID_ENUM) + return + } + + // Get texture id + let textureId = 0 + if (!texture) { + texture = null + } else if (texture instanceof WebGLTexture && + texture._pendingDelete) { + // Special case: error codes for deleted textures don't get set for some dumb reason + return + } else if (this._checkWrapper(texture, WebGLTexture)) { + // Check binding mode of texture + if (texture._binding && texture._binding !== target) { + this.setError(gl.INVALID_OPERATION) + return + } + texture._binding = target + + if (texture._complete) { + textureId = texture._ | 0 + } + } else { + return + } + + this._saveError() + super.bindTexture( + target, + textureId) + const error = this.getError() + this._restoreError(error) + + if (error !== gl.NO_ERROR) { + return + } + + const activeUnit = this._getActiveTextureUnit() + const activeTex = this._getActiveTexture(target) + + // Update references + if (activeTex !== texture) { + if (activeTex) { + activeTex._refCount -= 1 + activeTex._checkDelete() + } + if (texture) { + texture._refCount += 1 + } + } + + if (target === gl.TEXTURE_2D) { + activeUnit._bind2D = texture + } else if (target === gl.TEXTURE_CUBE_MAP) { + activeUnit._bindCube = texture + } + } + + blendColor (red, green, blue, alpha) { + return super.blendColor(+red, +green, +blue, +alpha) + } + + blendEquation (mode) { + mode |= 0 + if (this._validBlendMode(mode)) { + return super.blendEquation(mode) + } + this.setError(gl.INVALID_ENUM) + } + + blendEquationSeparate (modeRGB, modeAlpha) { + modeRGB |= 0 + modeAlpha |= 0 + if (this._validBlendMode(modeRGB) && this._validBlendMode(modeAlpha)) { + return super.blendEquationSeparate(modeRGB, modeAlpha) + } + this.setError(gl.INVALID_ENUM) + } + + createBuffer () { + const id = super.createBuffer() + if (id <= 0) return null + const webGLBuffer = new WebGLBuffer(id, this) + this._buffers[id] = webGLBuffer + return webGLBuffer + } + + createFramebuffer () { + const id = super.createFramebuffer() + if (id <= 0) return null + const webGLFramebuffer = new WebGLFramebuffer(id, this) + this._framebuffers[id] = webGLFramebuffer + return webGLFramebuffer + } + + createProgram () { + const id = super.createProgram() + if (id <= 0) return null + const webGLProgram = new WebGLProgram(id, this) + this._programs[id] = webGLProgram + return webGLProgram + } + + createRenderbuffer () { + const id = super.createRenderbuffer() + if (id <= 0) return null + const webGLRenderbuffer = new WebGLRenderbuffer(id, this) + this._renderbuffers[id] = webGLRenderbuffer + return webGLRenderbuffer + } + + createTexture () { + const id = super.createTexture() + if (id <= 0) return null + const webGlTexture = new WebGLTexture(id, this) + this._textures[id] = webGlTexture + return webGlTexture + } + + getContextAttributes () { + return this._contextAttributes + } + + getExtension (name) { + const str = name.toLowerCase() + if (str in this._extensions) { + return this._extensions[str] + } + const ext = availableExtensions[str] ? availableExtensions[str](this) : null + if (ext) { + this._extensions[str] = ext + } + return ext + } + + getSupportedExtensions () { + const exts = [ + 'ANGLE_instanced_arrays', + 'STACKGL_resize_drawingbuffer', + 'STACKGL_destroy_context' + ] + + const supportedExts = super.getSupportedExtensions() + + if (supportedExts.indexOf('GL_OES_element_index_uint') >= 0) { + exts.push('OES_element_index_uint') + } + + if (supportedExts.indexOf('GL_OES_standard_derivatives') >= 0) { + exts.push('OES_standard_derivatives') + } + + if (supportedExts.indexOf('GL_OES_texture_float') >= 0) { + exts.push('OES_texture_float') + } + + if (supportedExts.indexOf('GL_OES_texture_float_linear') >= 0) { + exts.push('OES_texture_float_linear') + } + + if (supportedExts.indexOf('EXT_draw_buffers') >= 0) { + exts.push('WEBGL_draw_buffers') + } + + if (supportedExts.indexOf('EXT_blend_minmax') >= 0) { + exts.push('EXT_blend_minmax') + } + + if (supportedExts.indexOf('EXT_texture_filter_anisotropic') >= 0) { + exts.push('EXT_texture_filter_anisotropic') + } + + return exts + } + + setError (error) { + NativeWebGL.setError.call(this, error | 0) + } + + blendFunc (sfactor, dfactor) { + sfactor |= 0 + dfactor |= 0 + if (!this._validBlendFunc(sfactor) || + !this._validBlendFunc(dfactor)) { + this.setError(gl.INVALID_ENUM) + return + } + if (this._isConstantBlendFunc(sfactor) && this._isConstantBlendFunc(dfactor)) { + this.setError(gl.INVALID_OPERATION) + return + } + super.blendFunc(sfactor, dfactor) + } + + blendFuncSeparate ( + srcRGB, + dstRGB, + srcAlpha, + dstAlpha) { + srcRGB |= 0 + dstRGB |= 0 + srcAlpha |= 0 + dstAlpha |= 0 + + if (!(this._validBlendFunc(srcRGB) && + this._validBlendFunc(dstRGB) && + this._validBlendFunc(srcAlpha) && + this._validBlendFunc(dstAlpha))) { + this.setError(gl.INVALID_ENUM) + return + } + + if ((this._isConstantBlendFunc(srcRGB) && this._isConstantBlendFunc(dstRGB)) || + (this._isConstantBlendFunc(srcAlpha) && this._isConstantBlendFunc(dstAlpha))) { + this.setError(gl.INVALID_OPERATION) + return + } + + super.blendFuncSeparate( + srcRGB, + dstRGB, + srcAlpha, + dstAlpha) + } + + bufferData (target, data, usage) { + target |= 0 + usage |= 0 + if (usage !== gl.STREAM_DRAW && + usage !== gl.STATIC_DRAW && + usage !== gl.DYNAMIC_DRAW) { + this.setError(gl.INVALID_ENUM) + return + } + + if (target !== gl.ARRAY_BUFFER && + target !== gl.ELEMENT_ARRAY_BUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + const active = this._getActiveBuffer(target) + if (!active) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (typeof data === 'object') { + let u8Data = null + if (isTypedArray(data)) { + u8Data = unpackTypedArray(data) + } else if (data instanceof ArrayBuffer) { + u8Data = new Uint8Array(data) + } else { + this.setError(gl.INVALID_VALUE) + return + } + + this._saveError() + super.bufferData( + target, + u8Data, + usage) + const error = this.getError() + this._restoreError(error) + if (error !== gl.NO_ERROR) { + return + } + + active._size = u8Data.length + if (target === gl.ELEMENT_ARRAY_BUFFER) { + active._elements = new Uint8Array(u8Data) + } + } else if (typeof data === 'number') { + const size = data | 0 + if (size < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + this._saveError() + super.bufferData( + target, + size, + usage) + const error = this.getError() + this._restoreError(error) + if (error !== gl.NO_ERROR) { + return + } + + active._size = size + if (target === gl.ELEMENT_ARRAY_BUFFER) { + active._elements = new Uint8Array(size) + } + } else { + this.setError(gl.INVALID_VALUE) + } + } + + bufferSubData (target, offset, data) { + target |= 0 + offset |= 0 + + if (target !== gl.ARRAY_BUFFER && + target !== gl.ELEMENT_ARRAY_BUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + if (data === null) { + return + } + + if (!data || typeof data !== 'object') { + this.setError(gl.INVALID_VALUE) + return + } + + const active = this._getActiveBuffer(target) + if (!active) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (offset < 0 || offset >= active._size) { + this.setError(gl.INVALID_VALUE) + return + } + + let u8Data = null + if (isTypedArray(data)) { + u8Data = unpackTypedArray(data) + } else if (data instanceof ArrayBuffer) { + u8Data = new Uint8Array(data) + } else { + this.setError(gl.INVALID_VALUE) + return + } + + if (offset + u8Data.length > active._size) { + this.setError(gl.INVALID_VALUE) + return + } + + if (target === gl.ELEMENT_ARRAY_BUFFER) { + active._elements.set(u8Data, offset) + } + + super.bufferSubData( + target, + offset, + u8Data) + } + + checkFramebufferStatus (target) { + if (target !== gl.FRAMEBUFFER) { + this.setError(gl.INVALID_ENUM) + return 0 + } + + const framebuffer = this._activeFramebuffer + if (!framebuffer) { + return gl.FRAMEBUFFER_COMPLETE + } + + return this._preCheckFramebufferStatus(framebuffer) + } + + clear (mask) { + if (!this._framebufferOk()) { + return + } + return super.clear(mask | 0) + } + + clearColor (red, green, blue, alpha) { + return super.clearColor(+red, +green, +blue, +alpha) + } + + clearDepth (depth) { + return super.clearDepth(+depth) + } + + clearStencil (s) { + this._checkStencil = false + return super.clearStencil(s | 0) + } + + colorMask (red, green, blue, alpha) { + return super.colorMask(!!red, !!green, !!blue, !!alpha) + } + + compileShader (shader) { + if (!checkObject(shader)) { + throw new TypeError('compileShader(WebGLShader)') + } + if (this._checkWrapper(shader, WebGLShader) && + this._checkShaderSource(shader)) { + const prevError = this.getError() + super.compileShader(shader._ | 0) + const error = this.getError() + shader._compileStatus = !!super.getShaderParameter( + shader._ | 0, + gl.COMPILE_STATUS) + shader._compileInfo = super.getShaderInfoLog(shader._ | 0) + this.getError() + this.setError(prevError || error) + } + } + + copyTexImage2D ( + target, + level, + internalFormat, + x, y, width, height, + border) { + target |= 0 + level |= 0 + internalFormat |= 0 + x |= 0 + y |= 0 + width |= 0 + height |= 0 + border |= 0 + + const texture = this._getTexImage(target) + if (!texture) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (internalFormat !== gl.RGBA && + internalFormat !== gl.RGB && + internalFormat !== gl.ALPHA && + internalFormat !== gl.LUMINANCE && + internalFormat !== gl.LUMINANCE_ALPHA) { + this.setError(gl.INVALID_ENUM) + return + } + + if (level < 0 || width < 0 || height < 0 || border !== 0) { + this.setError(gl.INVALID_VALUE) + return + } + + if (level > 0 && !(bits.isPow2(width) && bits.isPow2(height))) { + this.setError(gl.INVALID_VALUE) + return + } + + this._saveError() + super.copyTexImage2D( + target, + level, + internalFormat, + x, + y, + width, + height, + border) + const error = this.getError() + this._restoreError(error) + + if (error === gl.NO_ERROR) { + texture._levelWidth[level] = width + texture._levelHeight[level] = height + texture._format = gl.RGBA + texture._type = gl.UNSIGNED_BYTE + } + } + + copyTexSubImage2D ( + target, + level, + xoffset, yoffset, + x, y, width, height) { + target |= 0 + level |= 0 + xoffset |= 0 + yoffset |= 0 + x |= 0 + y |= 0 + width |= 0 + height |= 0 + + const texture = this._getTexImage(target) + if (!texture) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (width < 0 || height < 0 || xoffset < 0 || yoffset < 0 || level < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + super.copyTexSubImage2D( + target, + level, + xoffset, + yoffset, + x, + y, + width, + height) + } + + cullFace (mode) { + return super.cullFace(mode | 0) + } + + createShader (type) { + type |= 0 + if (type !== gl.FRAGMENT_SHADER && + type !== gl.VERTEX_SHADER) { + this.setError(gl.INVALID_ENUM) + return null + } + const id = super.createShader(type) + if (id < 0) { + return null + } + const result = new WebGLShader(id, this, type) + this._shaders[id] = result + return result + } + + deleteProgram (object) { + return this._deleteLinkable('deleteProgram', object, WebGLProgram) + } + + deleteShader (object) { + return this._deleteLinkable('deleteShader', object, WebGLShader) + } + + _deleteLinkable (name, object, Type) { + if (!checkObject(object)) { + throw new TypeError(name + '(' + Type.name + ')') + } + if (object instanceof Type && + this._checkOwns(object)) { + object._pendingDelete = true + object._checkDelete() + return + } + this.setError(gl.INVALID_OPERATION) + } + + deleteBuffer (buffer) { + if (!checkObject(buffer) || + (buffer !== null && !(buffer instanceof WebGLBuffer))) { + throw new TypeError('deleteBuffer(WebGLBuffer)') + } + + if (!(buffer instanceof WebGLBuffer && + this._checkOwns(buffer))) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (this._activeArrayBuffer === buffer) { + this.bindBuffer(gl.ARRAY_BUFFER, null) + } + if (this._activeElementArrayBuffer === buffer) { + this.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null) + } + + for (let i = 0; i < this._vertexAttribs.length; ++i) { + const attrib = this._vertexAttribs[i] + if (attrib._pointerBuffer === buffer) { + attrib._pointerBuffer = null + attrib._pointerStride = 0 + attrib._pointerOffset = 0 + attrib._pointerSize = 4 + buffer._refCount -= 1 + } + } + + buffer._pendingDelete = true + buffer._checkDelete() + } + + deleteFramebuffer (framebuffer) { + if (!checkObject(framebuffer)) { + throw new TypeError('deleteFramebuffer(WebGLFramebuffer)') + } + + if (!(framebuffer instanceof WebGLFramebuffer && + this._checkOwns(framebuffer))) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (this._activeFramebuffer === framebuffer) { + this.bindFramebuffer(gl.FRAMEBUFFER, null) + } + + framebuffer._pendingDelete = true + framebuffer._checkDelete() + } + + // Need to handle textures and render buffers as a special case: + // When a texture gets deleted, we need to do the following extra steps: + // 1. Is it bound to the current texture unit? + // If so, then unbind it + // 2. Is it attached to the active fbo? + // If so, then detach it + // + // For renderbuffers only need to do second step + // + // After this, proceed with the usual deletion algorithm + // + deleteRenderbuffer (renderbuffer) { + if (!checkObject(renderbuffer)) { + throw new TypeError('deleteRenderbuffer(WebGLRenderbuffer)') + } + + if (!(renderbuffer instanceof WebGLRenderbuffer && + this._checkOwns(renderbuffer))) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (this._activeRenderbuffer === renderbuffer) { + this.bindRenderbuffer(gl.RENDERBUFFER, null) + } + + const activeFramebuffer = this._activeFramebuffer + + this._tryDetachFramebuffer(activeFramebuffer, renderbuffer) + + renderbuffer._pendingDelete = true + renderbuffer._checkDelete() + } + + deleteTexture (texture) { + if (!checkObject(texture)) { + throw new TypeError('deleteTexture(WebGLTexture)') + } + + if (texture instanceof WebGLTexture) { + if (!this._checkOwns(texture)) { + this.setError(gl.INVALID_OPERATION) + return + } + } else { + return + } + + // Unbind from all texture units + const curActive = this._activeTextureUnit + + for (let i = 0; i < this._textureUnits.length; ++i) { + const unit = this._textureUnits[i] + if (unit._bind2D === texture) { + this.activeTexture(gl.TEXTURE0 + i) + this.bindTexture(gl.TEXTURE_2D, null) + } else if (unit._bindCube === texture) { + this.activeTexture(gl.TEXTURE0 + i) + this.bindTexture(gl.TEXTURE_CUBE_MAP, null) + } + } + this.activeTexture(gl.TEXTURE0 + curActive) + + // FIXME: Does the texture get unbound from *all* framebuffers, or just the + // active FBO? + const ctx = this + const activeFramebuffer = this._activeFramebuffer + function tryDetach (framebuffer) { + if (framebuffer && framebuffer._linked(texture)) { + const attachments = ctx._getAttachments() + for (let i = 0; i < attachments.length; ++i) { + const attachment = attachments[i] + if (framebuffer._attachments[attachment] === texture) { + ctx.framebufferTexture2D( + gl.FRAMEBUFFER, + attachment, + gl.TEXTURE_2D, + null) + } + } + } + } + + tryDetach(activeFramebuffer) + + // Mark texture for deletion + texture._pendingDelete = true + texture._checkDelete() + } + + depthFunc (func) { + func |= 0 + switch (func) { + case gl.NEVER: + case gl.LESS: + case gl.EQUAL: + case gl.LEQUAL: + case gl.GREATER: + case gl.NOTEQUAL: + case gl.GEQUAL: + case gl.ALWAYS: + return super.depthFunc(func) + default: + this.setError(gl.INVALID_ENUM) + } + } + + depthMask (flag) { + return super.depthMask(!!flag) + } + + depthRange (zNear, zFar) { + zNear = +zNear + zFar = +zFar + if (zNear <= zFar) { + return super.depthRange(zNear, zFar) + } + this.setError(gl.INVALID_OPERATION) + } + + destroy () { + super.destroy() + } + + detachShader (program, shader) { + if (!checkObject(program) || + !checkObject(shader)) { + throw new TypeError('detachShader(WebGLProgram, WebGLShader)') + } + if (this._checkWrapper(program, WebGLProgram) && + this._checkWrapper(shader, WebGLShader)) { + if (program._linked(shader)) { + super.detachShader(program._, shader._) + program._unlink(shader) + } else { + this.setError(gl.INVALID_OPERATION) + } + } + } + + disable (cap) { + cap |= 0 + super.disable(cap) + if (cap === gl.TEXTURE_2D || + cap === gl.TEXTURE_CUBE_MAP) { + const active = this._getActiveTextureUnit() + if (active._mode === cap) { + active._mode = 0 + } + } + } + + disableVertexAttribArray (index) { + index |= 0 + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return + } + super.disableVertexAttribArray(index) + this._vertexAttribs[index]._isPointer = false + } + + drawArrays (mode, first, count) { + mode |= 0 + first |= 0 + count |= 0 + + if (first < 0 || count < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + if (!this._checkStencilState()) { + return + } + + const reducedCount = vertexCount(mode, count) + if (reducedCount < 0) { + this.setError(gl.INVALID_ENUM) + return + } + + if (!this._framebufferOk()) { + return + } + + if (count === 0) { + return + } + + let maxIndex = first + if (count > 0) { + maxIndex = (count + first - 1) >>> 0 + } + if (this._checkVertexAttribState(maxIndex)) { + if ( + this._vertexAttribs[0]._isPointer || ( + this._extensions.webgl_draw_buffers && + this._extensions.webgl_draw_buffers._buffersState && + this._extensions.webgl_draw_buffers._buffersState.length > 0 + ) + ) { + return super.drawArrays(mode, first, reducedCount) + } else { + this._beginAttrib0Hack() + super._drawArraysInstanced(mode, first, reducedCount, 1) + this._endAttrib0Hack() + } + } + } + + drawElements (mode, count, type, ioffset) { + mode |= 0 + count |= 0 + type |= 0 + ioffset |= 0 + + if (count < 0 || ioffset < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + if (!this._checkStencilState()) { + return + } + + const elementBuffer = this._activeElementArrayBuffer + if (!elementBuffer) { + this.setError(gl.INVALID_OPERATION) + return + } + + // Unpack element data + let elementData = null + let offset = ioffset + if (type === gl.UNSIGNED_SHORT) { + if (offset % 2) { + this.setError(gl.INVALID_OPERATION) + return + } + offset >>= 1 + elementData = new Uint16Array(elementBuffer._elements.buffer) + } else if (this._extensions.oes_element_index_uint && type === gl.UNSIGNED_INT) { + if (offset % 4) { + this.setError(gl.INVALID_OPERATION) + return + } + offset >>= 2 + elementData = new Uint32Array(elementBuffer._elements.buffer) + } else if (type === gl.UNSIGNED_BYTE) { + elementData = elementBuffer._elements + } else { + this.setError(gl.INVALID_ENUM) + return + } + + let reducedCount = count + switch (mode) { + case gl.TRIANGLES: + if (count % 3) { + reducedCount -= (count % 3) + } + break + case gl.LINES: + if (count % 2) { + reducedCount -= (count % 2) + } + break + case gl.POINTS: + break + case gl.LINE_LOOP: + case gl.LINE_STRIP: + if (count < 2) { + this.setError(gl.INVALID_OPERATION) + return + } + break + case gl.TRIANGLE_FAN: + case gl.TRIANGLE_STRIP: + if (count < 3) { + this.setError(gl.INVALID_OPERATION) + return + } + break + default: + this.setError(gl.INVALID_ENUM) + return + } + + if (!this._framebufferOk()) { + return + } + + if (count === 0) { + this._checkVertexAttribState(0) + return + } + + if ((count + offset) >>> 0 > elementData.length) { + this.setError(gl.INVALID_OPERATION) + return + } + + // Compute max index + let maxIndex = -1 + for (let i = offset; i < offset + count; ++i) { + maxIndex = Math.max(maxIndex, elementData[i]) + } + + if (maxIndex < 0) { + this._checkVertexAttribState(0) + return + } + + if (this._checkVertexAttribState(maxIndex)) { + if (reducedCount > 0) { + if (this._vertexAttribs[0]._isPointer) { + return super.drawElements(mode, reducedCount, type, ioffset) + } else { + this._beginAttrib0Hack() + super._drawElementsInstanced(mode, reducedCount, type, ioffset, 1) + this._endAttrib0Hack() + } + } + } + } + + enable (cap) { + cap |= 0 + super.enable(cap) + } + + enableVertexAttribArray (index) { + index |= 0 + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return + } + + super.enableVertexAttribArray(index) + + this._vertexAttribs[index]._isPointer = true + } + + finish () { + return super.finish() + } + + flush () { + return super.flush() + } + + framebufferRenderbuffer ( + target, + attachment, + renderbufferTarget, + renderbuffer) { + target = target | 0 + attachment = attachment | 0 + renderbufferTarget = renderbufferTarget | 0 + + if (!checkObject(renderbuffer)) { + throw new TypeError('framebufferRenderbuffer(GLenum, GLenum, GLenum, WebGLRenderbuffer)') + } + + if (target !== gl.FRAMEBUFFER || + !this._validFramebufferAttachment(attachment) || + renderbufferTarget !== gl.RENDERBUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + const framebuffer = this._activeFramebuffer + if (!framebuffer) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (renderbuffer && !this._checkWrapper(renderbuffer, WebGLRenderbuffer)) { + return + } + + framebuffer._setAttachment(renderbuffer, attachment) + this._updateFramebufferAttachments(framebuffer) + } + + framebufferTexture2D ( + target, + attachment, + textarget, + texture, + level) { + target |= 0 + attachment |= 0 + textarget |= 0 + level |= 0 + if (!checkObject(texture)) { + throw new TypeError('framebufferTexture2D(GLenum, GLenum, GLenum, WebGLTexture, GLint)') + } + + // Check parameters are ok + if (target !== gl.FRAMEBUFFER || + !this._validFramebufferAttachment(attachment)) { + this.setError(gl.INVALID_ENUM) + return + } + + if (level !== 0) { + this.setError(gl.INVALID_VALUE) + return + } + + // Check object ownership + if (texture && !this._checkWrapper(texture, WebGLTexture)) { + return + } + + // Check texture target is ok + if (textarget === gl.TEXTURE_2D) { + if (texture && texture._binding !== gl.TEXTURE_2D) { + this.setError(gl.INVALID_OPERATION) + return + } + } else if (this._validCubeTarget(textarget)) { + if (texture && texture._binding !== gl.TEXTURE_CUBE_MAP) { + this.setError(gl.INVALID_OPERATION) + return + } + } else { + this.setError(gl.INVALID_ENUM) + return + } + + // Check a framebuffer is actually bound + const framebuffer = this._activeFramebuffer + if (!framebuffer) { + this.setError(gl.INVALID_OPERATION) + return + } + + framebuffer._attachmentLevel[attachment] = level + framebuffer._attachmentFace[attachment] = textarget + framebuffer._setAttachment(texture, attachment) + this._updateFramebufferAttachments(framebuffer) + } + + frontFace (mode) { + return super.frontFace(mode | 0) + } + + generateMipmap (target) { + return super.generateMipmap(target | 0) | 0 + } + + getActiveAttrib (program, index) { + if (!checkObject(program)) { + throw new TypeError('getActiveAttrib(WebGLProgram)') + } else if (!program) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(program, WebGLProgram)) { + const info = super.getActiveAttrib(program._ | 0, index | 0) + if (info) { + return new WebGLActiveInfo(info) + } + } + return null + } + + getActiveUniform (program, index) { + if (!checkObject(program)) { + throw new TypeError('getActiveUniform(WebGLProgram, GLint)') + } else if (!program) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(program, WebGLProgram)) { + const info = super.getActiveUniform(program._ | 0, index | 0) + if (info) { + return new WebGLActiveInfo(info) + } + } + return null + } + + getAttachedShaders (program) { + if (!checkObject(program) || + (typeof program === 'object' && + program !== null && + !(program instanceof WebGLProgram))) { + throw new TypeError('getAttachedShaders(WebGLProgram)') + } + if (!program) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(program, WebGLProgram)) { + const shaderArray = super.getAttachedShaders(program._ | 0) + if (!shaderArray) { + return null + } + const unboxedShaders = new Array(shaderArray.length) + for (let i = 0; i < shaderArray.length; ++i) { + unboxedShaders[i] = this._shaders[shaderArray[i]] + } + return unboxedShaders + } + return null + } + + getAttribLocation (program, name) { + if (!checkObject(program)) { + throw new TypeError('getAttribLocation(WebGLProgram, String)') + } + name += '' + if (!isValidString(name) || name.length > MAX_ATTRIBUTE_LENGTH) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(program, WebGLProgram)) { + return super.getAttribLocation(program._ | 0, name + '') + } + return -1 + } + + getParameter (pname) { + pname |= 0 + switch (pname) { + case gl.ARRAY_BUFFER_BINDING: + return this._activeArrayBuffer + case gl.ELEMENT_ARRAY_BUFFER_BINDING: + return this._activeElementArrayBuffer + case gl.CURRENT_PROGRAM: + return this._activeProgram + case gl.FRAMEBUFFER_BINDING: + return this._activeFramebuffer + case gl.RENDERBUFFER_BINDING: + return this._activeRenderbuffer + case gl.TEXTURE_BINDING_2D: + return this._getActiveTextureUnit()._bind2D + case gl.TEXTURE_BINDING_CUBE_MAP: + return this._getActiveTextureUnit()._bindCube + case gl.VERSION: + return 'WebGL 1.0 stack-gl ' + HEADLESS_VERSION + case gl.VENDOR: + return 'stack-gl' + case gl.RENDERER: + return 'ANGLE' + case gl.SHADING_LANGUAGE_VERSION: + return 'WebGL GLSL ES 1.0 stack-gl' + + case gl.COMPRESSED_TEXTURE_FORMATS: + return new Uint32Array(0) + + // Int arrays + case gl.MAX_VIEWPORT_DIMS: + case gl.SCISSOR_BOX: + case gl.VIEWPORT: + return new Int32Array(super.getParameter(pname)) + + // Float arrays + case gl.ALIASED_LINE_WIDTH_RANGE: + case gl.ALIASED_POINT_SIZE_RANGE: + case gl.DEPTH_RANGE: + case gl.BLEND_COLOR: + case gl.COLOR_CLEAR_VALUE: + return new Float32Array(super.getParameter(pname)) + + case gl.COLOR_WRITEMASK: + return super.getParameter(pname) + + case gl.DEPTH_CLEAR_VALUE: + case gl.LINE_WIDTH: + case gl.POLYGON_OFFSET_FACTOR: + case gl.POLYGON_OFFSET_UNITS: + case gl.SAMPLE_COVERAGE_VALUE: + return +super.getParameter(pname) + + case gl.BLEND: + case gl.CULL_FACE: + case gl.DEPTH_TEST: + case gl.DEPTH_WRITEMASK: + case gl.DITHER: + case gl.POLYGON_OFFSET_FILL: + case gl.SAMPLE_COVERAGE_INVERT: + case gl.SCISSOR_TEST: + case gl.STENCIL_TEST: + case gl.UNPACK_FLIP_Y_WEBGL: + case gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL: + return !!super.getParameter(pname) + + case gl.ACTIVE_TEXTURE: + case gl.ALPHA_BITS: + case gl.BLEND_DST_ALPHA: + case gl.BLEND_DST_RGB: + case gl.BLEND_EQUATION_ALPHA: + case gl.BLEND_EQUATION_RGB: + case gl.BLEND_SRC_ALPHA: + case gl.BLEND_SRC_RGB: + case gl.BLUE_BITS: + case gl.CULL_FACE_MODE: + case gl.DEPTH_BITS: + case gl.DEPTH_FUNC: + case gl.FRONT_FACE: + case gl.GENERATE_MIPMAP_HINT: + case gl.GREEN_BITS: + case gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS: + case gl.MAX_CUBE_MAP_TEXTURE_SIZE: + case gl.MAX_FRAGMENT_UNIFORM_VECTORS: + case gl.MAX_RENDERBUFFER_SIZE: + case gl.MAX_TEXTURE_IMAGE_UNITS: + case gl.MAX_TEXTURE_SIZE: + case gl.MAX_VARYING_VECTORS: + case gl.MAX_VERTEX_ATTRIBS: + case gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS: + case gl.MAX_VERTEX_UNIFORM_VECTORS: + case gl.PACK_ALIGNMENT: + case gl.RED_BITS: + case gl.SAMPLE_BUFFERS: + case gl.SAMPLES: + case gl.STENCIL_BACK_FAIL: + case gl.STENCIL_BACK_FUNC: + case gl.STENCIL_BACK_PASS_DEPTH_FAIL: + case gl.STENCIL_BACK_PASS_DEPTH_PASS: + case gl.STENCIL_BACK_REF: + case gl.STENCIL_BACK_VALUE_MASK: + case gl.STENCIL_BACK_WRITEMASK: + case gl.STENCIL_BITS: + case gl.STENCIL_CLEAR_VALUE: + case gl.STENCIL_FAIL: + case gl.STENCIL_FUNC: + case gl.STENCIL_PASS_DEPTH_FAIL: + case gl.STENCIL_PASS_DEPTH_PASS: + case gl.STENCIL_REF: + case gl.STENCIL_VALUE_MASK: + case gl.STENCIL_WRITEMASK: + case gl.SUBPIXEL_BITS: + case gl.UNPACK_ALIGNMENT: + case gl.UNPACK_COLORSPACE_CONVERSION_WEBGL: + return super.getParameter(pname) | 0 + + case gl.IMPLEMENTATION_COLOR_READ_FORMAT: + case gl.IMPLEMENTATION_COLOR_READ_TYPE: + return super.getParameter(pname) + + default: + if (this._extensions.webgl_draw_buffers) { + const ext = this._extensions.webgl_draw_buffers + switch (pname) { + case ext.DRAW_BUFFER0_WEBGL: + case ext.DRAW_BUFFER1_WEBGL: + case ext.DRAW_BUFFER2_WEBGL: + case ext.DRAW_BUFFER3_WEBGL: + case ext.DRAW_BUFFER4_WEBGL: + case ext.DRAW_BUFFER5_WEBGL: + case ext.DRAW_BUFFER6_WEBGL: + case ext.DRAW_BUFFER7_WEBGL: + case ext.DRAW_BUFFER8_WEBGL: + case ext.DRAW_BUFFER9_WEBGL: + case ext.DRAW_BUFFER10_WEBGL: + case ext.DRAW_BUFFER11_WEBGL: + case ext.DRAW_BUFFER12_WEBGL: + case ext.DRAW_BUFFER13_WEBGL: + case ext.DRAW_BUFFER14_WEBGL: + case ext.DRAW_BUFFER15_WEBGL: + if (ext._buffersState.length === 1 && ext._buffersState[0] === gl.BACK) { + return gl.BACK + } + return super.getParameter(pname) + case ext.MAX_DRAW_BUFFERS_WEBGL: + case ext.MAX_COLOR_ATTACHMENTS_WEBGL: + return super.getParameter(pname) + } + } + + if (this._extensions.oes_standard_derivatives && pname === this._extensions.oes_standard_derivatives.FRAGMENT_SHADER_DERIVATIVE_HINT_OES) { + return super.getParameter(pname) + } + + if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT) { + return super.getParameter(pname) + } + + this.setError(gl.INVALID_ENUM) + return null + } + } + + getShaderPrecisionFormat ( + shaderType, + precisionType) { + shaderType |= 0 + precisionType |= 0 + + if (!(shaderType === gl.FRAGMENT_SHADER || + shaderType === gl.VERTEX_SHADER) || + !(precisionType === gl.LOW_FLOAT || + precisionType === gl.MEDIUM_FLOAT || + precisionType === gl.HIGH_FLOAT || + precisionType === gl.LOW_INT || + precisionType === gl.MEDIUM_INT || + precisionType === gl.HIGH_INT)) { + this.setError(gl.INVALID_ENUM) + return + } + + const format = super.getShaderPrecisionFormat(shaderType, precisionType) + if (!format) { + return null + } + + return new WebGLShaderPrecisionFormat(format) + } + + getBufferParameter (target, pname) { + target |= 0 + pname |= 0 + if (target !== gl.ARRAY_BUFFER && + target !== gl.ELEMENT_ARRAY_BUFFER) { + this.setError(gl.INVALID_ENUM) + return null + } + + switch (pname) { + case gl.BUFFER_SIZE: + case gl.BUFFER_USAGE: + return super.getBufferParameter(target | 0, pname | 0) + default: + this.setError(gl.INVALID_ENUM) + return null + } + } + + getError () { + return super.getError() + } + + getFramebufferAttachmentParameter (target, attachment, pname) { + target |= 0 + attachment |= 0 + pname |= 0 + + if (target !== gl.FRAMEBUFFER || + !this._validFramebufferAttachment(attachment)) { + this.setError(gl.INVALID_ENUM) + return null + } + + const framebuffer = this._activeFramebuffer + if (!framebuffer) { + this.setError(gl.INVALID_OPERATION) + return null + } + + const object = framebuffer._attachments[attachment] + if (object === null) { + if (pname === gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) { + return gl.NONE + } + } else if (object instanceof WebGLTexture) { + switch (pname) { + case gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + return object + case gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + return gl.TEXTURE + case gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + return framebuffer._attachmentLevel[attachment] + case gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: { + const face = framebuffer._attachmentFace[attachment] + if (face === gl.TEXTURE_2D) { + return 0 + } + return face + } + } + } else if (object instanceof WebGLRenderbuffer) { + switch (pname) { + case gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + return object + case gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + return gl.RENDERBUFFER + } + } + + this.setError(gl.INVALID_ENUM) + return null + } + + getProgramParameter (program, pname) { + pname |= 0 + if (!checkObject(program)) { + throw new TypeError('getProgramParameter(WebGLProgram, GLenum)') + } else if (this._checkWrapper(program, WebGLProgram)) { + switch (pname) { + case gl.DELETE_STATUS: + return program._pendingDelete + + case gl.LINK_STATUS: + return program._linkStatus + + case gl.VALIDATE_STATUS: + return !!super.getProgramParameter(program._, pname) + + case gl.ATTACHED_SHADERS: + case gl.ACTIVE_ATTRIBUTES: + case gl.ACTIVE_UNIFORMS: + return super.getProgramParameter(program._, pname) + } + this.setError(gl.INVALID_ENUM) + } + return null + } + + getProgramInfoLog (program) { + if (!checkObject(program)) { + throw new TypeError('getProgramInfoLog(WebGLProgram)') + } else if (this._checkWrapper(program, WebGLProgram)) { + return program._linkInfoLog + } + return null + } + + getRenderbufferParameter (target, pname) { + target |= 0 + pname |= 0 + if (target !== gl.RENDERBUFFER) { + this.setError(gl.INVALID_ENUM) + return null + } + const renderbuffer = this._activeRenderbuffer + if (!renderbuffer) { + this.setError(gl.INVALID_OPERATION) + return null + } + switch (pname) { + case gl.RENDERBUFFER_INTERNAL_FORMAT: + return renderbuffer._format + case gl.RENDERBUFFER_WIDTH: + return renderbuffer._width + case gl.RENDERBUFFER_HEIGHT: + return renderbuffer._height + case gl.RENDERBUFFER_SIZE: + case gl.RENDERBUFFER_RED_SIZE: + case gl.RENDERBUFFER_GREEN_SIZE: + case gl.RENDERBUFFER_BLUE_SIZE: + case gl.RENDERBUFFER_ALPHA_SIZE: + case gl.RENDERBUFFER_DEPTH_SIZE: + case gl.RENDERBUFFER_STENCIL_SIZE: + return super.getRenderbufferParameter(target, pname) + } + this.setError(gl.INVALID_ENUM) + return null + } + + getShaderParameter (shader, pname) { + pname |= 0 + if (!checkObject(shader)) { + throw new TypeError('getShaderParameter(WebGLShader, GLenum)') + } else if (this._checkWrapper(shader, WebGLShader)) { + switch (pname) { + case gl.DELETE_STATUS: + return shader._pendingDelete + case gl.COMPILE_STATUS: + return shader._compileStatus + case gl.SHADER_TYPE: + return shader._type + } + this.setError(gl.INVALID_ENUM) + } + return null + } + + getShaderInfoLog (shader) { + if (!checkObject(shader)) { + throw new TypeError('getShaderInfoLog(WebGLShader)') + } else if (this._checkWrapper(shader, WebGLShader)) { + return shader._compileInfo + } + return null + } + + getShaderSource (shader) { + if (!checkObject(shader)) { + throw new TypeError('Input to getShaderSource must be an object') + } else if (this._checkWrapper(shader, WebGLShader)) { + return shader._source + } + return null + } + + getTexParameter (target, pname) { + target |= 0 + pname |= 0 + + if (!this._checkTextureTarget(target)) { + return null + } + + const unit = this._getActiveTextureUnit() + if ((target === gl.TEXTURE_2D && !unit._bind2D) || + (target === gl.TEXTURE_CUBE_MAP && !unit._bindCube)) { + this.setError(gl.INVALID_OPERATION) + return null + } + + switch (pname) { + case gl.TEXTURE_MAG_FILTER: + case gl.TEXTURE_MIN_FILTER: + case gl.TEXTURE_WRAP_S: + case gl.TEXTURE_WRAP_T: + return super.getTexParameter(target, pname) + } + + if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) { + return super.getTexParameter(target, pname) + } + + this.setError(gl.INVALID_ENUM) + return null + } + + getUniform (program, location) { + if (!checkObject(program) || + !checkObject(location)) { + throw new TypeError('getUniform(WebGLProgram, WebGLUniformLocation)') + } else if (!program) { + this.setError(gl.INVALID_VALUE) + return null + } else if (!location) { + return null + } else if (this._checkWrapper(program, WebGLProgram)) { + if (!checkUniform(program, location)) { + this.setError(gl.INVALID_OPERATION) + return null + } + const data = super.getUniform(program._ | 0, location._ | 0) + if (!data) { + return null + } + switch (location._activeInfo.type) { + case gl.FLOAT: + return data[0] + case gl.FLOAT_VEC2: + return new Float32Array(data.slice(0, 2)) + case gl.FLOAT_VEC3: + return new Float32Array(data.slice(0, 3)) + case gl.FLOAT_VEC4: + return new Float32Array(data.slice(0, 4)) + case gl.INT: + return data[0] | 0 + case gl.INT_VEC2: + return new Int32Array(data.slice(0, 2)) + case gl.INT_VEC3: + return new Int32Array(data.slice(0, 3)) + case gl.INT_VEC4: + return new Int32Array(data.slice(0, 4)) + case gl.BOOL: + return !!data[0] + case gl.BOOL_VEC2: + return [!!data[0], !!data[1]] + case gl.BOOL_VEC3: + return [!!data[0], !!data[1], !!data[2]] + case gl.BOOL_VEC4: + return [!!data[0], !!data[1], !!data[2], !!data[3]] + case gl.FLOAT_MAT2: + return new Float32Array(data.slice(0, 4)) + case gl.FLOAT_MAT3: + return new Float32Array(data.slice(0, 9)) + case gl.FLOAT_MAT4: + return new Float32Array(data.slice(0, 16)) + case gl.SAMPLER_2D: + case gl.SAMPLER_CUBE: + return data[0] | 0 + default: + return null + } + } + return null + } + + getUniformLocation (program, name) { + if (!checkObject(program)) { + throw new TypeError('getUniformLocation(WebGLProgram, String)') + } + + name += '' + if (!isValidString(name)) { + this.setError(gl.INVALID_VALUE) + return + } + + if (this._checkWrapper(program, WebGLProgram)) { + const loc = super.getUniformLocation(program._ | 0, name) + if (loc >= 0) { + let searchName = name + if (/\[\d+\]$/.test(name)) { + searchName = name.replace(/\[\d+\]$/, '[0]') + } + + let info = null + for (let i = 0; i < program._uniforms.length; ++i) { + const infoItem = program._uniforms[i] + if (infoItem.name === searchName) { + info = { + size: infoItem.size, + type: infoItem.type, + name: infoItem.name + } + } + } + if (!info) { + return null + } + + const result = new WebGLUniformLocation( + loc, + program, + info) + + // handle array case + if (/\[0\]$/.test(name)) { + const baseName = name.replace(/\[0\]$/, '') + const arrayLocs = [] + + // if (offset < 0 || offset >= info.size) { + // return null + // } + + this._saveError() + for (let i = 0; this.getError() === gl.NO_ERROR; ++i) { + const xloc = super.getUniformLocation( + program._ | 0, + baseName + '[' + i + ']') + if (this.getError() !== gl.NO_ERROR || xloc < 0) { + break + } + arrayLocs.push(xloc) + } + this._restoreError(gl.NO_ERROR) + + result._array = arrayLocs + } else if (/\[(\d+)\]$/.test(name)) { + const offset = +(/\[(\d+)\]$/.exec(name))[1] + if (offset < 0 || offset >= info.size) { + return null + } + } + return result + } + } + return null + } + + getVertexAttrib (index, pname) { + index |= 0 + pname |= 0 + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return null + } + const attrib = this._vertexAttribs[index] + + const extInstancing = this._extensions.angle_instanced_arrays + if (extInstancing) { + if (pname === extInstancing.VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE) { + return attrib._divisor + } + } + + switch (pname) { + case gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + return attrib._pointerBuffer + case gl.VERTEX_ATTRIB_ARRAY_ENABLED: + return attrib._isPointer + case gl.VERTEX_ATTRIB_ARRAY_SIZE: + return attrib._inputSize + case gl.VERTEX_ATTRIB_ARRAY_STRIDE: + return attrib._inputStride + case gl.VERTEX_ATTRIB_ARRAY_TYPE: + return attrib._pointerType + case gl.VERTEX_ATTRIB_ARRAY_NORMALIZED: + return attrib._pointerNormal + case gl.CURRENT_VERTEX_ATTRIB: + return new Float32Array(attrib._data) + default: + this.setError(gl.INVALID_ENUM) + return null + } + } + + getVertexAttribOffset (index, pname) { + index |= 0 + pname |= 0 + if (index < 0 || index >= this._vertexAttribs.length) { + this.setError(gl.INVALID_VALUE) + return null + } + if (pname === gl.VERTEX_ATTRIB_ARRAY_POINTER) { + return this._vertexAttribs[index]._pointerOffset + } else { + this.setError(gl.INVALID_ENUM) + return null + } + } + + hint (target, mode) { + target |= 0 + mode |= 0 + + if (!( + target === gl.GENERATE_MIPMAP_HINT || + ( + this._extensions.oes_standard_derivatives && target === this._extensions.oes_standard_derivatives.FRAGMENT_SHADER_DERIVATIVE_HINT_OES + ) + )) { + this.setError(gl.INVALID_ENUM) + return + } + + if (mode !== gl.FASTEST && + mode !== gl.NICEST && + mode !== gl.DONT_CARE) { + this.setError(gl.INVALID_ENUM) + return + } + + return super.hint(target, mode) + } + + isBuffer (object) { + if (!this._isObject(object, 'isBuffer', WebGLBuffer)) return false + return super.isBuffer(object._ | 0) + } + + isFramebuffer (object) { + if (!this._isObject(object, 'isFramebuffer', WebGLFramebuffer)) return false + return super.isFramebuffer(object._ | 0) + } + + isProgram (object) { + if (!this._isObject(object, 'isProgram', WebGLProgram)) return false + return super.isProgram(object._ | 0) + } + + isRenderbuffer (object) { + if (!this._isObject(object, 'isRenderbuffer', WebGLRenderbuffer)) return false + return super.isRenderbuffer(object._ | 0) + } + + isShader (object) { + if (!this._isObject(object, 'isShader', WebGLShader)) return false + return super.isShader(object._ | 0) + } + + isTexture (object) { + if (!this._isObject(object, 'isTexture', WebGLTexture)) return false + return super.isTexture(object._ | 0) + } + + isEnabled (cap) { + return super.isEnabled(cap | 0) + } + + lineWidth (width) { + if (isNaN(width)) { + this.setError(gl.INVALID_VALUE) + return + } + return super.lineWidth(+width) + } + + linkProgram (program) { + if (!checkObject(program)) { + throw new TypeError('linkProgram(WebGLProgram)') + } + if (this._checkWrapper(program, WebGLProgram)) { + program._linkCount += 1 + program._attributes = [] + const prevError = this.getError() + super.linkProgram(program._ | 0) + const error = this.getError() + if (error === gl.NO_ERROR) { + program._linkStatus = this._fixupLink(program) + } + this.getError() + this.setError(prevError || error) + } + } + + pixelStorei (pname, param) { + pname |= 0 + param |= 0 + if (pname === gl.UNPACK_ALIGNMENT) { + if (param === 1 || + param === 2 || + param === 4 || + param === 8) { + this._unpackAlignment = param + } else { + this.setError(gl.INVALID_VALUE) + return + } + } else if (pname === gl.PACK_ALIGNMENT) { + if (param === 1 || + param === 2 || + param === 4 || + param === 8) { + this._packAlignment = param + } else { + this.setError(gl.INVALID_VALUE) + return + } + } else if (pname === gl.UNPACK_COLORSPACE_CONVERSION_WEBGL) { + if (!(param === gl.NONE || param === gl.BROWSER_DEFAULT_WEBGL)) { + this.setError(gl.INVALID_VALUE) + return + } + } + return super.pixelStorei(pname, param) + } + + polygonOffset (factor, units) { + return super.polygonOffset(+factor, +units) + } + + readPixels (x, y, width, height, format, type, pixels) { + x |= 0 + y |= 0 + width |= 0 + height |= 0 + + if (this._extensions.oes_texture_float && type === gl.FLOAT && format === gl.RGBA) { + } else if (format === gl.RGB || + format === gl.ALPHA || + type !== gl.UNSIGNED_BYTE) { + this.setError(gl.INVALID_OPERATION) + return + } else if (format !== gl.RGBA) { + this.setError(gl.INVALID_ENUM) + return + } else if ( + width < 0 || + height < 0 || + !(pixels instanceof Uint8Array)) { + this.setError(gl.INVALID_VALUE) + return + } + + if (!this._framebufferOk()) { + return + } + + let rowStride = width * 4 + if (rowStride % this._packAlignment !== 0) { + rowStride += this._packAlignment - (rowStride % this._packAlignment) + } + + const imageSize = rowStride * (height - 1) + width * 4 + if (imageSize <= 0) { + return + } + if (pixels.length < imageSize) { + this.setError(gl.INVALID_VALUE) + return + } + + // Handle reading outside the window + let viewWidth = this.drawingBufferWidth + let viewHeight = this.drawingBufferHeight + + if (this._activeFramebuffer) { + viewWidth = this._activeFramebuffer._width + viewHeight = this._activeFramebuffer._height + } + + const pixelData = unpackTypedArray(pixels) + + if (x >= viewWidth || x + width <= 0 || + y >= viewHeight || y + height <= 0) { + for (let i = 0; i < pixelData.length; ++i) { + pixelData[i] = 0 + } + } else if (x < 0 || x + width > viewWidth || + y < 0 || y + height > viewHeight) { + for (let i = 0; i < pixelData.length; ++i) { + pixelData[i] = 0 + } + + let nx = x + let nWidth = width + if (x < 0) { + nWidth += x + nx = 0 + } + if (nx + width > viewWidth) { + nWidth = viewWidth - nx + } + let ny = y + let nHeight = height + if (y < 0) { + nHeight += y + ny = 0 + } + if (ny + height > viewHeight) { + nHeight = viewHeight - ny + } + + let nRowStride = nWidth * 4 + if (nRowStride % this._packAlignment !== 0) { + nRowStride += this._packAlignment - (nRowStride % this._packAlignment) + } + + if (nWidth > 0 && nHeight > 0) { + const subPixels = new Uint8Array(nRowStride * nHeight) + super.readPixels( + nx, + ny, + nWidth, + nHeight, + format, + type, + subPixels) + + const offset = 4 * (nx - x) + (ny - y) * rowStride + for (let j = 0; j < nHeight; ++j) { + for (let i = 0; i < nWidth; ++i) { + for (let k = 0; k < 4; ++k) { + pixelData[offset + j * rowStride + 4 * i + k] = + subPixels[j * nRowStride + 4 * i + k] + } + } + } + } + } else { + super.readPixels( + x, + y, + width, + height, + format, + type, + pixelData) + } + } + + renderbufferStorage ( + target, + internalFormat, + width, + height) { + target |= 0 + internalFormat |= 0 + width |= 0 + height |= 0 + + if (target !== gl.RENDERBUFFER) { + this.setError(gl.INVALID_ENUM) + return + } + + const renderbuffer = this._activeRenderbuffer + if (!renderbuffer) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (internalFormat !== gl.RGBA4 && + internalFormat !== gl.RGB565 && + internalFormat !== gl.RGB5_A1 && + internalFormat !== gl.DEPTH_COMPONENT16 && + internalFormat !== gl.STENCIL_INDEX && + internalFormat !== gl.STENCIL_INDEX8 && + internalFormat !== gl.DEPTH_STENCIL) { + this.setError(gl.INVALID_ENUM) + return + } + + this._saveError() + super.renderbufferStorage( + target, + internalFormat, + width, + height) + const error = this.getError() + this._restoreError(error) + if (error !== gl.NO_ERROR) { + return + } + + renderbuffer._width = width + renderbuffer._height = height + renderbuffer._format = internalFormat + + const activeFramebuffer = this._activeFramebuffer + if (activeFramebuffer) { + let needsUpdate = false + const attachments = this._getAttachments() + for (let i = 0; i < attachments.length; ++i) { + if (activeFramebuffer._attachments[attachments[i]] === renderbuffer) { + needsUpdate = true + break + } + } + if (needsUpdate) { + this._updateFramebufferAttachments(this._activeFramebuffer) + } + } + } + + resize (width, height) { + width = width | 0 + height = height | 0 + if (!(width > 0 && height > 0)) { + throw new Error('Invalid surface dimensions') + } else if (width !== this.drawingBufferWidth || + height !== this.drawingBufferHeight) { + this._resizeDrawingBuffer(width, height) + this.drawingBufferWidth = width + this.drawingBufferHeight = height + } + } + + sampleCoverage (value, invert) { + return super.sampleCoverage(+value, !!invert) + } + + scissor (x, y, width, height) { + return super.scissor(x | 0, y | 0, width | 0, height | 0) + } + + shaderSource (shader, source) { + if (!checkObject(shader)) { + throw new TypeError('shaderSource(WebGLShader, String)') + } + if (!shader || (!source && typeof source !== 'string')) { + this.setError(gl.INVALID_VALUE) + return + } + source += '' + if (!isValidString(source)) { + this.setError(gl.INVALID_VALUE) + } else if (this._checkWrapper(shader, WebGLShader)) { + super.shaderSource(shader._ | 0, this._wrapShader(shader._type, source)) // eslint-disable-line + shader._source = source + } + } + + stencilFunc (func, ref, mask) { + this._checkStencil = true + return super.stencilFunc(func | 0, ref | 0, mask | 0) + } + + stencilFuncSeparate (face, func, ref, mask) { + this._checkStencil = true + return super.stencilFuncSeparate(face | 0, func | 0, ref | 0, mask | 0) + } + + stencilMask (mask) { + this._checkStencil = true + return super.stencilMask(mask | 0) + } + + stencilMaskSeparate (face, mask) { + this._checkStencil = true + return super.stencilMaskSeparate(face | 0, mask | 0) + } + + stencilOp (fail, zfail, zpass) { + this._checkStencil = true + return super.stencilOp(fail | 0, zfail | 0, zpass | 0) + } + + stencilOpSeparate (face, fail, zfail, zpass) { + this._checkStencil = true + return super.stencilOpSeparate(face | 0, fail | 0, zfail | 0, zpass | 0) + } + + texImage2D ( + target, + level, + internalFormat, + width, + height, + border, + format, + type, + pixels) { + if (arguments.length === 6) { + pixels = border + type = height + format = width + + pixels = extractImageData(pixels) + + if (pixels == null) { + throw new TypeError('texImage2D(GLenum, GLint, GLenum, GLint, GLenum, GLenum, ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement)') + } + + width = pixels.width + height = pixels.height + pixels = pixels.data + } + + target |= 0 + level |= 0 + internalFormat |= 0 + width |= 0 + height |= 0 + border |= 0 + format |= 0 + type |= 0 + + if (typeof pixels !== 'object' && pixels !== undefined) { + throw new TypeError('texImage2D(GLenum, GLint, GLenum, GLint, GLint, GLint, GLenum, GLenum, Uint8Array)') + } + + if (!checkFormat(format) || !checkFormat(internalFormat)) { + this.setError(gl.INVALID_ENUM) + return + } + + if (type === gl.FLOAT && !this._extensions.oes_texture_float) { + this.setError(gl.INVALID_ENUM) + return + } + + const texture = this._getTexImage(target) + if (!texture || format !== internalFormat) { + this.setError(gl.INVALID_OPERATION) + return + } + + const pixelSize = this._computePixelSize(type, format) + if (pixelSize === 0) { + return + } + + if (!this._checkDimensions( + target, + width, + height, + level)) { + return + } + + const data = convertPixels(pixels) + const rowStride = this._computeRowStride(width, pixelSize) + const imageSize = rowStride * height + + if (data && data.length < imageSize) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (border !== 0 || + (validCubeTarget(target) && width !== height)) { + this.setError(gl.INVALID_VALUE) + return + } + // Need to check for out of memory error + this._saveError() + super.texImage2D( + target, + level, + internalFormat, + width, + height, + border, + format, + type, + data) + const error = this.getError() + this._restoreError(error) + if (error !== gl.NO_ERROR) { + return + } + + // Save width and height at level + texture._levelWidth[level] = width + texture._levelHeight[level] = height + texture._format = format + texture._type = type + + const activeFramebuffer = this._activeFramebuffer + if (activeFramebuffer) { + let needsUpdate = false + const attachments = this._getAttachments() + for (let i = 0; i < attachments.length; ++i) { + if (activeFramebuffer._attachments[attachments[i]] === texture) { + needsUpdate = true + break + } + } + if (needsUpdate) { + this._updateFramebufferAttachments(this._activeFramebuffer) + } + } + } + + texSubImage2D ( + target, + level, + xoffset, + yoffset, + width, + height, + format, + type, + pixels) { + if (arguments.length === 7) { + pixels = format + type = height + format = width + + pixels = extractImageData(pixels) + + if (pixels == null) { + throw new TypeError('texSubImage2D(GLenum, GLint, GLint, GLint, GLenum, GLenum, ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement)') + } + + width = pixels.width + height = pixels.height + pixels = pixels.data + } + + if (typeof pixels !== 'object') { + throw new TypeError('texSubImage2D(GLenum, GLint, GLint, GLint, GLint, GLint, GLenum, GLenum, Uint8Array)') + } + + target |= 0 + level |= 0 + xoffset |= 0 + yoffset |= 0 + width |= 0 + height |= 0 + format |= 0 + type |= 0 + + const texture = this._getTexImage(target) + if (!texture) { + this.setError(gl.INVALID_OPERATION) + return + } + + if (type === gl.FLOAT && !this._extensions.oes_texture_float) { + this.setError(gl.INVALID_ENUM) + return + } + + const pixelSize = this._computePixelSize(type, format) + if (pixelSize === 0) { + return + } + + if (!this._checkDimensions( + target, + width, + height, + level)) { + return + } + + if (xoffset < 0 || yoffset < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + const data = convertPixels(pixels) + const rowStride = this._computeRowStride(width, pixelSize) + const imageSize = rowStride * height + + if (!data || data.length < imageSize) { + this.setError(gl.INVALID_OPERATION) + return + } + + super.texSubImage2D( + target, + level, + xoffset, + yoffset, + width, + height, + format, + type, + data) + } + + texParameterf (target, pname, param) { + target |= 0 + pname |= 0 + param = +param + + if (this._checkTextureTarget(target)) { + this._verifyTextureCompleteness(target, pname, param) + switch (pname) { + case gl.TEXTURE_MIN_FILTER: + case gl.TEXTURE_MAG_FILTER: + case gl.TEXTURE_WRAP_S: + case gl.TEXTURE_WRAP_T: + return super.texParameterf(target, pname, param) + } + + if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) { + return super.texParameterf(target, pname, param) + } + + this.setError(gl.INVALID_ENUM) + } + } + + texParameteri (target, pname, param) { + target |= 0 + pname |= 0 + param |= 0 + + if (this._checkTextureTarget(target)) { + this._verifyTextureCompleteness(target, pname, param) + switch (pname) { + case gl.TEXTURE_MIN_FILTER: + case gl.TEXTURE_MAG_FILTER: + case gl.TEXTURE_WRAP_S: + case gl.TEXTURE_WRAP_T: + return super.texParameteri(target, pname, param) + } + + if (this._extensions.ext_texture_filter_anisotropic && pname === this._extensions.ext_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT) { + return super.texParameteri(target, pname, param) + } + + this.setError(gl.INVALID_ENUM) + } + } + + useProgram (program) { + if (!checkObject(program)) { + throw new TypeError('useProgram(WebGLProgram)') + } else if (!program) { + this._switchActiveProgram(this._activeProgram) + this._activeProgram = null + return super.useProgram(0) + } else if (this._checkWrapper(program, WebGLProgram)) { + if (this._activeProgram !== program) { + this._switchActiveProgram(this._activeProgram) + this._activeProgram = program + program._refCount += 1 + } + return super.useProgram(program._ | 0) + } + } + + validateProgram (program) { + if (this._checkWrapper(program, WebGLProgram)) { + super.validateProgram(program._ | 0) + const error = this.getError() + if (error === gl.NO_ERROR) { + program._linkInfoLog = super.getProgramInfoLog(program._ | 0) + } + this.getError() + this.setError(error) + } + } + + vertexAttribPointer ( + index, + size, + type, + normalized, + stride, + offset) { + if (stride < 0 || offset < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + index |= 0 + size |= 0 + type |= 0 + normalized = !!normalized + stride |= 0 + offset |= 0 + + if (stride < 0 || + offset < 0 || + index < 0 || index >= this._vertexAttribs.length || + !(size === 1 || size === 2 || size === 3 || size === 4)) { + this.setError(gl.INVALID_VALUE) + return + } + + if (this._activeArrayBuffer === null) { + this.setError(gl.INVALID_OPERATION) + return + } + + // fixed, int and unsigned int aren't allowed in WebGL + const byteSize = typeSize(type) + if (byteSize === 0 || + type === gl.INT || + type === gl.UNSIGNED_INT) { + this.setError(gl.INVALID_ENUM) + return + } + + if (stride > 255 || stride < 0) { + this.setError(gl.INVALID_VALUE) + return + } + + // stride and offset must be multiples of size + if ((stride % byteSize) !== 0 || + (offset % byteSize) !== 0) { + this.setError(gl.INVALID_OPERATION) + return + } + + // Call vertex attrib pointer + super.vertexAttribPointer(index, size, type, normalized, stride, offset) + + // Save attribute pointer state + const attrib = this._vertexAttribs[index] + + if (attrib._pointerBuffer && + attrib._pointerBuffer !== this._activeArrayBuffer) { + attrib._pointerBuffer._refCount -= 1 + attrib._pointerBuffer._checkDelete() + } + + this._activeArrayBuffer._refCount += 1 + attrib._pointerBuffer = this._activeArrayBuffer + attrib._pointerSize = size * byteSize + attrib._pointerOffset = offset + attrib._pointerStride = stride || (size * byteSize) + attrib._pointerType = type + attrib._pointerNormal = normalized + attrib._inputStride = stride + attrib._inputSize = size + } + + viewport (x, y, width, height) { + return super.viewport(x | 0, y | 0, width | 0, height | 0) + } + + _allocateDrawingBuffer (width, height) { + this._drawingBuffer = new WebGLDrawingBufferWrapper( + super.createFramebuffer(), + super.createTexture(), + super.createRenderbuffer()) + + this._resizeDrawingBuffer(width, height) + } + + isContextLost () { + return false + } + + compressedTexImage2D () { + // TODO not yet implemented + } + + compressedTexSubImage2D () { + // TODO not yet implemented + } + + _checkUniformValid (location, v0, name, count, type) { + if (!checkObject(location)) { + throw new TypeError(`${name}(WebGLUniformLocation, ...)`) + } else if (!location) { + return false + } else if (this._checkLocationActive(location)) { + const utype = location._activeInfo.type + if (utype === gl.SAMPLER_2D || utype === gl.SAMPLER_CUBE) { + if (count !== 1) { + this.setError(gl.INVALID_VALUE) + return + } + if (type !== 'i') { + this.setError(gl.INVALID_OPERATION) + return + } + if (v0 < 0 || v0 >= this._textureUnits.length) { + this.setError(gl.INVALID_VALUE) + return false + } + } + if (uniformTypeSize(utype) > count) { + this.setError(gl.INVALID_OPERATION) + return false + } + return true + } + return false + } + + _checkUniformValueValid (location, value, name, count, type) { + if (!checkObject(location) || + !checkObject(value)) { + throw new TypeError(`${name}v(WebGLUniformLocation, Array)`) + } else if (!location) { + return false + } else if (!this._checkLocationActive(location)) { + return false + } else if (typeof value !== 'object' || !value || typeof value.length !== 'number') { + throw new TypeError(`Second argument to ${name} must be array`) + } else if (uniformTypeSize(location._activeInfo.type) > count) { + this.setError(gl.INVALID_OPERATION) + return false + } else if (value.length >= count && value.length % count === 0) { + if (location._array) { + return true + } else if (value.length === count) { + return true + } else { + this.setError(gl.INVALID_OPERATION) + return false + } + } + this.setError(gl.INVALID_VALUE) + return false + } + + uniform1f (location, v0) { + if (!this._checkUniformValid(location, v0, 'uniform1f', 1, 'f')) return + super.uniform1f(location._ | 0, v0) + } + + uniform1fv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform1fv', 1, 'f')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && i < value.length; ++i) { + const loc = locs[i] + super.uniform1f(loc, value[i]) + } + return + } + super.uniform1f(location._ | 0, value[0]) + } + + uniform1i (location, v0) { + if (!this._checkUniformValid(location, v0, 'uniform1i', 1, 'i')) return + super.uniform1i(location._ | 0, v0) + } + + uniform1iv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform1iv', 1, 'i')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && i < value.length; ++i) { + const loc = locs[i] + super.uniform1i(loc, value[i]) + } + return + } + this.uniform1i(location, value[0]) + } + + uniform2f (location, v0, v1) { + if (!this._checkUniformValid(location, v0, 'uniform2f', 2, 'f')) return + super.uniform2f(location._ | 0, v0, v1) + } + + uniform2fv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform2fv', 2, 'f')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 2 * i < value.length; ++i) { + const loc = locs[i] + super.uniform2f(loc, value[2 * i], value[(2 * i) + 1]) + } + return + } + super.uniform2f(location._ | 0, value[0], value[1]) + } + + uniform2i (location, v0, v1) { + if (!this._checkUniformValid(location, v0, 'uniform2i', 2, 'i')) return + super.uniform2i(location._ | 0, v0, v1) + } + + uniform2iv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform2iv', 2, 'i')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 2 * i < value.length; ++i) { + const loc = locs[i] + super.uniform2i(loc, value[2 * i], value[2 * i + 1]) + } + return + } + this.uniform2i(location, value[0], value[1]) + } + + uniform3f (location, v0, v1, v2) { + if (!this._checkUniformValid(location, v0, 'uniform3f', 3, 'f')) return + super.uniform3f(location._ | 0, v0, v1, v2) + } + + uniform3fv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform3fv', 3, 'f')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 3 * i < value.length; ++i) { + const loc = locs[i] + super.uniform3f(loc, value[3 * i], value[3 * i + 1], value[3 * i + 2]) + } + return + } + super.uniform3f(location._ | 0, value[0], value[1], value[2]) + } + + uniform3i (location, v0, v1, v2) { + if (!this._checkUniformValid(location, v0, 'uniform3i', 3, 'i')) return + super.uniform3i(location._ | 0, v0, v1, v2) + } + + uniform3iv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform3iv', 3, 'i')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 3 * i < value.length; ++i) { + const loc = locs[i] + super.uniform3i(loc, value[3 * i], value[3 * i + 1], value[3 * i + 2]) + } + return + } + this.uniform3i(location, value[0], value[1], value[2]) + } + + uniform4f (location, v0, v1, v2, v3) { + if (!this._checkUniformValid(location, v0, 'uniform4f', 4, 'f')) return + super.uniform4f(location._ | 0, v0, v1, v2, v3) + } + + uniform4fv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform4fv', 4, 'f')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 4 * i < value.length; ++i) { + const loc = locs[i] + super.uniform4f(loc, value[4 * i], value[4 * i + 1], value[4 * i + 2], value[4 * i + 3]) + } + return + } + super.uniform4f(location._ | 0, value[0], value[1], value[2], value[3]) + } + + uniform4i (location, v0, v1, v2, v3) { + if (!this._checkUniformValid(location, v0, 'uniform4i', 4, 'i')) return + super.uniform4i(location._ | 0, v0, v1, v2, v3) + } + + uniform4iv (location, value) { + if (!this._checkUniformValueValid(location, value, 'uniform4iv', 4, 'i')) return + if (location._array) { + const locs = location._array + for (let i = 0; i < locs.length && 4 * i < value.length; ++i) { + const loc = locs[i] + super.uniform4i(loc, value[4 * i], value[4 * i + 1], value[4 * i + 2], value[4 * i + 3]) + } + return + } + this.uniform4i(location, value[0], value[1], value[2], value[3]) + } + + _checkUniformMatrix (location, transpose, value, name, count) { + if (!checkObject(location) || + typeof value !== 'object') { + throw new TypeError(name + '(WebGLUniformLocation, Boolean, Array)') + } else if (!!transpose || + typeof value !== 'object' || + value === null || + !value.length || + value.length % count * count !== 0) { + this.setError(gl.INVALID_VALUE) + return false + } + if (!location) { + return false + } + if (!this._checkLocationActive(location)) { + return false + } + + if (value.length === count * count) { + return true + } else if (location._array) { + return true + } + this.setError(gl.INVALID_VALUE) + return false + } + + uniformMatrix2fv (location, transpose, value) { + if (!this._checkUniformMatrix(location, transpose, value, 'uniformMatrix2fv', 2)) return + const data = new Float32Array(value) + super.uniformMatrix2fv( + location._ | 0, + !!transpose, + data) + } + + uniformMatrix3fv (location, transpose, value) { + if (!this._checkUniformMatrix(location, transpose, value, 'uniformMatrix3fv', 3)) return + const data = new Float32Array(value) + super.uniformMatrix3fv( + location._ | 0, + !!transpose, + data) + } + + uniformMatrix4fv (location, transpose, value) { + if (!this._checkUniformMatrix(location, transpose, value, 'uniformMatrix4fv', 4)) return + const data = new Float32Array(value) + super.uniformMatrix4fv( + location._ | 0, + !!transpose, + data) + } + + vertexAttrib1f (index, v0) { + index |= 0 + if (!this._checkVertexIndex(index)) return + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[1] = data[2] = 0 + data[0] = v0 + return super.vertexAttrib1f(index | 0, +v0) + } + + vertexAttrib2f (index, v0, v1) { + index |= 0 + if (!this._checkVertexIndex(index)) return + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = 0 + data[1] = v1 + data[0] = v0 + return super.vertexAttrib2f(index | 0, +v0, +v1) + } + + vertexAttrib3f (index, v0, v1, v2) { + index |= 0 + if (!this._checkVertexIndex(index)) return + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = v2 + data[1] = v1 + data[0] = v0 + return super.vertexAttrib3f(index | 0, +v0, +v1, +v2) + } + + vertexAttrib4f (index, v0, v1, v2, v3) { + index |= 0 + if (!this._checkVertexIndex(index)) return + const data = this._vertexAttribs[index]._data + data[3] = v3 + data[2] = v2 + data[1] = v1 + data[0] = v0 + return super.vertexAttrib4f(index | 0, +v0, +v1, +v2, +v3) + } + + vertexAttrib1fv (index, value) { + if (typeof value !== 'object' || value === null || value.length < 1) { + this.setError(gl.INVALID_OPERATION) + return + } + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = 0 + data[1] = 0 + data[0] = value[0] + return super.vertexAttrib1f(index | 0, +value[0]) + } + + vertexAttrib2fv (index, value) { + if (typeof value !== 'object' || value === null || value.length < 2) { + this.setError(gl.INVALID_OPERATION) + return + } + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = 0 + data[1] = value[1] + data[0] = value[0] + return super.vertexAttrib2f(index | 0, +value[0], +value[1]) + } + + vertexAttrib3fv (index, value) { + if (typeof value !== 'object' || value === null || value.length < 3) { + this.setError(gl.INVALID_OPERATION) + return + } + const data = this._vertexAttribs[index]._data + data[3] = 1 + data[2] = value[2] + data[1] = value[1] + data[0] = value[0] + return super.vertexAttrib3f(index | 0, +value[0], +value[1], +value[2]) + } + + vertexAttrib4fv (index, value) { + if (typeof value !== 'object' || value === null || value.length < 4) { + this.setError(gl.INVALID_OPERATION) + return + } + const data = this._vertexAttribs[index]._data + data[3] = value[3] + data[2] = value[2] + data[1] = value[1] + data[0] = value[0] + return super.vertexAttrib4f(index | 0, +value[0], +value[1], +value[2], +value[3]) + } +} + +module.exports = { WebGLRenderingContext, wrapContext } + +},{"../../package.json":135,"./extensions/angle-instanced-arrays":137,"./extensions/ext-blend-minmax":138,"./extensions/ext-texture-filter-anisotropic":139,"./extensions/oes-element-index-unit":140,"./extensions/oes-standard-derivatives":141,"./extensions/oes-texture-float":143,"./extensions/oes-texture-float-linear":142,"./extensions/stackgl-destroy-context":144,"./extensions/stackgl-resize-drawing-buffer":145,"./extensions/webgl-draw-buffers":146,"./native-gl":148,"./utils":150,"./webgl-active-info":151,"./webgl-buffer":152,"./webgl-drawing-buffer-wrapper":154,"./webgl-framebuffer":155,"./webgl-program":156,"./webgl-renderbuffer":157,"./webgl-shader":160,"./webgl-shader-precision-format":159,"./webgl-texture":162,"./webgl-uniform-location":163,"bit-twiddle":31,"glsl-tokenizer/string":179}],159:[function(require,module,exports){ +class WebGLShaderPrecisionFormat { + constructor (_) { + this.rangeMin = _.rangeMin + this.rangeMax = _.rangeMax + this.precision = _.precision + } +} + +module.exports = { WebGLShaderPrecisionFormat } + +},{}],160:[function(require,module,exports){ +const { gl } = require('./native-gl') +const { Linkable } = require('./linkable') + +class WebGLShader extends Linkable { + constructor (_, ctx, type) { + super(_) + this._type = type + this._ctx = ctx + this._source = '' + this._compileStatus = false + this._compileInfo = '' + } + + _performDelete () { + const ctx = this._ctx + delete ctx._shaders[this._ | 0] + gl.deleteShader.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLShader } + +},{"./linkable":147,"./native-gl":148}],161:[function(require,module,exports){ +class WebGLTextureUnit { + constructor (ctx, idx) { + this._ctx = ctx + this._idx = idx + this._mode = 0 + this._bind2D = null + this._bindCube = null + } +} + +module.exports = { WebGLTextureUnit } + +},{}],162:[function(require,module,exports){ +const { Linkable } = require('./linkable') +const { gl } = require('./native-gl') + +class WebGLTexture extends Linkable { + constructor (_, ctx) { + super(_) + this._ctx = ctx + this._binding = 0 + this._levelWidth = new Int32Array(32) + this._levelHeight = new Int32Array(32) + this._format = 0 + this._type = 0 + this._complete = true + } + + _performDelete () { + const ctx = this._ctx + delete ctx._textures[this._ | 0] + gl.deleteTexture.call(ctx, this._ | 0) + } +} + +module.exports = { WebGLTexture } + +},{"./linkable":147,"./native-gl":148}],163:[function(require,module,exports){ +class WebGLUniformLocation { + constructor (_, program, info) { + this._ = _ + this._program = program + this._linkCount = program._linkCount + this._activeInfo = info + this._array = null + } +} + +module.exports = { WebGLUniformLocation } + +},{}],164:[function(require,module,exports){ +const { gl } = require('./native-gl') + +class WebGLVertexAttribute { + constructor (ctx, idx) { + this._ctx = ctx + this._idx = idx + this._isPointer = false + this._pointerBuffer = null + this._pointerOffset = 0 + this._pointerSize = 0 + this._pointerStride = 0 + this._pointerType = gl.FLOAT + this._pointerNormal = false + this._divisor = 0 + this._inputSize = 4 + this._inputStride = 0 + this._data = new Float32Array([0, 0, 0, 1]) + } +} + +module.exports = { WebGLVertexAttribute } + +},{"./native-gl":148}],165:[function(require,module,exports){ +/* + * glfx.js + * http://evanw.github.com/glfx.js/ + * + * Copyright 2011 Evan Wallace + * Released under the MIT license + */ +var fx=function(){function q(a,d,c){return Math.max(a,Math.min(d,c))}function w(b){return{_:b,loadContentsOf:function(b){a=this._.gl;this._.loadContentsOf(b)},destroy:function(){a=this._.gl;this._.destroy()}}}function A(a){return w(r.fromElement(a))}function B(b,d){var c=a.UNSIGNED_BYTE;if(a.getExtension("OES_texture_float")&&a.getExtension("OES_texture_float_linear")){var e=new r(100,100,a.RGBA,a.FLOAT);try{e.drawTo(function(){c=a.FLOAT})}catch(g){}e.destroy()}this._.texture&&this._.texture.destroy(); +this._.spareTexture&&this._.spareTexture.destroy();this.width=b;this.height=d;this._.texture=new r(b,d,a.RGBA,c);this._.spareTexture=new r(b,d,a.RGBA,c);this._.extraTexture=this._.extraTexture||new r(0,0,a.RGBA,c);this._.flippedShader=this._.flippedShader||new h(null,"uniform sampler2D texture;varying vec2 texCoord;void main(){gl_FragColor=texture2D(texture,vec2(texCoord.x,1.0-texCoord.y));}");this._.isInitialized=!0}function C(a,d,c){if(!this._.isInitialized|| +a._.width!=this.width||a._.height!=this.height)B.call(this,d?d:a._.width,c?c:a._.height);a._.use();this._.texture.drawTo(function(){h.getDefaultShader().drawRect()});return this}function D(){this._.texture.use();this._.flippedShader.drawRect();return this}function f(a,d,c,e){(c||this._.texture).use();this._.spareTexture.drawTo(function(){a.uniforms(d).drawRect()});this._.spareTexture.swapWith(e||this._.texture)}function E(a){a.parentNode.insertBefore(this,a);a.parentNode.removeChild(a);return this} +function F(){var b=new r(this._.texture.width,this._.texture.height,a.RGBA,a.UNSIGNED_BYTE);this._.texture.use();b.drawTo(function(){h.getDefaultShader().drawRect()});return w(b)}function G(){var b=this._.texture.width,d=this._.texture.height,c=new Uint8Array(4*b*d);this._.texture.drawTo(function(){a.readPixels(0,0,b,d,a.RGBA,a.UNSIGNED_BYTE,c)});return c}function k(b){return function(){a=this._.gl;return b.apply(this,arguments)}}function x(a,d,c,e,g,n,l,p){var m=c-g,h=e-n,f=l-g,k=p-n;g=a-c+g-l;n= +d-e+n-p;var q=m*k-f*h,f=(g*k-f*n)/q,m=(m*n-g*h)/q;return[c-a+f*c,e-d+f*e,f,l-a+m*l,p-d+m*p,m,a,d,1]}function y(a){var d=a[0],c=a[1],e=a[2],g=a[3],n=a[4],l=a[5],p=a[6],m=a[7];a=a[8];var f=d*n*a-d*l*m-c*g*a+c*l*p+e*g*m-e*n*p;return[(n*a-l*m)/f,(e*m-c*a)/f,(c*l-e*n)/f,(l*p-g*a)/f,(d*a-e*p)/f,(e*g-d*l)/f,(g*m-n*p)/f,(c*p-d*m)/f,(d*n-c*g)/f]}function z(a){var d=a.length;this.xa=[];this.ya=[];this.u=[];this.y2=[];a.sort(function(a,b){return a[0]-b[0]});for(var c=0;cd;d++)f.call(this,a.denoise,{exponent:Math.max(0,b),texSize:[this.width,this.height]});return this}function L(b,d){a.brightnessContrast=a.brightnessContrast||new h(null,"uniform sampler2D texture;uniform float brightness;uniform float contrast;varying vec2 texCoord;void main(){vec4 color=texture2D(texture,texCoord);color.rgb+=brightness;if(contrast>0.0){color.rgb=(color.rgb-0.5)/(1.0-contrast)+0.5;}else{color.rgb=(color.rgb-0.5)*(1.0+contrast)+0.5;}gl_FragColor=color;}"); +f.call(this,a.brightnessContrast,{brightness:q(-1,b,1),contrast:q(-1,d,1)});return this}function t(a){a=new z(a);for(var d=[],c=0;256>c;c++)d.push(q(0,Math.floor(256*a.interpolate(c/255)),255));return d}function M(b,d,c){b=t(b);1==arguments.length?d=c=b:(d=t(d),c=t(c));for(var e=[],g=0;256>g;g++)e.splice(e.length,0,b[g],d[g],c[g],255);this._.extraTexture.initFromBytes(256,1,e);this._.extraTexture.use(1);a.curves=a.curves||new h(null,"uniform sampler2D texture;uniform sampler2D map;varying vec2 texCoord;void main(){vec4 color=texture2D(texture,texCoord);color.r=texture2D(map,vec2(color.r)).r;color.g=texture2D(map,vec2(color.g)).g;color.b=texture2D(map,vec2(color.b)).b;gl_FragColor=color;}"); +a.curves.textures({map:1});f.call(this,a.curves,{});return this}function N(b,d){a.unsharpMask=a.unsharpMask||new h(null,"uniform sampler2D blurredTexture;uniform sampler2D originalTexture;uniform float strength;uniform float threshold;varying vec2 texCoord;void main(){vec4 blurred=texture2D(blurredTexture,texCoord);vec4 original=texture2D(originalTexture,texCoord);gl_FragColor=mix(blurred,original,1.0+strength);}"); +this._.extraTexture.ensureFormat(this._.texture);this._.texture.use();this._.extraTexture.drawTo(function(){h.getDefaultShader().drawRect()});this._.extraTexture.use(1);this.triangleBlur(b);a.unsharpMask.textures({originalTexture:1});f.call(this,a.unsharpMask,{strength:d});this._.extraTexture.unuse(1);return this}function O(b){a.sepia=a.sepia||new h(null,"uniform sampler2D texture;uniform float amount;varying vec2 texCoord;void main(){vec4 color=texture2D(texture,texCoord);float r=color.r;float g=color.g;float b=color.b;color.r=min(1.0,(r*(1.0-(0.607*amount)))+(g*(0.769*amount))+(b*(0.189*amount)));color.g=min(1.0,(r*0.349*amount)+(g*(1.0-(0.314*amount)))+(b*0.168*amount));color.b=min(1.0,(r*0.272*amount)+(g*0.534*amount)+(b*(1.0-(0.869*amount))));gl_FragColor=color;}"); +f.call(this,a.sepia,{amount:q(0,b,1)});return this}function P(b,d){a.hueSaturation=a.hueSaturation||new h(null,"uniform sampler2D texture;uniform float hue;uniform float saturation;varying vec2 texCoord;void main(){vec4 color=texture2D(texture,texCoord);float angle=hue*3.14159265;float s=sin(angle),c=cos(angle);vec3 weights=(vec3(2.0*c,-sqrt(3.0)*s-c,sqrt(3.0)*s-c)+1.0)/3.0;float len=length(color.rgb);color.rgb=vec3(dot(color.rgb,weights.xyz),dot(color.rgb,weights.zxy),dot(color.rgb,weights.yzx));float average=(color.r+color.g+color.b)/3.0;if(saturation>0.0){color.rgb+=(average-color.rgb)*(1.0-1.0/(1.001-saturation));}else{color.rgb+=(average-color.rgb)*(-saturation);}gl_FragColor=color;}"); +f.call(this,a.hueSaturation,{hue:q(-1,b,1),saturation:q(-1,d,1)});return this}function Q(b,d,c){a.zoomBlur=a.zoomBlur||new h(null,"uniform sampler2D texture;uniform vec2 center;uniform float strength;uniform vec2 texSize;varying vec2 texCoord;"+s+"void main(){vec4 color=vec4(0.0);float total=0.0;vec2 toCenter=center-texCoord*texSize;float offset=random(vec3(12.9898,78.233,151.7182),0.0);for(float t=0.0;t<=40.0;t++){float percent=(t+offset)/40.0;float weight=4.0*(percent-percent*percent);vec4 sample=texture2D(texture,texCoord+toCenter*percent*strength/texSize);sample.rgb*=sample.a;color+=sample*weight;total+=weight;}gl_FragColor=color/total;gl_FragColor.rgb/=gl_FragColor.a+0.00001;}"); +f.call(this,a.zoomBlur,{center:[b,d],strength:c,texSize:[this.width,this.height]});return this}function R(b,d,c,e,g,n){a.tiltShift=a.tiltShift||new h(null,"uniform sampler2D texture;uniform float blurRadius;uniform float gradientRadius;uniform vec2 start;uniform vec2 end;uniform vec2 delta;uniform vec2 texSize;varying vec2 texCoord;"+s+"void main(){vec4 color=vec4(0.0);float total=0.0;float offset=random(vec3(12.9898,78.233,151.7182),0.0);vec2 normal=normalize(vec2(start.y-end.y,end.x-start.x));float radius=smoothstep(0.0,1.0,abs(dot(texCoord*texSize-start,normal))/gradientRadius)*blurRadius;for(float t=-30.0;t<=30.0;t++){float percent=(t+offset-0.5)/30.0;float weight=1.0-abs(percent);vec4 sample=texture2D(texture,texCoord+delta/texSize*percent*radius);sample.rgb*=sample.a;color+=sample*weight;total+=weight;}gl_FragColor=color/total;gl_FragColor.rgb/=gl_FragColor.a+0.00001;}"); +var l=c-b,p=e-d,m=Math.sqrt(l*l+p*p);f.call(this,a.tiltShift,{blurRadius:g,gradientRadius:n,start:[b,d],end:[c,e],delta:[l/m,p/m],texSize:[this.width,this.height]});f.call(this,a.tiltShift,{blurRadius:g,gradientRadius:n,start:[b,d],end:[c,e],delta:[-p/m,l/m],texSize:[this.width,this.height]});return this}function S(b,d,c){a.lensBlurPrePass=a.lensBlurPrePass||new h(null,"uniform sampler2D texture;uniform float power;varying vec2 texCoord;void main(){vec4 color=texture2D(texture,texCoord);color=pow(color,vec4(power));gl_FragColor=vec4(color);}"); +var e="uniform sampler2D texture0;uniform sampler2D texture1;uniform vec2 delta0;uniform vec2 delta1;uniform float power;varying vec2 texCoord;"+s+"vec4 sample(vec2 delta){float offset=random(vec3(delta,151.7182),0.0);vec4 color=vec4(0.0);float total=0.0;for(float t=0.0;t<=30.0;t++){float percent=(t+offset)/30.0;color+=texture2D(texture0,texCoord+delta*percent);total+=1.0;}return color/total;}"; +a.lensBlur0=a.lensBlur0||new h(null,e+"void main(){gl_FragColor=sample(delta0);}");a.lensBlur1=a.lensBlur1||new h(null,e+"void main(){gl_FragColor=(sample(delta0)+sample(delta1))*0.5;}");a.lensBlur2=a.lensBlur2||(new h(null,e+"void main(){vec4 color=(sample(delta0)+2.0*texture2D(texture1,texCoord))/3.0;gl_FragColor=pow(color,vec4(power));}")).textures({texture1:1});for(var e= +[],g=0;3>g;g++){var n=c+2*g*Math.PI/3;e.push([b*Math.sin(n)/this.width,b*Math.cos(n)/this.height])}b=Math.pow(10,q(-1,d,1));f.call(this,a.lensBlurPrePass,{power:b});this._.extraTexture.ensureFormat(this._.texture);f.call(this,a.lensBlur0,{delta0:e[0]},this._.texture,this._.extraTexture);f.call(this,a.lensBlur1,{delta0:e[1],delta1:e[2]},this._.extraTexture,this._.extraTexture);f.call(this,a.lensBlur0,{delta0:e[1]});this._.extraTexture.use(1);f.call(this,a.lensBlur2,{power:1/b,delta0:e[2]});return this} +function T(b){a.triangleBlur=a.triangleBlur||new h(null,"uniform sampler2D texture;uniform vec2 delta;varying vec2 texCoord;"+s+"void main(){vec4 color=vec4(0.0);float total=0.0;float offset=random(vec3(12.9898,78.233,151.7182),0.0);for(float t=-30.0;t<=30.0;t++){float percent=(t+offset-0.5)/30.0;float weight=1.0-abs(percent);vec4 sample=texture2D(texture,texCoord+delta*percent);sample.rgb*=sample.a;color+=sample*weight;total+=weight;}gl_FragColor=color/total;gl_FragColor.rgb/=gl_FragColor.a+0.00001;}"); +f.call(this,a.triangleBlur,{delta:[b/this.width,0]});f.call(this,a.triangleBlur,{delta:[0,b/this.height]});return this}function U(b){a.edgeWork1=a.edgeWork1||new h(null,"uniform sampler2D texture;uniform vec2 delta;varying vec2 texCoord;"+s+"void main(){vec2 color=vec2(0.0);vec2 total=vec2(0.0);float offset=random(vec3(12.9898,78.233,151.7182),0.0);for(float t=-30.0;t<=30.0;t++){float percent=(t+offset-0.5)/30.0;float weight=1.0-abs(percent);vec3 sample=texture2D(texture,texCoord+delta*percent).rgb;float average=(sample.r+sample.g+sample.b)/3.0;color.x+=average*weight;total.x+=weight;if(abs(t)<15.0){weight=weight*2.0-1.0;color.y+=average*weight;total.y+=weight;}}gl_FragColor=vec4(color/total,0.0,1.0);}"); +a.edgeWork2=a.edgeWork2||new h(null,"uniform sampler2D texture;uniform vec2 delta;varying vec2 texCoord;"+s+"void main(){vec2 color=vec2(0.0);vec2 total=vec2(0.0);float offset=random(vec3(12.9898,78.233,151.7182),0.0);for(float t=-30.0;t<=30.0;t++){float percent=(t+offset-0.5)/30.0;float weight=1.0-abs(percent);vec2 sample=texture2D(texture,texCoord+delta*percent).xy;color.x+=sample.x*weight;total.x+=weight;if(abs(t)<15.0){weight=weight*2.0-1.0;color.y+=sample.y*weight;total.y+=weight;}}float c=clamp(10000.0*(color.y/total.y-color.x/total.x)+0.5,0.0,1.0);gl_FragColor=vec4(c,c,c,1.0);}"); +f.call(this,a.edgeWork1,{delta:[b/this.width,0]});f.call(this,a.edgeWork2,{delta:[0,b/this.height]});return this}function V(b,d,c){a.hexagonalPixelate=a.hexagonalPixelate||new h(null,"uniform sampler2D texture;uniform vec2 center;uniform float scale;uniform vec2 texSize;varying vec2 texCoord;void main(){vec2 tex=(texCoord*texSize-center)/scale;tex.y/=0.866025404;tex.x-=tex.y*0.5;vec2 a;if(tex.x+tex.y-floor(tex.x)-floor(tex.y)<1.0)a=vec2(floor(tex.x),floor(tex.y));else a=vec2(ceil(tex.x),ceil(tex.y));vec2 b=vec2(ceil(tex.x),floor(tex.y));vec2 c=vec2(floor(tex.x),ceil(tex.y));vec3 TEX=vec3(tex.x,tex.y,1.0-tex.x-tex.y);vec3 A=vec3(a.x,a.y,1.0-a.x-a.y);vec3 B=vec3(b.x,b.y,1.0-b.x-b.y);vec3 C=vec3(c.x,c.y,1.0-c.x-c.y);float alen=length(TEX-A);float blen=length(TEX-B);float clen=length(TEX-C);vec2 choice;if(alen0.0){coord*=mix(1.0,smoothstep(0.0,radius/distance,percent),strength*0.75);}else{coord*=mix(1.0,pow(percent,1.0+strength*0.75)*radius/distance,1.0-percent);}}coord+=center;"); +f.call(this,a.bulgePinch,{radius:c,strength:q(-1,e,1),center:[b,d],texSize:[this.width,this.height]});return this}function ba(a,d){var c=x.apply(null,d),e=x.apply(null,a),c=y(c);return this.matrixWarp([c[0]*e[0]+c[1]*e[3]+c[2]*e[6],c[0]*e[1]+c[1]*e[4]+c[2]*e[7],c[0]*e[2]+c[1]*e[5]+c[2]*e[8],c[3]*e[0]+c[4]*e[3]+c[5]*e[6],c[3]*e[1]+c[4]*e[4]+c[5]*e[7],c[3]*e[2]+c[4]*e[5]+c[5]*e[8],c[6]*e[0]+c[7]*e[3]+c[8]*e[6],c[6]*e[1]+c[7]*e[4]+c[8]*e[7],c[6]*e[2]+c[7]*e[5]+c[8]*e[8]])}var v={};(function(){function a(b){if(!b.getExtension("OES_texture_float"))return!1; +var c=b.createFramebuffer(),e=b.createTexture();b.bindTexture(b.TEXTURE_2D,e);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.NEAREST);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE);b.texImage2D(b.TEXTURE_2D,0,b.RGBA,1,1,0,b.RGBA,b.UNSIGNED_BYTE,null);b.bindFramebuffer(b.FRAMEBUFFER,c);b.framebufferTexture2D(b.FRAMEBUFFER,b.COLOR_ATTACHMENT0,b.TEXTURE_2D, +e,0);c=b.createTexture();b.bindTexture(b.TEXTURE_2D,c);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MAG_FILTER,b.LINEAR);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_MIN_FILTER,b.LINEAR);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.CLAMP_TO_EDGE);b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.CLAMP_TO_EDGE);b.texImage2D(b.TEXTURE_2D,0,b.RGBA,2,2,0,b.RGBA,b.FLOAT,new Float32Array([2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]));var e=b.createProgram(),d=b.createShader(b.VERTEX_SHADER),g=b.createShader(b.FRAGMENT_SHADER); +b.shaderSource(d,"attribute vec2 vertex;void main(){gl_Position=vec4(vertex,0.0,1.0);}");b.shaderSource(g,"uniform sampler2D texture;void main(){gl_FragColor=texture2D(texture,vec2(0.5));}");b.compileShader(d);b.compileShader(g);b.attachShader(e,d);b.attachShader(e,g);b.linkProgram(e);d=b.createBuffer();b.bindBuffer(b.ARRAY_BUFFER,d);b.bufferData(b.ARRAY_BUFFER,new Float32Array([0,0]),b.STREAM_DRAW);b.enableVertexAttribArray(0); +b.vertexAttribPointer(0,2,b.FLOAT,!1,0,0);d=new Uint8Array(4);b.useProgram(e);b.viewport(0,0,1,1);b.bindTexture(b.TEXTURE_2D,c);b.drawArrays(b.POINTS,0,1);b.readPixels(0,0,1,1,b.RGBA,b.UNSIGNED_BYTE,d);return 127===d[0]||128===d[0]}function d(){}function c(a){"OES_texture_float_linear"===a?(void 0===this.$OES_texture_float_linear$&&Object.defineProperty(this,"$OES_texture_float_linear$",{enumerable:!1,configurable:!1,writable:!1,value:new d}),a=this.$OES_texture_float_linear$):a=l.call(this,a);return a} +function e(){var a=f.call(this);-1===a.indexOf("OES_texture_float_linear")&&a.push("OES_texture_float_linear");return a}try{var g=document.createElement("canvas").getContext("experimental-webgl")}catch(n){}if(g&&-1===g.getSupportedExtensions().indexOf("OES_texture_float_linear")&&a(g)){var l=WebGLRenderingContext.prototype.getExtension,f=WebGLRenderingContext.prototype.getSupportedExtensions;WebGLRenderingContext.prototype.getExtension=c;WebGLRenderingContext.prototype.getSupportedExtensions=e}})(); +var a;v.canvas=function(){var b=document.createElement("canvas");try{a=b.getContext("experimental-webgl",{premultipliedAlpha:!1})}catch(d){a=null}if(!a)throw"This browser does not support WebGL";b._={gl:a,isInitialized:!1,texture:null,spareTexture:null,flippedShader:null};b.texture=k(A);b.draw=k(C);b.update=k(D);b.replace=k(E);b.contents=k(F);b.getPixelArray=k(G);b.brightnessContrast=k(L);b.hexagonalPixelate=k(V);b.hueSaturation=k(P);b.colorHalftone=k(W);b.triangleBlur=k(T);b.unsharpMask=k(N);b.perspective= +k(ba);b.matrixWarp=k(Z);b.bulgePinch=k(aa);b.tiltShift=k(R);b.dotScreen=k(Y);b.edgeWork=k(U);b.lensBlur=k(S);b.zoomBlur=k(Q);b.noise=k(H);b.denoise=k(K);b.curves=k(M);b.swirl=k($);b.ink=k(X);b.vignette=k(J);b.vibrance=k(I);b.sepia=k(O);return b};v.splineInterpolate=t;var r=function(){function b(b,c,d,l){this.gl=a;this.id=a.createTexture();this.width=b;this.height=c;this.format=d;this.type=l;a.bindTexture(a.TEXTURE_2D,this.id);a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.LINEAR);a.texParameteri(a.TEXTURE_2D, +a.TEXTURE_MIN_FILTER,a.LINEAR);a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE);a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE);b&&c&&a.texImage2D(a.TEXTURE_2D,0,this.format,b,c,0,this.format,this.type,null)}function d(a){null==c&&(c=document.createElement("canvas"));c.width=a.width;c.height=a.height;a=c.getContext("2d");a.clearRect(0,0,c.width,c.height);return a}b.fromElement=function(c){var d=new b(0,0,a.RGBA,a.UNSIGNED_BYTE);d.loadContentsOf(c);return d};b.prototype.loadContentsOf= +function(b){this.width=b.width||b.videoWidth;this.height=b.height||b.videoHeight;a.bindTexture(a.TEXTURE_2D,this.id);a.texImage2D(a.TEXTURE_2D,0,this.format,this.format,this.type,b)};b.prototype.initFromBytes=function(b,c,d){this.width=b;this.height=c;this.format=a.RGBA;this.type=a.UNSIGNED_BYTE;a.bindTexture(a.TEXTURE_2D,this.id);a.texImage2D(a.TEXTURE_2D,0,a.RGBA,b,c,0,a.RGBA,this.type,new Uint8Array(d))};b.prototype.destroy=function(){a.deleteTexture(this.id);this.id=null};b.prototype.use=function(b){a.activeTexture(a.TEXTURE0+ +(b||0));a.bindTexture(a.TEXTURE_2D,this.id)};b.prototype.unuse=function(b){a.activeTexture(a.TEXTURE0+(b||0));a.bindTexture(a.TEXTURE_2D,null)};b.prototype.ensureFormat=function(b,c,d,l){if(1==arguments.length){var f=arguments[0];b=f.width;c=f.height;d=f.format;l=f.type}if(b!=this.width||c!=this.height||d!=this.format||l!=this.type)this.width=b,this.height=c,this.format=d,this.type=l,a.bindTexture(a.TEXTURE_2D,this.id),a.texImage2D(a.TEXTURE_2D,0,this.format,b,c,0,this.format,this.type,null)};b.prototype.drawTo= +function(b){a.framebuffer=a.framebuffer||a.createFramebuffer();a.bindFramebuffer(a.FRAMEBUFFER,a.framebuffer);a.framebufferTexture2D(a.FRAMEBUFFER,a.COLOR_ATTACHMENT0,a.TEXTURE_2D,this.id,0);if(a.checkFramebufferStatus(a.FRAMEBUFFER)!==a.FRAMEBUFFER_COMPLETE)throw Error("incomplete framebuffer");a.viewport(0,0,this.width,this.height);b();a.bindFramebuffer(a.FRAMEBUFFER,null)};var c=null;b.prototype.fillUsingCanvas=function(b){b(d(this));this.format=a.RGBA;this.type=a.UNSIGNED_BYTE;a.bindTexture(a.TEXTURE_2D, +this.id);a.texImage2D(a.TEXTURE_2D,0,a.RGBA,a.RGBA,a.UNSIGNED_BYTE,c);return this};b.prototype.toImage=function(b){this.use();h.getDefaultShader().drawRect();var g=4*this.width*this.height,f=new Uint8Array(g),l=d(this),p=l.createImageData(this.width,this.height);a.readPixels(0,0,this.width,this.height,a.RGBA,a.UNSIGNED_BYTE,f);for(var m=0;m>1;this.xa[e]>a?c=e:d=e}var e=this.xa[c]-this.xa[d],g=(this.xa[c]-a)/e;a=(a-this.xa[d])/e;return g*this.ya[d]+a*this.ya[c]+((g*g*g-g)*this.y2[d]+(a*a*a-a)*this.y2[c])*e*e/6};var h=function(){function b(b,c){var d=a.createShader(b);a.shaderSource(d,c);a.compileShader(d);if(!a.getShaderParameter(d,a.COMPILE_STATUS))throw"compile error: "+ +a.getShaderInfoLog(d);return d}function d(d,f){this.texCoordAttribute=this.vertexAttribute=null;this.program=a.createProgram();d=d||c;f=f||e;f="precision highp float;"+f;a.attachShader(this.program,b(a.VERTEX_SHADER,d));a.attachShader(this.program,b(a.FRAGMENT_SHADER,f));a.linkProgram(this.program);if(!a.getProgramParameter(this.program,a.LINK_STATUS))throw"link error: "+a.getProgramInfoLog(this.program);}var c="attribute vec2 vertex;attribute vec2 _texCoord;varying vec2 texCoord;void main(){texCoord=_texCoord;gl_Position=vec4(vertex*2.0-1.0,0.0,1.0);}", +e="uniform sampler2D texture;varying vec2 texCoord;void main(){gl_FragColor=texture2D(texture,texCoord);}";d.prototype.destroy=function(){a.deleteProgram(this.program);this.program=null};d.prototype.uniforms=function(b){a.useProgram(this.program);for(var c in b)if(b.hasOwnProperty(c)){var d=a.getUniformLocation(this.program,c);if(null!==d){var e=b[c];if("[object Array]"==Object.prototype.toString.call(e))switch(e.length){case 1:a.uniform1fv(d,new Float32Array(e));break; +case 2:a.uniform2fv(d,new Float32Array(e));break;case 3:a.uniform3fv(d,new Float32Array(e));break;case 4:a.uniform4fv(d,new Float32Array(e));break;case 9:a.uniformMatrix3fv(d,!1,new Float32Array(e));break;case 16:a.uniformMatrix4fv(d,!1,new Float32Array(e));break;default:throw"dont't know how to load uniform \""+c+'" of length '+e.length;}else if("[object Number]"==Object.prototype.toString.call(e))a.uniform1f(d,e);else throw'attempted to set uniform "'+c+'" to invalid value '+(e||"undefined").toString(); +}}return this};d.prototype.textures=function(b){a.useProgram(this.program);for(var c in b)b.hasOwnProperty(c)&&a.uniform1i(a.getUniformLocation(this.program,c),b[c]);return this};d.prototype.drawRect=function(b,c,d,e){var f=a.getParameter(a.VIEWPORT);c=void 0!==c?(c-f[1])/f[3]:0;b=void 0!==b?(b-f[0])/f[2]:0;d=void 0!==d?(d-f[0])/f[2]:1;e=void 0!==e?(e-f[1])/f[3]:1;null==a.vertexBuffer&&(a.vertexBuffer=a.createBuffer());a.bindBuffer(a.ARRAY_BUFFER,a.vertexBuffer);a.bufferData(a.ARRAY_BUFFER,new Float32Array([b, +c,b,e,d,c,d,e]),a.STATIC_DRAW);null==a.texCoordBuffer&&(a.texCoordBuffer=a.createBuffer(),a.bindBuffer(a.ARRAY_BUFFER,a.texCoordBuffer),a.bufferData(a.ARRAY_BUFFER,new Float32Array([0,0,0,1,1,0,1,1]),a.STATIC_DRAW));null==this.vertexAttribute&&(this.vertexAttribute=a.getAttribLocation(this.program,"vertex"),a.enableVertexAttribArray(this.vertexAttribute));null==this.texCoordAttribute&&(this.texCoordAttribute=a.getAttribLocation(this.program,"_texCoord"),a.enableVertexAttribArray(this.texCoordAttribute)); +a.useProgram(this.program);a.bindBuffer(a.ARRAY_BUFFER,a.vertexBuffer);a.vertexAttribPointer(this.vertexAttribute,2,a.FLOAT,!1,0,0);a.bindBuffer(a.ARRAY_BUFFER,a.texCoordBuffer);a.vertexAttribPointer(this.texCoordAttribute,2,a.FLOAT,!1,0,0);a.drawArrays(a.TRIANGLE_STRIP,0,4)};d.getDefaultShader=function(){a.defaultShader=a.defaultShader||new d;return a.defaultShader};return d}(),s="float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);}"; +return v}();"object"===typeof module?module.exports=fx:window.fx=fx; + +},{}],166:[function(require,module,exports){ +(function (process){ +'use strict'; +const {promisify} = require('util'); +const fs = require('fs'); +const path = require('path'); +const fastGlob = require('fast-glob'); +const gitIgnore = require('ignore'); +const slash = require('slash'); + +const DEFAULT_IGNORE = [ + '**/node_modules/**', + '**/flow-typed/**', + '**/coverage/**', + '**/.git' +]; + +const readFileP = promisify(fs.readFile); + +const mapGitIgnorePatternTo = base => ignore => { + if (ignore.startsWith('!')) { + return '!' + path.posix.join(base, ignore.slice(1)); + } + + return path.posix.join(base, ignore); +}; + +const parseGitIgnore = (content, options) => { + const base = slash(path.relative(options.cwd, path.dirname(options.fileName))); + + return content + .split(/\r?\n/) + .filter(Boolean) + .filter(line => !line.startsWith('#')) + .map(mapGitIgnorePatternTo(base)); +}; + +const reduceIgnore = files => { + return files.reduce((ignores, file) => { + ignores.add(parseGitIgnore(file.content, { + cwd: file.cwd, + fileName: file.filePath + })); + return ignores; + }, gitIgnore()); +}; + +const ensureAbsolutePathForCwd = (cwd, p) => { + if (path.isAbsolute(p)) { + if (p.startsWith(cwd)) { + return p; + } + + throw new Error(`Path ${p} is not in cwd ${cwd}`); + } + + return path.join(cwd, p); +}; + +const getIsIgnoredPredecate = (ignores, cwd) => { + return p => ignores.ignores(slash(path.relative(cwd, ensureAbsolutePathForCwd(cwd, p)))); +}; + +const getFile = async (file, cwd) => { + const filePath = path.join(cwd, file); + const content = await readFileP(filePath, 'utf8'); + + return { + cwd, + filePath, + content + }; +}; + +const getFileSync = (file, cwd) => { + const filePath = path.join(cwd, file); + const content = fs.readFileSync(filePath, 'utf8'); + + return { + cwd, + filePath, + content + }; +}; + +const normalizeOptions = ({ + ignore = [], + cwd = process.cwd() +} = {}) => { + return {ignore, cwd}; +}; + +module.exports = async options => { + options = normalizeOptions(options); + + const paths = await fastGlob('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); + + const files = await Promise.all(paths.map(file => getFile(file, options.cwd))); + const ignores = reduceIgnore(files); + + return getIsIgnoredPredecate(ignores, options.cwd); +}; + +module.exports.sync = options => { + options = normalizeOptions(options); + + const paths = fastGlob.sync('**/.gitignore', { + ignore: DEFAULT_IGNORE.concat(options.ignore), + cwd: options.cwd + }); + + const files = paths.map(file => getFileSync(file, options.cwd)); + const ignores = reduceIgnore(files); + + return getIsIgnoredPredecate(ignores, options.cwd); +}; + +}).call(this,require('_process')) +},{"_process":432,"fast-glob":83,"fs":296,"ignore":171,"path":402,"slash":501,"util":523}],167:[function(require,module,exports){ +'use strict'; +const fs = require('fs'); +const arrayUnion = require('array-union'); +const merge2 = require('merge2'); +const glob = require('glob'); +const fastGlob = require('fast-glob'); +const dirGlob = require('dir-glob'); +const gitignore = require('./gitignore'); +const {FilterStream, UniqueStream} = require('./stream-utils'); + +const DEFAULT_FILTER = () => false; + +const isNegative = pattern => pattern[0] === '!'; + +const assertPatternsInput = patterns => { + if (!patterns.every(pattern => typeof pattern === 'string')) { + throw new TypeError('Patterns must be a string or an array of strings'); + } +}; + +const checkCwdOption = (options = {}) => { + if (!options.cwd) { + return; + } + + let stat; + try { + stat = fs.statSync(options.cwd); + } catch (_) { + return; + } + + if (!stat.isDirectory()) { + throw new Error('The `cwd` option must be a path to a directory'); + } +}; + +const getPathString = p => p.stats instanceof fs.Stats ? p.path : p; + +const generateGlobTasks = (patterns, taskOptions) => { + patterns = arrayUnion([].concat(patterns)); + assertPatternsInput(patterns); + checkCwdOption(taskOptions); + + const globTasks = []; + + taskOptions = { + ignore: [], + expandDirectories: true, + ...taskOptions + }; + + for (const [index, pattern] of patterns.entries()) { + if (isNegative(pattern)) { + continue; + } + + const ignore = patterns + .slice(index) + .filter(isNegative) + .map(pattern => pattern.slice(1)); + + const options = { + ...taskOptions, + ignore: taskOptions.ignore.concat(ignore) + }; + + globTasks.push({pattern, options}); + } + + return globTasks; +}; + +const globDirs = (task, fn) => { + let options = {}; + if (task.options.cwd) { + options.cwd = task.options.cwd; + } + + if (Array.isArray(task.options.expandDirectories)) { + options = { + ...options, + files: task.options.expandDirectories + }; + } else if (typeof task.options.expandDirectories === 'object') { + options = { + ...options, + ...task.options.expandDirectories + }; + } + + return fn(task.pattern, options); +}; + +const getPattern = (task, fn) => task.options.expandDirectories ? globDirs(task, fn) : [task.pattern]; + +const getFilterSync = options => { + return options && options.gitignore ? + gitignore.sync({cwd: options.cwd, ignore: options.ignore}) : + DEFAULT_FILTER; +}; + +const globToTask = task => glob => { + const {options} = task; + if (options.ignore && Array.isArray(options.ignore) && options.expandDirectories) { + options.ignore = dirGlob.sync(options.ignore); + } + + return { + pattern: glob, + options + }; +}; + +module.exports = async (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); + + const getFilter = async () => { + return options && options.gitignore ? + gitignore({cwd: options.cwd, ignore: options.ignore}) : + DEFAULT_FILTER; + }; + + const getTasks = async () => { + const tasks = await Promise.all(globTasks.map(async task => { + const globs = await getPattern(task, dirGlob); + return Promise.all(globs.map(globToTask(task))); + })); + + return arrayUnion(...tasks); + }; + + const [filter, tasks] = await Promise.all([getFilter(), getTasks()]); + const paths = await Promise.all(tasks.map(task => fastGlob(task.pattern, task.options))); + + return arrayUnion(...paths).filter(path_ => !filter(getPathString(path_))); +}; + +module.exports.sync = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); + + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); + + const filter = getFilterSync(options); + + return tasks.reduce( + (matches, task) => arrayUnion(matches, fastGlob.sync(task.pattern, task.options)), + [] + ).filter(path_ => !filter(path_)); +}; + +module.exports.stream = (patterns, options) => { + const globTasks = generateGlobTasks(patterns, options); + + const tasks = globTasks.reduce((tasks, task) => { + const newTask = getPattern(task, dirGlob.sync).map(globToTask(task)); + return tasks.concat(newTask); + }, []); + + const filter = getFilterSync(options); + const filterStream = new FilterStream(p => !filter(p)); + const uniqueStream = new UniqueStream(); + + return merge2(tasks.map(task => fastGlob.stream(task.pattern, task.options))) + .pipe(filterStream) + .pipe(uniqueStream); +}; + +module.exports.generateGlobTasks = generateGlobTasks; + +module.exports.hasMagic = (patterns, options) => [] + .concat(patterns) + .some(pattern => glob.hasMagic(pattern, options)); + +module.exports.gitignore = gitignore; + +},{"./gitignore":166,"./stream-utils":172,"array-union":24,"dir-glob":53,"fast-glob":83,"fs":296,"glob":169,"merge2":379}],168:[function(require,module,exports){ +(function (process){ +exports.alphasort = alphasort +exports.alphasorti = alphasorti +exports.setopts = setopts +exports.ownProp = ownProp +exports.makeAbs = makeAbs +exports.finish = finish +exports.mark = mark +exports.isIgnored = isIgnored +exports.childrenIgnored = childrenIgnored + +function ownProp (obj, field) { + return Object.prototype.hasOwnProperty.call(obj, field) +} + +var path = require("path") +var minimatch = require("minimatch") +var isAbsolute = require("path-is-absolute") +var Minimatch = minimatch.Minimatch + +function alphasorti (a, b) { + return a.toLowerCase().localeCompare(b.toLowerCase()) +} + +function alphasort (a, b) { + return a.localeCompare(b) +} + +function setupIgnores (self, options) { + self.ignore = options.ignore || [] + + if (!Array.isArray(self.ignore)) + self.ignore = [self.ignore] + + if (self.ignore.length) { + self.ignore = self.ignore.map(ignoreMap) + } +} + +// ignore patterns are always in dot:true mode. +function ignoreMap (pattern) { + var gmatcher = null + if (pattern.slice(-3) === '/**') { + var gpattern = pattern.replace(/(\/\*\*)+$/, '') + gmatcher = new Minimatch(gpattern, { dot: true }) + } + + return { + matcher: new Minimatch(pattern, { dot: true }), + gmatcher: gmatcher + } +} + +function setopts (self, pattern, options) { + if (!options) + options = {} + + // base-matching: just use globstar for that. + if (options.matchBase && -1 === pattern.indexOf("/")) { + if (options.noglobstar) { + throw new Error("base matching requires globstar") + } + pattern = "**/" + pattern + } + + self.silent = !!options.silent + self.pattern = pattern + self.strict = options.strict !== false + self.realpath = !!options.realpath + self.realpathCache = options.realpathCache || Object.create(null) + self.follow = !!options.follow + self.dot = !!options.dot + self.mark = !!options.mark + self.nodir = !!options.nodir + if (self.nodir) + self.mark = true + self.sync = !!options.sync + self.nounique = !!options.nounique + self.nonull = !!options.nonull + self.nosort = !!options.nosort + self.nocase = !!options.nocase + self.stat = !!options.stat + self.noprocess = !!options.noprocess + self.absolute = !!options.absolute + + self.maxLength = options.maxLength || Infinity + self.cache = options.cache || Object.create(null) + self.statCache = options.statCache || Object.create(null) + self.symlinks = options.symlinks || Object.create(null) + + setupIgnores(self, options) + + self.changedCwd = false + var cwd = process.cwd() + if (!ownProp(options, "cwd")) + self.cwd = cwd + else { + self.cwd = path.resolve(options.cwd) + self.changedCwd = self.cwd !== cwd + } + + self.root = options.root || path.resolve(self.cwd, "/") + self.root = path.resolve(self.root) + if (process.platform === "win32") + self.root = self.root.replace(/\\/g, "/") + + // TODO: is an absolute `cwd` supposed to be resolved against `root`? + // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') + self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) + if (process.platform === "win32") + self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") + self.nomount = !!options.nomount + + // disable comments and negation in Minimatch. + // Note that they are not supported in Glob itself anyway. + options.nonegate = true + options.nocomment = true + + self.minimatch = new Minimatch(pattern, options) + self.options = self.minimatch.options +} + +function finish (self) { + var nou = self.nounique + var all = nou ? [] : Object.create(null) + + for (var i = 0, l = self.matches.length; i < l; i ++) { + var matches = self.matches[i] + if (!matches || Object.keys(matches).length === 0) { + if (self.nonull) { + // do like the shell, and spit out the literal glob + var literal = self.minimatch.globSet[i] + if (nou) + all.push(literal) + else + all[literal] = true + } + } else { + // had matches + var m = Object.keys(matches) + if (nou) + all.push.apply(all, m) + else + m.forEach(function (m) { + all[m] = true + }) + } + } + + if (!nou) + all = Object.keys(all) + + if (!self.nosort) + all = all.sort(self.nocase ? alphasorti : alphasort) + + // at *some* point we statted all of these + if (self.mark) { + for (var i = 0; i < all.length; i++) { + all[i] = self._mark(all[i]) + } + if (self.nodir) { + all = all.filter(function (e) { + var notDir = !(/\/$/.test(e)) + var c = self.cache[e] || self.cache[makeAbs(self, e)] + if (notDir && c) + notDir = c !== 'DIR' && !Array.isArray(c) + return notDir + }) + } + } + + if (self.ignore.length) + all = all.filter(function(m) { + return !isIgnored(self, m) + }) + + self.found = all +} + +function mark (self, p) { + var abs = makeAbs(self, p) + var c = self.cache[abs] + var m = p + if (c) { + var isDir = c === 'DIR' || Array.isArray(c) + var slash = p.slice(-1) === '/' + + if (isDir && !slash) + m += '/' + else if (!isDir && slash) + m = m.slice(0, -1) + + if (m !== p) { + var mabs = makeAbs(self, m) + self.statCache[mabs] = self.statCache[abs] + self.cache[mabs] = self.cache[abs] + } + } + + return m +} + +// lotta situps... +function makeAbs (self, f) { + var abs = f + if (f.charAt(0) === '/') { + abs = path.join(self.root, f) + } else if (isAbsolute(f) || f === '') { + abs = f + } else if (self.changedCwd) { + abs = path.resolve(self.cwd, f) + } else { + abs = path.resolve(f) + } + + if (process.platform === 'win32') + abs = abs.replace(/\\/g, '/') + + return abs +} + + +// Return true, if pattern ends with globstar '**', for the accompanying parent directory. +// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents +function isIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +function childrenIgnored (self, path) { + if (!self.ignore.length) + return false + + return self.ignore.some(function(item) { + return !!(item.gmatcher && item.gmatcher.match(path)) + }) +} + +}).call(this,require('_process')) +},{"_process":432,"minimatch":383,"path":402,"path-is-absolute":403}],169:[function(require,module,exports){ +(function (process){ +// Approach: +// +// 1. Get the minimatch set +// 2. For each pattern in the set, PROCESS(pattern, false) +// 3. Store matches per-set, then uniq them +// +// PROCESS(pattern, inGlobStar) +// Get the first [n] items from pattern that are all strings +// Join these together. This is PREFIX. +// If there is no more remaining, then stat(PREFIX) and +// add to matches if it succeeds. END. +// +// If inGlobStar and PREFIX is symlink and points to dir +// set ENTRIES = [] +// else readdir(PREFIX) as ENTRIES +// If fail, END +// +// with ENTRIES +// If pattern[n] is GLOBSTAR +// // handle the case where the globstar match is empty +// // by pruning it out, and testing the resulting pattern +// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) +// // handle other cases. +// for ENTRY in ENTRIES (not dotfiles) +// // attach globstar + tail onto the entry +// // Mark that this entry is a globstar match +// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) +// +// else // not globstar +// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) +// Test ENTRY against pattern[n] +// If fails, continue +// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) +// +// Caveat: +// Cache all stats and readdirs results to minimize syscall. Since all +// we ever care about is existence and directory-ness, we can just keep +// `true` for files, and [children,...] for directories, or `false` for +// things that don't exist. + +module.exports = glob + +var fs = require('fs') +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var inherits = require('inherits') +var EE = require('events').EventEmitter +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var globSync = require('./sync.js') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var inflight = require('inflight') +var util = require('util') +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +var once = require('once') + +function glob (pattern, options, cb) { + if (typeof options === 'function') cb = options, options = {} + if (!options) options = {} + + if (options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return globSync(pattern, options) + } + + return new Glob(pattern, options, cb) +} + +glob.sync = globSync +var GlobSync = glob.GlobSync = globSync.GlobSync + +// old api surface +glob.glob = glob + +function extend (origin, add) { + if (add === null || typeof add !== 'object') { + return origin + } + + var keys = Object.keys(add) + var i = keys.length + while (i--) { + origin[keys[i]] = add[keys[i]] + } + return origin +} + +glob.hasMagic = function (pattern, options_) { + var options = extend({}, options_) + options.noprocess = true + + var g = new Glob(pattern, options) + var set = g.minimatch.set + + if (!pattern) + return false + + if (set.length > 1) + return true + + for (var j = 0; j < set[0].length; j++) { + if (typeof set[0][j] !== 'string') + return true + } + + return false +} + +glob.Glob = Glob +inherits(Glob, EE) +function Glob (pattern, options, cb) { + if (typeof options === 'function') { + cb = options + options = null + } + + if (options && options.sync) { + if (cb) + throw new TypeError('callback provided to sync glob') + return new GlobSync(pattern, options) + } + + if (!(this instanceof Glob)) + return new Glob(pattern, options, cb) + + setopts(this, pattern, options) + this._didRealPath = false + + // process each pattern in the minimatch set + var n = this.minimatch.set.length + + // The matches are stored as {: true,...} so that + // duplicates are automagically pruned. + // Later, we do an Object.keys() on these. + // Keep them as a list so we can fill in when nonull is set. + this.matches = new Array(n) + + if (typeof cb === 'function') { + cb = once(cb) + this.on('error', cb) + this.on('end', function (matches) { + cb(null, matches) + }) + } + + var self = this + this._processing = 0 + + this._emitQueue = [] + this._processQueue = [] + this.paused = false + + if (this.noprocess) + return this + + if (n === 0) + return done() + + var sync = true + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false, done) + } + sync = false + + function done () { + --self._processing + if (self._processing <= 0) { + if (sync) { + process.nextTick(function () { + self._finish() + }) + } else { + self._finish() + } + } + } +} + +Glob.prototype._finish = function () { + assert(this instanceof Glob) + if (this.aborted) + return + + if (this.realpath && !this._didRealpath) + return this._realpath() + + common.finish(this) + this.emit('end', this.found) +} + +Glob.prototype._realpath = function () { + if (this._didRealpath) + return + + this._didRealpath = true + + var n = this.matches.length + if (n === 0) + return this._finish() + + var self = this + for (var i = 0; i < this.matches.length; i++) + this._realpathSet(i, next) + + function next () { + if (--n === 0) + self._finish() + } +} + +Glob.prototype._realpathSet = function (index, cb) { + var matchset = this.matches[index] + if (!matchset) + return cb() + + var found = Object.keys(matchset) + var self = this + var n = found.length + + if (n === 0) + return cb() + + var set = this.matches[index] = Object.create(null) + found.forEach(function (p, i) { + // If there's a problem with the stat, then it means that + // one or more of the links in the realpath couldn't be + // resolved. just return the abs value in that case. + p = self._makeAbs(p) + rp.realpath(p, self.realpathCache, function (er, real) { + if (!er) + set[real] = true + else if (er.syscall === 'stat') + set[p] = true + else + self.emit('error', er) // srsly wtf right here + + if (--n === 0) { + self.matches[index] = set + cb() + } + }) + }) +} + +Glob.prototype._mark = function (p) { + return common.mark(this, p) +} + +Glob.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +Glob.prototype.abort = function () { + this.aborted = true + this.emit('abort') +} + +Glob.prototype.pause = function () { + if (!this.paused) { + this.paused = true + this.emit('pause') + } +} + +Glob.prototype.resume = function () { + if (this.paused) { + this.emit('resume') + this.paused = false + if (this._emitQueue.length) { + var eq = this._emitQueue.slice(0) + this._emitQueue.length = 0 + for (var i = 0; i < eq.length; i ++) { + var e = eq[i] + this._emitMatch(e[0], e[1]) + } + } + if (this._processQueue.length) { + var pq = this._processQueue.slice(0) + this._processQueue.length = 0 + for (var i = 0; i < pq.length; i ++) { + var p = pq[i] + this._processing-- + this._process(p[0], p[1], p[2], p[3]) + } + } + } +} + +Glob.prototype._process = function (pattern, index, inGlobStar, cb) { + assert(this instanceof Glob) + assert(typeof cb === 'function') + + if (this.aborted) + return + + this._processing++ + if (this.paused) { + this._processQueue.push([pattern, index, inGlobStar, cb]) + return + } + + //console.error('PROCESS %d', this._processing, pattern) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // see if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index, cb) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip _processing + if (childrenIgnored(this, read)) + return cb() + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb) +} + +Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + +Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return cb() + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return cb() + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return cb() + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) { + if (prefix !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + this._process([e].concat(remain), index, inGlobStar, cb) + } + cb() +} + +Glob.prototype._emitMatch = function (index, e) { + if (this.aborted) + return + + if (isIgnored(this, e)) + return + + if (this.paused) { + this._emitQueue.push([index, e]) + return + } + + var abs = isAbsolute(e) ? e : this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) + e = abs + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + var st = this.statCache[abs] + if (st) + this.emit('stat', e, st) + + this.emit('match', e) +} + +Glob.prototype._readdirInGlobStar = function (abs, cb) { + if (this.aborted) + return + + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false, cb) + + var lstatkey = 'lstat\0' + abs + var self = this + var lstatcb = inflight(lstatkey, lstatcb_) + + if (lstatcb) + fs.lstat(abs, lstatcb) + + function lstatcb_ (er, lstat) { + if (er && er.code === 'ENOENT') + return cb() + + var isSym = lstat && lstat.isSymbolicLink() + self.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) { + self.cache[abs] = 'FILE' + cb() + } else + self._readdir(abs, false, cb) + } +} + +Glob.prototype._readdir = function (abs, inGlobStar, cb) { + if (this.aborted) + return + + cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb) + if (!cb) + return + + //console.error('RD %j %j', +inGlobStar, abs) + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs, cb) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return cb() + + if (Array.isArray(c)) + return cb(null, c) + } + + var self = this + fs.readdir(abs, readdirCb(this, abs, cb)) +} + +function readdirCb (self, abs, cb) { + return function (er, entries) { + if (er) + self._readdirError(abs, er, cb) + else + self._readdirEntries(abs, entries, cb) + } +} + +Glob.prototype._readdirEntries = function (abs, entries, cb) { + if (this.aborted) + return + + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + return cb(null, entries) +} + +Glob.prototype._readdirError = function (f, er, cb) { + if (this.aborted) + return + + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + this.emit('error', error) + this.abort() + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) { + this.emit('error', er) + // If the error is handled, then we abort + // if not, we threw out of here + this.abort() + } + if (!this.silent) + console.error('glob error', er) + break + } + + return cb() +} + +Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { + var self = this + this._readdir(abs, inGlobStar, function (er, entries) { + self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb) + }) +} + + +Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { + //console.error('pgs2', prefix, remain[0], entries) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return cb() + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false, cb) + + var isSym = this.symlinks[abs] + var len = entries.length + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return cb() + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true, cb) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true, cb) + } + + cb() +} + +Glob.prototype._processSimple = function (prefix, index, cb) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var self = this + this._stat(prefix, function (er, exists) { + self._processSimple2(prefix, index, er, exists, cb) + }) +} +Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { + + //console.error('ps2', prefix, exists) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return cb() + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) + cb() +} + +// Returns either 'DIR', 'FILE', or false +Glob.prototype._stat = function (f, cb) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return cb() + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return cb(null, c) + + if (needDir && c === 'FILE') + return cb() + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (stat !== undefined) { + if (stat === false) + return cb(null, stat) + else { + var type = stat.isDirectory() ? 'DIR' : 'FILE' + if (needDir && type === 'FILE') + return cb() + else + return cb(null, type, stat) + } + } + + var self = this + var statcb = inflight('stat\0' + abs, lstatcb_) + if (statcb) + fs.lstat(abs, statcb) + + function lstatcb_ (er, lstat) { + if (lstat && lstat.isSymbolicLink()) { + // If it's a symlink, then treat it as the target, unless + // the target does not exist, then treat it as a file. + return fs.stat(abs, function (er, stat) { + if (er) + self._stat2(f, abs, null, lstat, cb) + else + self._stat2(f, abs, er, stat, cb) + }) + } else { + self._stat2(f, abs, er, lstat, cb) + } + } +} + +Glob.prototype._stat2 = function (f, abs, er, stat, cb) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return cb() + } + + var needDir = f.slice(-1) === '/' + this.statCache[abs] = stat + + if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) + return cb(null, false, stat) + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return cb() + + return cb(null, c, stat) +} + +}).call(this,require('_process')) +},{"./common.js":168,"./sync.js":170,"_process":432,"assert":290,"events":298,"fs":296,"fs.realpath":119,"inflight":359,"inherits":360,"minimatch":383,"once":397,"path":402,"path-is-absolute":403,"util":523}],170:[function(require,module,exports){ +(function (process){ +module.exports = globSync +globSync.GlobSync = GlobSync + +var fs = require('fs') +var rp = require('fs.realpath') +var minimatch = require('minimatch') +var Minimatch = minimatch.Minimatch +var Glob = require('./glob.js').Glob +var util = require('util') +var path = require('path') +var assert = require('assert') +var isAbsolute = require('path-is-absolute') +var common = require('./common.js') +var alphasort = common.alphasort +var alphasorti = common.alphasorti +var setopts = common.setopts +var ownProp = common.ownProp +var childrenIgnored = common.childrenIgnored +var isIgnored = common.isIgnored + +function globSync (pattern, options) { + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + return new GlobSync(pattern, options).found +} + +function GlobSync (pattern, options) { + if (!pattern) + throw new Error('must provide pattern') + + if (typeof options === 'function' || arguments.length === 3) + throw new TypeError('callback provided to sync glob\n'+ + 'See: https://github.com/isaacs/node-glob/issues/167') + + if (!(this instanceof GlobSync)) + return new GlobSync(pattern, options) + + setopts(this, pattern, options) + + if (this.noprocess) + return this + + var n = this.minimatch.set.length + this.matches = new Array(n) + for (var i = 0; i < n; i ++) { + this._process(this.minimatch.set[i], i, false) + } + this._finish() +} + +GlobSync.prototype._finish = function () { + assert(this instanceof GlobSync) + if (this.realpath) { + var self = this + this.matches.forEach(function (matchset, index) { + var set = self.matches[index] = Object.create(null) + for (var p in matchset) { + try { + p = self._makeAbs(p) + var real = rp.realpathSync(p, self.realpathCache) + set[real] = true + } catch (er) { + if (er.syscall === 'stat') + set[self._makeAbs(p)] = true + else + throw er + } + } + }) + } + common.finish(this) +} + + +GlobSync.prototype._process = function (pattern, index, inGlobStar) { + assert(this instanceof GlobSync) + + // Get the first [n] parts of pattern that are all strings. + var n = 0 + while (typeof pattern[n] === 'string') { + n ++ + } + // now n is the index of the first one that is *not* a string. + + // See if there's anything else + var prefix + switch (n) { + // if not, then this is rather simple + case pattern.length: + this._processSimple(pattern.join('/'), index) + return + + case 0: + // pattern *starts* with some non-trivial item. + // going to readdir(cwd), but not include the prefix in matches. + prefix = null + break + + default: + // pattern has some string bits in the front. + // whatever it starts with, whether that's 'absolute' like /foo/bar, + // or 'relative' like '../baz' + prefix = pattern.slice(0, n).join('/') + break + } + + var remain = pattern.slice(n) + + // get the list of entries. + var read + if (prefix === null) + read = '.' + else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { + if (!prefix || !isAbsolute(prefix)) + prefix = '/' + prefix + read = prefix + } else + read = prefix + + var abs = this._makeAbs(read) + + //if ignored, skip processing + if (childrenIgnored(this, read)) + return + + var isGlobStar = remain[0] === minimatch.GLOBSTAR + if (isGlobStar) + this._processGlobStar(prefix, read, abs, remain, index, inGlobStar) + else + this._processReaddir(prefix, read, abs, remain, index, inGlobStar) +} + + +GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { + var entries = this._readdir(abs, inGlobStar) + + // if the abs isn't a dir, then nothing can match! + if (!entries) + return + + // It will only match dot entries if it starts with a dot, or if + // dot is set. Stuff like @(.foo|.bar) isn't allowed. + var pn = remain[0] + var negate = !!this.minimatch.negate + var rawGlob = pn._glob + var dotOk = this.dot || rawGlob.charAt(0) === '.' + + var matchedEntries = [] + for (var i = 0; i < entries.length; i++) { + var e = entries[i] + if (e.charAt(0) !== '.' || dotOk) { + var m + if (negate && !prefix) { + m = !e.match(pn) + } else { + m = e.match(pn) + } + if (m) + matchedEntries.push(e) + } + } + + var len = matchedEntries.length + // If there are no matched entries, then nothing matches. + if (len === 0) + return + + // if this is the last remaining pattern bit, then no need for + // an additional stat *unless* the user has specified mark or + // stat explicitly. We know they exist, since readdir returned + // them. + + if (remain.length === 1 && !this.mark && !this.stat) { + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + if (prefix) { + if (prefix.slice(-1) !== '/') + e = prefix + '/' + e + else + e = prefix + e + } + + if (e.charAt(0) === '/' && !this.nomount) { + e = path.join(this.root, e) + } + this._emitMatch(index, e) + } + // This was the last one, and no stats were needed + return + } + + // now test all matched entries as stand-ins for that part + // of the pattern. + remain.shift() + for (var i = 0; i < len; i ++) { + var e = matchedEntries[i] + var newPattern + if (prefix) + newPattern = [prefix, e] + else + newPattern = [e] + this._process(newPattern.concat(remain), index, inGlobStar) + } +} + + +GlobSync.prototype._emitMatch = function (index, e) { + if (isIgnored(this, e)) + return + + var abs = this._makeAbs(e) + + if (this.mark) + e = this._mark(e) + + if (this.absolute) { + e = abs + } + + if (this.matches[index][e]) + return + + if (this.nodir) { + var c = this.cache[abs] + if (c === 'DIR' || Array.isArray(c)) + return + } + + this.matches[index][e] = true + + if (this.stat) + this._stat(e) +} + + +GlobSync.prototype._readdirInGlobStar = function (abs) { + // follow all symlinked directories forever + // just proceed as if this is a non-globstar situation + if (this.follow) + return this._readdir(abs, false) + + var entries + var lstat + var stat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er.code === 'ENOENT') { + // lstat failed, doesn't exist + return null + } + } + + var isSym = lstat && lstat.isSymbolicLink() + this.symlinks[abs] = isSym + + // If it's not a symlink or a dir, then it's definitely a regular file. + // don't bother doing a readdir in that case. + if (!isSym && lstat && !lstat.isDirectory()) + this.cache[abs] = 'FILE' + else + entries = this._readdir(abs, false) + + return entries +} + +GlobSync.prototype._readdir = function (abs, inGlobStar) { + var entries + + if (inGlobStar && !ownProp(this.symlinks, abs)) + return this._readdirInGlobStar(abs) + + if (ownProp(this.cache, abs)) { + var c = this.cache[abs] + if (!c || c === 'FILE') + return null + + if (Array.isArray(c)) + return c + } + + try { + return this._readdirEntries(abs, fs.readdirSync(abs)) + } catch (er) { + this._readdirError(abs, er) + return null + } +} + +GlobSync.prototype._readdirEntries = function (abs, entries) { + // if we haven't asked to stat everything, then just + // assume that everything in there exists, so we can avoid + // having to stat it a second time. + if (!this.mark && !this.stat) { + for (var i = 0; i < entries.length; i ++) { + var e = entries[i] + if (abs === '/') + e = abs + e + else + e = abs + '/' + e + this.cache[e] = true + } + } + + this.cache[abs] = entries + + // mark and cache dir-ness + return entries +} + +GlobSync.prototype._readdirError = function (f, er) { + // handle errors, and cache the information + switch (er.code) { + case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 + case 'ENOTDIR': // totally normal. means it *does* exist. + var abs = this._makeAbs(f) + this.cache[abs] = 'FILE' + if (abs === this.cwdAbs) { + var error = new Error(er.code + ' invalid cwd ' + this.cwd) + error.path = this.cwd + error.code = er.code + throw error + } + break + + case 'ENOENT': // not terribly unusual + case 'ELOOP': + case 'ENAMETOOLONG': + case 'UNKNOWN': + this.cache[this._makeAbs(f)] = false + break + + default: // some unusual error. Treat as failure. + this.cache[this._makeAbs(f)] = false + if (this.strict) + throw er + if (!this.silent) + console.error('glob error', er) + break + } +} + +GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { + + var entries = this._readdir(abs, inGlobStar) + + // no entries means not a dir, so it can never have matches + // foo.txt/** doesn't match foo.txt + if (!entries) + return + + // test without the globstar, and with every child both below + // and replacing the globstar. + var remainWithoutGlobStar = remain.slice(1) + var gspref = prefix ? [ prefix ] : [] + var noGlobStar = gspref.concat(remainWithoutGlobStar) + + // the noGlobStar pattern exits the inGlobStar state + this._process(noGlobStar, index, false) + + var len = entries.length + var isSym = this.symlinks[abs] + + // If it's a symlink, and we're in a globstar, then stop + if (isSym && inGlobStar) + return + + for (var i = 0; i < len; i++) { + var e = entries[i] + if (e.charAt(0) === '.' && !this.dot) + continue + + // these two cases enter the inGlobStar state + var instead = gspref.concat(entries[i], remainWithoutGlobStar) + this._process(instead, index, true) + + var below = gspref.concat(entries[i], remain) + this._process(below, index, true) + } +} + +GlobSync.prototype._processSimple = function (prefix, index) { + // XXX review this. Shouldn't it be doing the mounting etc + // before doing stat? kinda weird? + var exists = this._stat(prefix) + + if (!this.matches[index]) + this.matches[index] = Object.create(null) + + // If it doesn't exist, then just mark the lack of results + if (!exists) + return + + if (prefix && isAbsolute(prefix) && !this.nomount) { + var trail = /[\/\\]$/.test(prefix) + if (prefix.charAt(0) === '/') { + prefix = path.join(this.root, prefix) + } else { + prefix = path.resolve(this.root, prefix) + if (trail) + prefix += '/' + } + } + + if (process.platform === 'win32') + prefix = prefix.replace(/\\/g, '/') + + // Mark this as a match + this._emitMatch(index, prefix) +} + +// Returns either 'DIR', 'FILE', or false +GlobSync.prototype._stat = function (f) { + var abs = this._makeAbs(f) + var needDir = f.slice(-1) === '/' + + if (f.length > this.maxLength) + return false + + if (!this.stat && ownProp(this.cache, abs)) { + var c = this.cache[abs] + + if (Array.isArray(c)) + c = 'DIR' + + // It exists, but maybe not how we need it + if (!needDir || c === 'DIR') + return c + + if (needDir && c === 'FILE') + return false + + // otherwise we have to stat, because maybe c=true + // if we know it exists, but not what it is. + } + + var exists + var stat = this.statCache[abs] + if (!stat) { + var lstat + try { + lstat = fs.lstatSync(abs) + } catch (er) { + if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { + this.statCache[abs] = false + return false + } + } + + if (lstat && lstat.isSymbolicLink()) { + try { + stat = fs.statSync(abs) + } catch (er) { + stat = lstat + } + } else { + stat = lstat + } + } + + this.statCache[abs] = stat + + var c = true + if (stat) + c = stat.isDirectory() ? 'DIR' : 'FILE' + + this.cache[abs] = this.cache[abs] || c + + if (needDir && c === 'FILE') + return false + + return c +} + +GlobSync.prototype._mark = function (p) { + return common.mark(this, p) +} + +GlobSync.prototype._makeAbs = function (f) { + return common.makeAbs(this, f) +} + +}).call(this,require('_process')) +},{"./common.js":168,"./glob.js":169,"_process":432,"assert":290,"fs":296,"fs.realpath":119,"minimatch":383,"path":402,"path-is-absolute":403,"util":523}],171:[function(require,module,exports){ +(function (process){ +// A simple implementation of make-array +function makeArray (subject) { + return Array.isArray(subject) + ? subject + : [subject] +} + +const REGEX_TEST_BLANK_LINE = /^\s+$/ +const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/ +const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/ +const REGEX_SPLITALL_CRLF = /\r?\n/g +// /foo, +// ./foo, +// ../foo, +// . +// .. +const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/ + +const SLASH = '/' +const KEY_IGNORE = typeof Symbol !== 'undefined' + ? Symbol.for('node-ignore') + /* istanbul ignore next */ + : 'node-ignore' + +const define = (object, key, value) => + Object.defineProperty(object, key, {value}) + +const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g + +// Sanitize the range of a regular expression +// The cases are complicated, see test cases for details +const sanitizeRange = range => range.replace( + REGEX_REGEXP_RANGE, + (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) + ? match + // Invalid range (out of order) which is ok for gitignore rules but + // fatal for JavaScript regular expression, so eliminate it. + : '' +) + +// > If the pattern ends with a slash, +// > it is removed for the purpose of the following description, +// > but it would only find a match with a directory. +// > In other words, foo/ will match a directory foo and paths underneath it, +// > but will not match a regular file or a symbolic link foo +// > (this is consistent with the way how pathspec works in general in Git). +// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' +// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call +// you could use option `mark: true` with `glob` + +// '`foo/`' should not continue with the '`..`' +const REPLACERS = [ + + // > Trailing spaces are ignored unless they are quoted with backslash ("\") + [ + // (a\ ) -> (a ) + // (a ) -> (a) + // (a \ ) -> (a ) + /\\?\s+$/, + match => match.indexOf('\\') === 0 + ? ' ' + : '' + ], + + // replace (\ ) with ' ' + [ + /\\\s/g, + () => ' ' + ], + + // Escape metacharacters + // which is written down by users but means special for regular expressions. + + // > There are 12 characters with special meanings: + // > - the backslash \, + // > - the caret ^, + // > - the dollar sign $, + // > - the period or dot ., + // > - the vertical bar or pipe symbol |, + // > - the question mark ?, + // > - the asterisk or star *, + // > - the plus sign +, + // > - the opening parenthesis (, + // > - the closing parenthesis ), + // > - and the opening square bracket [, + // > - the opening curly brace {, + // > These special characters are often called "metacharacters". + [ + /[\\^$.|*+(){]/g, + match => `\\${match}` + ], + + [ + // > [abc] matches any character inside the brackets + // > (in this case a, b, or c); + /\[([^\]/]*)($|\])/g, + (match, p1, p2) => p2 === ']' + ? `[${sanitizeRange(p1)}]` + : `\\${match}` + ], + + [ + // > a question mark (?) matches a single character + /(?!\\)\?/g, + () => '[^/]' + ], + + // leading slash + [ + + // > A leading slash matches the beginning of the pathname. + // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". + // A leading slash matches the beginning of the pathname + /^\//, + () => '^' + ], + + // replace special metacharacter slash after the leading slash + [ + /\//g, + () => '\\/' + ], + + [ + // > A leading "**" followed by a slash means match in all directories. + // > For example, "**/foo" matches file or directory "foo" anywhere, + // > the same as pattern "foo". + // > "**/foo/bar" matches file or directory "bar" anywhere that is directly + // > under directory "foo". + // Notice that the '*'s have been replaced as '\\*' + /^\^*\\\*\\\*\\\//, + + // '**/foo' <-> 'foo' + () => '^(?:.*\\/)?' + ], + + // ending + [ + // 'js' will not match 'js.' + // 'ab' will not match 'abc' + /(?:[^*])$/, + + // WTF! + // https://git-scm.com/docs/gitignore + // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) + // which re-fixes #24, #38 + + // > If there is a separator at the end of the pattern then the pattern + // > will only match directories, otherwise the pattern can match both + // > files and directories. + + // 'js*' will not match 'a.js' + // 'js/' will not match 'a.js' + // 'js' will match 'a.js' and 'a.js/' + match => /\/$/.test(match) + // foo/ will not match 'foo' + ? `${match}$` + // foo matches 'foo' and 'foo/' + : `${match}(?=$|\\/$)` + ], + + // starting + [ + // there will be no leading '/' + // (which has been replaced by section "leading slash") + // If starts with '**', adding a '^' to the regular expression also works + /^(?=[^^])/, + function startingReplacer () { + // If has a slash `/` at the beginning or middle + return !/\/(?!$)/.test(this) + // > Prior to 2.22.1 + // > If the pattern does not contain a slash /, + // > Git treats it as a shell glob pattern + // Actually, if there is only a trailing slash, + // git also treats it as a shell glob pattern + + // After 2.22.1 (compatible but clearer) + // > If there is a separator at the beginning or middle (or both) + // > of the pattern, then the pattern is relative to the directory + // > level of the particular .gitignore file itself. + // > Otherwise the pattern may also match at any level below + // > the .gitignore level. + ? '(?:^|\\/)' + + // > Otherwise, Git treats the pattern as a shell glob suitable for + // > consumption by fnmatch(3) + : '^' + } + ], + + // two globstars + [ + // Use lookahead assertions so that we could match more than one `'/**'` + /\\\/\\\*\\\*(?=\\\/|$)/g, + + // Zero, one or several directories + // should not use '*', or it will be replaced by the next replacer + + // Check if it is not the last `'/**'` + (_, index, str) => index + 6 < str.length + + // case: /**/ + // > A slash followed by two consecutive asterisks then a slash matches + // > zero or more directories. + // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. + // '/**/' + ? '(?:\\/[^\\/]+)*' + + // case: /** + // > A trailing `"/**"` matches everything inside. + + // #21: everything inside but it should not include the current folder + : '\\/.+' + ], + + // intermediate wildcards + [ + // Never replace escaped '*' + // ignore rule '\*' will match the path '*' + + // 'abc.*/' -> go + // 'abc.*' -> skip this rule + /(^|[^\\]+)\\\*(?=.+)/g, + + // '*.js' matches '.js' + // '*.js' doesn't match 'abc' + (_, p1) => `${p1}[^\\/]*` + ], + + // trailing wildcard + [ + /(\^|\\\/)?\\\*$/, + (_, p1) => { + const prefix = p1 + // '\^': + // '/*' does not match '' + // '/*' does not match everything + + // '\\\/': + // 'abc/*' does not match 'abc/' + ? `${p1}[^/]+` + + // 'a*' matches 'a' + // 'a*' matches 'aa' + : '[^/]*' + + return `${prefix}(?=$|\\/$)` + } + ], + + [ + // unescape + /\\\\\\/g, + () => '\\' + ] +] + +// A simple cache, because an ignore rule only has only one certain meaning +const regexCache = Object.create(null) + +// @param {pattern} +const makeRegex = (pattern, negative, ignorecase) => { + const r = regexCache[pattern] + if (r) { + return r + } + + // const replacers = negative + // ? NEGATIVE_REPLACERS + // : POSITIVE_REPLACERS + + const source = REPLACERS.reduce( + (prev, current) => prev.replace(current[0], current[1].bind(pattern)), + pattern + ) + + return regexCache[pattern] = ignorecase + ? new RegExp(source, 'i') + : new RegExp(source) +} + +const isString = subject => typeof subject === 'string' + +// > A blank line matches no files, so it can serve as a separator for readability. +const checkPattern = pattern => pattern + && isString(pattern) + && !REGEX_TEST_BLANK_LINE.test(pattern) + + // > A line starting with # serves as a comment. + && pattern.indexOf('#') !== 0 + +const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF) + +class IgnoreRule { + constructor ( + origin, + pattern, + negative, + regex + ) { + this.origin = origin + this.pattern = pattern + this.negative = negative + this.regex = regex + } +} + +const createRule = (pattern, ignorecase) => { + const origin = pattern + let negative = false + + // > An optional prefix "!" which negates the pattern; + if (pattern.indexOf('!') === 0) { + negative = true + pattern = pattern.substr(1) + } + + pattern = pattern + // > Put a backslash ("\") in front of the first "!" for patterns that + // > begin with a literal "!", for example, `"\!important!.txt"`. + .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') + // > Put a backslash ("\") in front of the first hash for patterns that + // > begin with a hash. + .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#') + + const regex = makeRegex(pattern, negative, ignorecase) + + return new IgnoreRule( + origin, + pattern, + negative, + regex + ) +} + +const throwError = (message, Ctor) => { + throw new Ctor(message) +} + +const checkPath = (path, originalPath, doThrow) => { + if (!isString(path)) { + return doThrow( + `path must be a string, but got \`${originalPath}\``, + TypeError + ) + } + + // We don't know if we should ignore '', so throw + if (!path) { + return doThrow(`path must not be empty`, TypeError) + } + + // Check if it is a relative path + if (checkPath.isNotRelative(path)) { + const r = '`path.relative()`d' + return doThrow( + `path should be a ${r} string, but got "${originalPath}"`, + RangeError + ) + } + + return true +} + +const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path) + +checkPath.isNotRelative = isNotRelative +checkPath.convert = p => p + +class Ignore { + constructor ({ + ignorecase = true + } = {}) { + this._rules = [] + this._ignorecase = ignorecase + define(this, KEY_IGNORE, true) + this._initCache() + } + + _initCache () { + this._ignoreCache = Object.create(null) + this._testCache = Object.create(null) + } + + _addPattern (pattern) { + // #32 + if (pattern && pattern[KEY_IGNORE]) { + this._rules = this._rules.concat(pattern._rules) + this._added = true + return + } + + if (checkPattern(pattern)) { + const rule = createRule(pattern, this._ignorecase) + this._added = true + this._rules.push(rule) + } + } + + // @param {Array | string | Ignore} pattern + add (pattern) { + this._added = false + + makeArray( + isString(pattern) + ? splitPattern(pattern) + : pattern + ).forEach(this._addPattern, this) + + // Some rules have just added to the ignore, + // making the behavior changed. + if (this._added) { + this._initCache() + } + + return this + } + + // legacy + addPattern (pattern) { + return this.add(pattern) + } + + // | ignored : unignored + // negative | 0:0 | 0:1 | 1:0 | 1:1 + // -------- | ------- | ------- | ------- | -------- + // 0 | TEST | TEST | SKIP | X + // 1 | TESTIF | SKIP | TEST | X + + // - SKIP: always skip + // - TEST: always test + // - TESTIF: only test if checkUnignored + // - X: that never happen + + // @param {boolean} whether should check if the path is unignored, + // setting `checkUnignored` to `false` could reduce additional + // path matching. + + // @returns {TestResult} true if a file is ignored + _testOne (path, checkUnignored) { + let ignored = false + let unignored = false + + this._rules.forEach(rule => { + const {negative} = rule + if ( + unignored === negative && ignored !== unignored + || negative && !ignored && !unignored && !checkUnignored + ) { + return + } + + const matched = rule.regex.test(path) + + if (matched) { + ignored = !negative + unignored = negative + } + }) + + return { + ignored, + unignored + } + } + + // @returns {TestResult} + _test (originalPath, cache, checkUnignored, slices) { + const path = originalPath + // Supports nullable path + && checkPath.convert(originalPath) + + checkPath(path, originalPath, throwError) + + return this._t(path, cache, checkUnignored, slices) + } + + _t (path, cache, checkUnignored, slices) { + if (path in cache) { + return cache[path] + } + + if (!slices) { + // path/to/a.js + // ['path', 'to', 'a.js'] + slices = path.split(SLASH) + } + + slices.pop() + + // If the path has no parent directory, just test it + if (!slices.length) { + return cache[path] = this._testOne(path, checkUnignored) + } + + const parent = this._t( + slices.join(SLASH) + SLASH, + cache, + checkUnignored, + slices + ) + + // If the path contains a parent directory, check the parent first + return cache[path] = parent.ignored + // > It is not possible to re-include a file if a parent directory of + // > that file is excluded. + ? parent + : this._testOne(path, checkUnignored) + } + + ignores (path) { + return this._test(path, this._ignoreCache, false).ignored + } + + createFilter () { + return path => !this.ignores(path) + } + + filter (paths) { + return makeArray(paths).filter(this.createFilter()) + } + + // @returns {TestResult} + test (path) { + return this._test(path, this._testCache, true) + } +} + +const factory = options => new Ignore(options) + +const returnFalse = () => false + +const isPathValid = path => + checkPath(path && checkPath.convert(path), path, returnFalse) + +factory.isPathValid = isPathValid + +// Fixes typescript +factory.default = factory + +module.exports = factory + +// Windows +// -------------------------------------------------------------- +/* istanbul ignore if */ +if ( + // Detect `process` so that it can run in browsers. + typeof process !== 'undefined' + && ( + process.env && process.env.IGNORE_TEST_WIN32 + || process.platform === 'win32' + ) +) { + /* eslint no-control-regex: "off" */ + const makePosix = str => /^\\\\\?\\/.test(str) + || /["<>|\u0000-\u001F]+/u.test(str) + ? str + : str.replace(/\\/g, '/') + + checkPath.convert = makePosix + + // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' + // 'd:\\foo' + const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i + checkPath.isNotRelative = path => + REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) + || isNotRelative(path) +} + +}).call(this,require('_process')) +},{"_process":432}],172:[function(require,module,exports){ +'use strict'; +const {Transform} = require('stream'); + +class ObjectTransform extends Transform { + constructor() { + super({ + objectMode: true + }); + } +} + +class FilterStream extends ObjectTransform { + constructor(filter) { + super(); + this._filter = filter; + } + + _transform(data, encoding, callback) { + if (this._filter(data)) { + this.push(data); + } + + callback(); + } +} + +class UniqueStream extends ObjectTransform { + constructor() { + super(); + this._pushed = new Set(); + } + + _transform(data, encoding, callback) { + if (!this._pushed.has(data)) { + this.push(data); + this._pushed.add(data); + } + + callback(); + } +} + +module.exports = { + FilterStream, + UniqueStream +}; + +},{"stream":503}],173:[function(require,module,exports){ +module.exports = tokenize + +var literals100 = require('./lib/literals') + , operators = require('./lib/operators') + , builtins100 = require('./lib/builtins') + , literals300es = require('./lib/literals-300es') + , builtins300es = require('./lib/builtins-300es') + +var NORMAL = 999 // <-- never emitted + , TOKEN = 9999 // <-- never emitted + , BLOCK_COMMENT = 0 + , LINE_COMMENT = 1 + , PREPROCESSOR = 2 + , OPERATOR = 3 + , INTEGER = 4 + , FLOAT = 5 + , IDENT = 6 + , BUILTIN = 7 + , KEYWORD = 8 + , WHITESPACE = 9 + , EOF = 10 + , HEX = 11 + +var map = [ + 'block-comment' + , 'line-comment' + , 'preprocessor' + , 'operator' + , 'integer' + , 'float' + , 'ident' + , 'builtin' + , 'keyword' + , 'whitespace' + , 'eof' + , 'integer' +] + +function tokenize(opt) { + var i = 0 + , total = 0 + , mode = NORMAL + , c + , last + , content = [] + , tokens = [] + , token_idx = 0 + , token_offs = 0 + , line = 1 + , col = 0 + , start = 0 + , isnum = false + , isoperator = false + , input = '' + , len + + opt = opt || {} + var allBuiltins = builtins100 + var allLiterals = literals100 + if (opt.version === '300 es') { + allBuiltins = builtins300es + allLiterals = literals300es + } + + // cache by name + var builtinsDict = {}, literalsDict = {} + for (var i = 0; i < allBuiltins.length; i++) { + builtinsDict[allBuiltins[i]] = true + } + for (var i = 0; i < allLiterals.length; i++) { + literalsDict[allLiterals[i]] = true + } + + return function(data) { + tokens = [] + if (data !== null) return write(data) + return end() + } + + function token(data) { + if (data.length) { + tokens.push({ + type: map[mode] + , data: data + , position: start + , line: line + , column: col + }) + } + } + + function write(chunk) { + i = 0 + + if (chunk.toString) chunk = chunk.toString() + + input += chunk.replace(/\r\n/g, '\n') + len = input.length + + + var last + + while(c = input[i], i < len) { + last = i + + switch(mode) { + case BLOCK_COMMENT: i = block_comment(); break + case LINE_COMMENT: i = line_comment(); break + case PREPROCESSOR: i = preprocessor(); break + case OPERATOR: i = operator(); break + case INTEGER: i = integer(); break + case HEX: i = hex(); break + case FLOAT: i = decimal(); break + case TOKEN: i = readtoken(); break + case WHITESPACE: i = whitespace(); break + case NORMAL: i = normal(); break + } + + if(last !== i) { + switch(input[last]) { + case '\n': col = 0; ++line; break + default: ++col; break + } + } + } + + total += i + input = input.slice(i) + return tokens + } + + function end(chunk) { + if(content.length) { + token(content.join('')) + } + + mode = EOF + token('(eof)') + return tokens + } + + function normal() { + content = content.length ? [] : content + + if(last === '/' && c === '*') { + start = total + i - 1 + mode = BLOCK_COMMENT + last = c + return i + 1 + } + + if(last === '/' && c === '/') { + start = total + i - 1 + mode = LINE_COMMENT + last = c + return i + 1 + } + + if(c === '#') { + mode = PREPROCESSOR + start = total + i + return i + } + + if(/\s/.test(c)) { + mode = WHITESPACE + start = total + i + return i + } + + isnum = /\d/.test(c) + isoperator = /[^\w_]/.test(c) + + start = total + i + mode = isnum ? INTEGER : isoperator ? OPERATOR : TOKEN + return i + } + + function whitespace() { + if(/[^\s]/g.test(c)) { + token(content.join('')) + mode = NORMAL + return i + } + content.push(c) + last = c + return i + 1 + } + + function preprocessor() { + if((c === '\r' || c === '\n') && last !== '\\') { + token(content.join('')) + mode = NORMAL + return i + } + content.push(c) + last = c + return i + 1 + } + + function line_comment() { + return preprocessor() + } + + function block_comment() { + if(c === '/' && last === '*') { + content.push(c) + token(content.join('')) + mode = NORMAL + return i + 1 + } + + content.push(c) + last = c + return i + 1 + } + + function operator() { + if(last === '.' && /\d/.test(c)) { + mode = FLOAT + return i + } + + if(last === '/' && c === '*') { + mode = BLOCK_COMMENT + return i + } + + if(last === '/' && c === '/') { + mode = LINE_COMMENT + return i + } + + if(c === '.' && content.length) { + while(determine_operator(content)); + + mode = FLOAT + return i + } + + if(c === ';' || c === ')' || c === '(') { + if(content.length) while(determine_operator(content)); + token(c) + mode = NORMAL + return i + 1 + } + + var is_composite_operator = content.length === 2 && c !== '=' + if(/[\w_\d\s]/.test(c) || is_composite_operator) { + while(determine_operator(content)); + mode = NORMAL + return i + } + + content.push(c) + last = c + return i + 1 + } + + function determine_operator(buf) { + var j = 0 + , idx + , res + + do { + idx = operators.indexOf(buf.slice(0, buf.length + j).join('')) + res = operators[idx] + + if(idx === -1) { + if(j-- + buf.length > 0) continue + res = buf.slice(0, 1).join('') + } + + token(res) + + start += res.length + content = content.slice(res.length) + return content.length + } while(1) + } + + function hex() { + if(/[^a-fA-F0-9]/.test(c)) { + token(content.join('')) + mode = NORMAL + return i + } + + content.push(c) + last = c + return i + 1 + } + + function integer() { + if(c === '.') { + content.push(c) + mode = FLOAT + last = c + return i + 1 + } + + if(/[eE]/.test(c)) { + content.push(c) + mode = FLOAT + last = c + return i + 1 + } + + if(c === 'x' && content.length === 1 && content[0] === '0') { + mode = HEX + content.push(c) + last = c + return i + 1 + } + + if(/[^\d]/.test(c)) { + token(content.join('')) + mode = NORMAL + return i + } + + content.push(c) + last = c + return i + 1 + } + + function decimal() { + if(c === 'f') { + content.push(c) + last = c + i += 1 + } + + if(/[eE]/.test(c)) { + content.push(c) + last = c + return i + 1 + } + + if ((c === '-' || c === '+') && /[eE]/.test(last)) { + content.push(c) + last = c + return i + 1 + } + + if(/[^\d]/.test(c)) { + token(content.join('')) + mode = NORMAL + return i + } + + content.push(c) + last = c + return i + 1 + } + + function readtoken() { + if(/[^\d\w_]/.test(c)) { + var contentstr = content.join('') + if(literalsDict[contentstr]) { + mode = KEYWORD + } else if(builtinsDict[contentstr]) { + mode = BUILTIN + } else { + mode = IDENT + } + token(content.join('')) + mode = NORMAL + return i + } + content.push(c) + last = c + return i + 1 + } +} + +},{"./lib/builtins":175,"./lib/builtins-300es":174,"./lib/literals":177,"./lib/literals-300es":176,"./lib/operators":178}],174:[function(require,module,exports){ +// 300es builtins/reserved words that were previously valid in v100 +var v100 = require('./builtins') + +// The texture2D|Cube functions have been removed +// And the gl_ features are updated +v100 = v100.slice().filter(function (b) { + return !/^(gl\_|texture)/.test(b) +}) + +module.exports = v100.concat([ + // the updated gl_ constants + 'gl_VertexID' + , 'gl_InstanceID' + , 'gl_Position' + , 'gl_PointSize' + , 'gl_FragCoord' + , 'gl_FrontFacing' + , 'gl_FragDepth' + , 'gl_PointCoord' + , 'gl_MaxVertexAttribs' + , 'gl_MaxVertexUniformVectors' + , 'gl_MaxVertexOutputVectors' + , 'gl_MaxFragmentInputVectors' + , 'gl_MaxVertexTextureImageUnits' + , 'gl_MaxCombinedTextureImageUnits' + , 'gl_MaxTextureImageUnits' + , 'gl_MaxFragmentUniformVectors' + , 'gl_MaxDrawBuffers' + , 'gl_MinProgramTexelOffset' + , 'gl_MaxProgramTexelOffset' + , 'gl_DepthRangeParameters' + , 'gl_DepthRange' + + // other builtins + , 'trunc' + , 'round' + , 'roundEven' + , 'isnan' + , 'isinf' + , 'floatBitsToInt' + , 'floatBitsToUint' + , 'intBitsToFloat' + , 'uintBitsToFloat' + , 'packSnorm2x16' + , 'unpackSnorm2x16' + , 'packUnorm2x16' + , 'unpackUnorm2x16' + , 'packHalf2x16' + , 'unpackHalf2x16' + , 'outerProduct' + , 'transpose' + , 'determinant' + , 'inverse' + , 'texture' + , 'textureSize' + , 'textureProj' + , 'textureLod' + , 'textureOffset' + , 'texelFetch' + , 'texelFetchOffset' + , 'textureProjOffset' + , 'textureLodOffset' + , 'textureProjLod' + , 'textureProjLodOffset' + , 'textureGrad' + , 'textureGradOffset' + , 'textureProjGrad' + , 'textureProjGradOffset' +]) + +},{"./builtins":175}],175:[function(require,module,exports){ +module.exports = [ + // Keep this list sorted + 'abs' + , 'acos' + , 'all' + , 'any' + , 'asin' + , 'atan' + , 'ceil' + , 'clamp' + , 'cos' + , 'cross' + , 'dFdx' + , 'dFdy' + , 'degrees' + , 'distance' + , 'dot' + , 'equal' + , 'exp' + , 'exp2' + , 'faceforward' + , 'floor' + , 'fract' + , 'gl_BackColor' + , 'gl_BackLightModelProduct' + , 'gl_BackLightProduct' + , 'gl_BackMaterial' + , 'gl_BackSecondaryColor' + , 'gl_ClipPlane' + , 'gl_ClipVertex' + , 'gl_Color' + , 'gl_DepthRange' + , 'gl_DepthRangeParameters' + , 'gl_EyePlaneQ' + , 'gl_EyePlaneR' + , 'gl_EyePlaneS' + , 'gl_EyePlaneT' + , 'gl_Fog' + , 'gl_FogCoord' + , 'gl_FogFragCoord' + , 'gl_FogParameters' + , 'gl_FragColor' + , 'gl_FragCoord' + , 'gl_FragData' + , 'gl_FragDepth' + , 'gl_FragDepthEXT' + , 'gl_FrontColor' + , 'gl_FrontFacing' + , 'gl_FrontLightModelProduct' + , 'gl_FrontLightProduct' + , 'gl_FrontMaterial' + , 'gl_FrontSecondaryColor' + , 'gl_LightModel' + , 'gl_LightModelParameters' + , 'gl_LightModelProducts' + , 'gl_LightProducts' + , 'gl_LightSource' + , 'gl_LightSourceParameters' + , 'gl_MaterialParameters' + , 'gl_MaxClipPlanes' + , 'gl_MaxCombinedTextureImageUnits' + , 'gl_MaxDrawBuffers' + , 'gl_MaxFragmentUniformComponents' + , 'gl_MaxLights' + , 'gl_MaxTextureCoords' + , 'gl_MaxTextureImageUnits' + , 'gl_MaxTextureUnits' + , 'gl_MaxVaryingFloats' + , 'gl_MaxVertexAttribs' + , 'gl_MaxVertexTextureImageUnits' + , 'gl_MaxVertexUniformComponents' + , 'gl_ModelViewMatrix' + , 'gl_ModelViewMatrixInverse' + , 'gl_ModelViewMatrixInverseTranspose' + , 'gl_ModelViewMatrixTranspose' + , 'gl_ModelViewProjectionMatrix' + , 'gl_ModelViewProjectionMatrixInverse' + , 'gl_ModelViewProjectionMatrixInverseTranspose' + , 'gl_ModelViewProjectionMatrixTranspose' + , 'gl_MultiTexCoord0' + , 'gl_MultiTexCoord1' + , 'gl_MultiTexCoord2' + , 'gl_MultiTexCoord3' + , 'gl_MultiTexCoord4' + , 'gl_MultiTexCoord5' + , 'gl_MultiTexCoord6' + , 'gl_MultiTexCoord7' + , 'gl_Normal' + , 'gl_NormalMatrix' + , 'gl_NormalScale' + , 'gl_ObjectPlaneQ' + , 'gl_ObjectPlaneR' + , 'gl_ObjectPlaneS' + , 'gl_ObjectPlaneT' + , 'gl_Point' + , 'gl_PointCoord' + , 'gl_PointParameters' + , 'gl_PointSize' + , 'gl_Position' + , 'gl_ProjectionMatrix' + , 'gl_ProjectionMatrixInverse' + , 'gl_ProjectionMatrixInverseTranspose' + , 'gl_ProjectionMatrixTranspose' + , 'gl_SecondaryColor' + , 'gl_TexCoord' + , 'gl_TextureEnvColor' + , 'gl_TextureMatrix' + , 'gl_TextureMatrixInverse' + , 'gl_TextureMatrixInverseTranspose' + , 'gl_TextureMatrixTranspose' + , 'gl_Vertex' + , 'greaterThan' + , 'greaterThanEqual' + , 'inversesqrt' + , 'length' + , 'lessThan' + , 'lessThanEqual' + , 'log' + , 'log2' + , 'matrixCompMult' + , 'max' + , 'min' + , 'mix' + , 'mod' + , 'normalize' + , 'not' + , 'notEqual' + , 'pow' + , 'radians' + , 'reflect' + , 'refract' + , 'sign' + , 'sin' + , 'smoothstep' + , 'sqrt' + , 'step' + , 'tan' + , 'texture2D' + , 'texture2DLod' + , 'texture2DProj' + , 'texture2DProjLod' + , 'textureCube' + , 'textureCubeLod' + , 'texture2DLodEXT' + , 'texture2DProjLodEXT' + , 'textureCubeLodEXT' + , 'texture2DGradEXT' + , 'texture2DProjGradEXT' + , 'textureCubeGradEXT' +] + +},{}],176:[function(require,module,exports){ +var v100 = require('./literals') + +module.exports = v100.slice().concat([ + 'layout' + , 'centroid' + , 'smooth' + , 'case' + , 'mat2x2' + , 'mat2x3' + , 'mat2x4' + , 'mat3x2' + , 'mat3x3' + , 'mat3x4' + , 'mat4x2' + , 'mat4x3' + , 'mat4x4' + , 'uvec2' + , 'uvec3' + , 'uvec4' + , 'samplerCubeShadow' + , 'sampler2DArray' + , 'sampler2DArrayShadow' + , 'isampler2D' + , 'isampler3D' + , 'isamplerCube' + , 'isampler2DArray' + , 'usampler2D' + , 'usampler3D' + , 'usamplerCube' + , 'usampler2DArray' + , 'coherent' + , 'restrict' + , 'readonly' + , 'writeonly' + , 'resource' + , 'atomic_uint' + , 'noperspective' + , 'patch' + , 'sample' + , 'subroutine' + , 'common' + , 'partition' + , 'active' + , 'filter' + , 'image1D' + , 'image2D' + , 'image3D' + , 'imageCube' + , 'iimage1D' + , 'iimage2D' + , 'iimage3D' + , 'iimageCube' + , 'uimage1D' + , 'uimage2D' + , 'uimage3D' + , 'uimageCube' + , 'image1DArray' + , 'image2DArray' + , 'iimage1DArray' + , 'iimage2DArray' + , 'uimage1DArray' + , 'uimage2DArray' + , 'image1DShadow' + , 'image2DShadow' + , 'image1DArrayShadow' + , 'image2DArrayShadow' + , 'imageBuffer' + , 'iimageBuffer' + , 'uimageBuffer' + , 'sampler1DArray' + , 'sampler1DArrayShadow' + , 'isampler1D' + , 'isampler1DArray' + , 'usampler1D' + , 'usampler1DArray' + , 'isampler2DRect' + , 'usampler2DRect' + , 'samplerBuffer' + , 'isamplerBuffer' + , 'usamplerBuffer' + , 'sampler2DMS' + , 'isampler2DMS' + , 'usampler2DMS' + , 'sampler2DMSArray' + , 'isampler2DMSArray' + , 'usampler2DMSArray' +]) + +},{"./literals":177}],177:[function(require,module,exports){ +module.exports = [ + // current + 'precision' + , 'highp' + , 'mediump' + , 'lowp' + , 'attribute' + , 'const' + , 'uniform' + , 'varying' + , 'break' + , 'continue' + , 'do' + , 'for' + , 'while' + , 'if' + , 'else' + , 'in' + , 'out' + , 'inout' + , 'float' + , 'int' + , 'uint' + , 'void' + , 'bool' + , 'true' + , 'false' + , 'discard' + , 'return' + , 'mat2' + , 'mat3' + , 'mat4' + , 'vec2' + , 'vec3' + , 'vec4' + , 'ivec2' + , 'ivec3' + , 'ivec4' + , 'bvec2' + , 'bvec3' + , 'bvec4' + , 'sampler1D' + , 'sampler2D' + , 'sampler3D' + , 'samplerCube' + , 'sampler1DShadow' + , 'sampler2DShadow' + , 'struct' + + // future + , 'asm' + , 'class' + , 'union' + , 'enum' + , 'typedef' + , 'template' + , 'this' + , 'packed' + , 'goto' + , 'switch' + , 'default' + , 'inline' + , 'noinline' + , 'volatile' + , 'public' + , 'static' + , 'extern' + , 'external' + , 'interface' + , 'long' + , 'short' + , 'double' + , 'half' + , 'fixed' + , 'unsigned' + , 'input' + , 'output' + , 'hvec2' + , 'hvec3' + , 'hvec4' + , 'dvec2' + , 'dvec3' + , 'dvec4' + , 'fvec2' + , 'fvec3' + , 'fvec4' + , 'sampler2DRect' + , 'sampler3DRect' + , 'sampler2DRectShadow' + , 'sizeof' + , 'cast' + , 'namespace' + , 'using' +] + +},{}],178:[function(require,module,exports){ +module.exports = [ + '<<=' + , '>>=' + , '++' + , '--' + , '<<' + , '>>' + , '<=' + , '>=' + , '==' + , '!=' + , '&&' + , '||' + , '+=' + , '-=' + , '*=' + , '/=' + , '%=' + , '&=' + , '^^' + , '^=' + , '|=' + , '(' + , ')' + , '[' + , ']' + , '.' + , '!' + , '~' + , '*' + , '/' + , '%' + , '+' + , '-' + , '<' + , '>' + , '&' + , '^' + , '|' + , '?' + , ':' + , '=' + , ',' + , ';' + , '{' + , '}' +] + +},{}],179:[function(require,module,exports){ +var tokenize = require('./index') + +module.exports = tokenizeString + +function tokenizeString(str, opt) { + var generator = tokenize(opt) + var tokens = [] + + tokens = tokens.concat(generator(str)) + tokens = tokens.concat(generator(null)) + + return tokens +} + +},{"./index":173}],180:[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); + } + 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); + } + } +} + +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 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.destroy = () => {}; + kernel.validateSettings = () => {}; + if (kernel.graphical && kernel.output) { + setupGraphical(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; + // cpu is not flipped by default + 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; + }; + + // these are added for api compatibility, but have no affect + const mockMethod = () => kernel; + const methods = [ + 'setWarnVarUsage', + 'setArgumentTypes', + 'setTactic', + 'setOptimizeFloatMemory', + 'setDebug', + 'setLoopMaxIterations', + 'setConstantTypes', + 'setFunctions', + 'setNativeFunctions', + 'setInjectedNative', + 'setPipeline', + 'setPrecision', + 'setOutputToTexture', + 'setImmutable', + 'setStrictIntegers', + 'setDynamicOutput', + 'setHardcodeConstants', + 'setDynamicArguments', + 'setUseLegacyEncoder', + 'setWarnVarUsage', + 'addSubKernel', + ]; + for (let i = 0; i < methods.length; i++) { + kernel[methods[i]] = mockMethod; + } + 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 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) { + // 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; +} + +module.exports = { + gpuMock +}; + +},{}],181:[function(require,module,exports){ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = global || self, factory(global.acorn = {})); +}(this, (function (exports) { 'use strict'; + + // Reserved word lists for various dialects of the language + + 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" + }; + + // And the keywords + + 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, + "5module": ecma5AndLessKeywords + " export import", + 6: ecma5AndLessKeywords + " const class extends export import super" + }; + + var keywordRelationalOperator = /^in(stanceof)?$/; + + // ## Character categories + + // Big ugly regular expressions that match characters in the + // whitespace, identifier, and identifier-start categories. These + // are only applied when a character is found to actually have a + // code point above 128. + // Generated by `bin/generate-identifier-regex.js`. + 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-\u08c7\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\u0d04-\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\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\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-\u1cf3\u1cf5\u1cf6\u1cfa\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-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\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-\uab69\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\u0b55-\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\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\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\u1abf\u1ac0\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\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\ua82c\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; + + // These are a run-length and offset encoded representation of the + // >0xffff code points that are a valid part of identifiers. The + // offset starts at 0x10000, and each pair of numbers represents an + // offset to the next range, and then a size of the range. They were + // generated by bin/generate-identifier-regex.js + + // eslint-disable-next-line comma-spacing + 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,349,41,7,1,79,28,11,0,9,21,107,20,28,22,13,52,76,44,33,24,27,35,30,0,3,0,9,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,21,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,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,190,0,80,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,74,6,0,67,12,65,1,2,0,29,6135,9,1237,43,8,8952,286,50,2,18,3,9,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,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,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,42717,35,4148,12,221,3,5761,15,7472,3104,541,1507,4938]; + + // eslint-disable-next-line comma-spacing + 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,370,1,154,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,2,11,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,71,5,2,1,3,3,2,0,2,1,13,9,120,6,3,6,4,0,29,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,1014,0,2,54,8,3,82,0,12,1,19628,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,262,6,10,9,419,13,1495,6,110,6,6,9,4759,9,787719,239]; + + // This has a complexity linear to the value of the code. The + // assumption is that looking up astral identifier characters is + // rare. + 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 } + } + } + + // Test whether a given character code starts an identifier. + + 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) + } + + // Test whether a given character is part of an identifier. + + 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) + } + + // ## Token types + + // The assignment of fine-grained, information-carrying type objects + // allows the tokenizer to store the information it has about a + // token in a way that is very cheap for the parser to look up. + + // All token type variables start with an underscore, to make them + // easy to recognize. + + // The `beforeExpr` property is used to disambiguate between regular + // expressions and divisions. It is set on all token types that can + // be followed by an expression (thus, a slash after them would be a + // regular expression). + // + // The `startsExpr` property is used to check if the token ends a + // `yield` expression. It is set on all token types that either can + // directly start an expression (like a quotation mark) or can + // continue an expression (like the body of a string). + // + // `isLoop` marks a keyword as starting a loop, which is important + // to know when parsing a label, in order to allow or disallow + // continue jumps to that label. + + 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}, startsExpr = {startsExpr: true}; + + // Map keyword names to token types. + + var keywords$1 = {}; + + // Succinct definitions of keyword token types + 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"), + + // Punctuation token types. + 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), + questionDot: new TokenType("?."), + 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}), + + // Operators. These carry several kinds of properties to help the + // parser use them properly (the presence of these properties is + // what categorizes them as operators). + // + // `binop`, when present, specifies that this operator is a binary + // operator, and will refer to its precedence. + // + // `prefix` and `postfix` mark the operator as a prefix or postfix + // unary operator. + // + // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as + // binary operators with a very low precedence, that should result + // in AssignmentExpression nodes. + + 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}), + coalesce: binop("??", 1), + + // Keyword token types. + _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", startsExpr), + _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}) + }; + + // Matches a whole line break (where CRLF is considered a single + // line break). Used to count lines. + + 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\u2000-\u200a\u202f\u205f\u3000\ufeff]/; + + var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; + + var ref = Object.prototype; + var hasOwnProperty = ref.hasOwnProperty; + var toString = ref.toString; + + // Checks if an object has a property. + + function has(obj, propName) { + return hasOwnProperty.call(obj, propName) + } + + var isArray = Array.isArray || (function (obj) { return ( + toString.call(obj) === "[object Array]" + ); }); + + function wordsRegexp(words) { + return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$") + } + + // These are used when `options.locations` is on, for the + // `startLoc` and `endLoc` properties. + + 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; } + }; + + // The `getLineInfo` function is mostly useful when the + // `locations` option is off (for performance reasons) and you + // want to find the line/column position for a given character + // offset. `input` should be the code string that the offset refers + // into. + + 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) + } + } + } + + // A second optional argument can be given to further configure + // the parser process. These options are recognized: + + var defaultOptions = { + // `ecmaVersion` indicates the ECMAScript version to parse. Must be + // either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10 + // (2019). This influences support for strict mode, the set of + // reserved words, and support for new syntax features. The default + // is 10. + ecmaVersion: 10, + // `sourceType` indicates the mode the code should be parsed in. + // Can be either `"script"` or `"module"`. This influences global + // strict mode and parsing of `import` and `export` declarations. + sourceType: "script", + // `onInsertedSemicolon` can be a callback that will be called + // when a semicolon is automatically inserted. It will be passed + // the position of the comma as an offset, and if `locations` is + // enabled, it is given the location as a `{line, column}` object + // as second argument. + onInsertedSemicolon: null, + // `onTrailingComma` is similar to `onInsertedSemicolon`, but for + // trailing commas. + onTrailingComma: null, + // By default, reserved words are only enforced if ecmaVersion >= 5. + // Set `allowReserved` to a boolean value to explicitly turn this on + // an off. When this option has the value "never", reserved words + // and keywords can also not be used as property names. + allowReserved: null, + // When enabled, a return at the top level is not considered an + // error. + allowReturnOutsideFunction: false, + // When enabled, import/export statements are not constrained to + // appearing at the top of the program. + allowImportExportEverywhere: false, + // When enabled, await identifiers are allowed to appear at the top-level scope, + // but they are still not allowed in non-async functions. + allowAwaitOutsideFunction: false, + // When enabled, hashbang directive in the beginning of file + // is allowed and treated as a line comment. + allowHashBang: false, + // When `locations` is on, `loc` properties holding objects with + // `start` and `end` properties in `{line, column}` form (with + // line being 1-based and column 0-based) will be attached to the + // nodes. + locations: false, + // A function can be passed as `onToken` option, which will + // cause Acorn to call that function with object in the same + // format as tokens returned from `tokenizer().getToken()`. Note + // that you are not allowed to call the parser from the + // callback—that will corrupt its internal state. + onToken: null, + // A function can be passed as `onComment` option, which will + // cause Acorn to call that function with `(block, text, start, + // end)` parameters whenever a comment is skipped. `block` is a + // boolean indicating whether this is a block (`/* */`) comment, + // `text` is the content of the comment, and `start` and `end` are + // character offsets that denote the start and end of the comment. + // When the `locations` option is on, two more parameters are + // passed, the full `{line, column}` locations of the start and + // end of the comments. Note that you are not allowed to call the + // parser from the callback—that will corrupt its internal state. + onComment: null, + // Nodes have their start and end characters offsets recorded in + // `start` and `end` properties (directly on the node, rather than + // the `loc` object, which holds line/column data. To also add a + // [semi-standardized][range] `range` property holding a `[start, + // end]` array with the same numbers, set the `ranges` option to + // `true`. + // + // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 + ranges: false, + // It is possible to parse multiple files into a single AST by + // passing the tree produced by parsing the first file as + // `program` option in subsequent parses. This will add the + // toplevel forms of the parsed file to the `Program` (top) node + // of an existing parse tree. + program: null, + // When `locations` is on, you can pass this to record the source + // file in every node's `loc` object. + sourceFile: null, + // This value, if given, is stored in every node, whether + // `locations` is on or off. + directSourceFile: null, + // When enabled, parenthesized expressions are represented by + // (non-standard) ParenthesizedExpression nodes + preserveParens: false + }; + + // Interpret and default an options object + + 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); + } + } + + // Each scope gets a bitset that may contain these flags + var + SCOPE_TOP = 1, + SCOPE_FUNCTION = 2, + SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION, + SCOPE_ASYNC = 4, + SCOPE_GENERATOR = 8, + SCOPE_ARROW = 16, + SCOPE_SIMPLE_CATCH = 32, + SCOPE_SUPER = 64, + SCOPE_DIRECT_SUPER = 128; + + function functionFlags(async, generator) { + return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0) + } + + // Used in checkLVal and declareName to determine the type of a binding + var + BIND_NONE = 0, // Not a binding + BIND_VAR = 1, // Var-style binding + BIND_LEXICAL = 2, // Let- or const-style binding + BIND_FUNCTION = 3, // Function declaration + BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding + BIND_OUTSIDE = 5; // Special case for function names as bound inside the function + + var Parser = function Parser(options, input, startPos) { + this.options = options = getOptions(options); + this.sourceFile = options.sourceFile; + this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]); + var reserved = ""; + if (options.allowReserved !== true) { + for (var v = options.ecmaVersion;; v--) + { if (reserved = reservedWords[v]) { break } } + if (options.sourceType === "module") { reserved += " await"; } + } + this.reservedWords = wordsRegexp(reserved); + var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict; + this.reservedWordsStrict = wordsRegexp(reservedStrict); + this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind); + this.input = String(input); + + // Used to signal to callers of `readWord1` whether the word + // contained any escape sequences. This is needed because words with + // escape sequences must not be interpreted as keywords. + this.containsEsc = false; + + // Set up token state + + // The current position of the tokenizer in the input. + 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; + } + + // Properties of the current token: + // Its type + this.type = types.eof; + // For tokens that include more information than their type, the value + this.value = null; + // Its start and end offset + this.start = this.end = this.pos; + // And, if locations are used, the {line, column} object + // corresponding to those offsets + this.startLoc = this.endLoc = this.curPosition(); + + // Position information for the previous token + this.lastTokEndLoc = this.lastTokStartLoc = null; + this.lastTokStart = this.lastTokEnd = this.pos; + + // The context stack is used to superficially track syntactic + // context to predict whether a regular expression is allowed in a + // given position. + this.context = this.initialContext(); + this.exprAllowed = true; + + // Figure out if it's a module code. + this.inModule = options.sourceType === "module"; + this.strict = this.inModule || this.strictDirective(this.pos); + + // Used to signify the start of a potential arrow function + this.potentialArrowAt = -1; + + // Positions to delayed-check that yield/await does not exist in default parameters. + this.yieldPos = this.awaitPos = this.awaitIdentPos = 0; + // Labels in scope. + this.labels = []; + // Thus-far undefined exports. + this.undefinedExports = {}; + + // If enabled, skip leading hashbang line. + if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!") + { this.skipLineComment(2); } + + // Scope tracking for duplicate variable names (see scope.js) + this.scopeStack = []; + this.enterScope(SCOPE_TOP); + + // For RegExp validation + this.regexpState = null; + }; + + var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true } }; + + Parser.prototype.parse = function parse () { + var node = this.options.program || this.startNode(); + this.nextToken(); + return this.parseTopLevel(node) + }; + + prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 }; + prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 }; + prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 }; + prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 }; + prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 }; + prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) }; + + // Switch to a getter for 7.0.0. + Parser.prototype.inNonArrowFunction = function inNonArrowFunction () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 }; + + Parser.extend = function extend () { + var plugins = [], len = arguments.length; + while ( len-- ) plugins[ len ] = arguments[ len ]; + + var cls = this; + for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); } + return cls + }; + + Parser.parse = function parse (input, options) { + return new this(options, input).parse() + }; + + Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) { + var parser = new this(options, input, pos); + parser.nextToken(); + return parser.parseExpression() + }; + + Parser.tokenizer = function tokenizer (input, options) { + return new this(options, input) + }; + + Object.defineProperties( Parser.prototype, prototypeAccessors ); + + var pp = Parser.prototype; + + // ## Parser utilities + + var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/; + pp.strictDirective = function(start) { + for (;;) { + // Try to find string literal. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + var match = literal.exec(this.input.slice(start)); + if (!match) { return false } + if ((match[1] || match[2]) === "use strict") { + skipWhiteSpace.lastIndex = start + match[0].length; + var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length; + var next = this.input.charAt(end); + return next === ";" || next === "}" || + (lineBreak.test(spaceAfter[0]) && + !(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "=")) + } + start += match[0].length; + + // Skip semicolon, if any. + skipWhiteSpace.lastIndex = start; + start += skipWhiteSpace.exec(this.input)[0].length; + if (this.input[start] === ";") + { start++; } + } + }; + + // Predicate that tests whether the next token is of the given + // type, and if yes, consumes it as a side effect. + + pp.eat = function(type) { + if (this.type === type) { + this.next(); + return true + } else { + return false + } + }; + + // Tests whether parsed token is a contextual keyword. + + pp.isContextual = function(name) { + return this.type === types.name && this.value === name && !this.containsEsc + }; + + // Consumes contextual keyword if possible. + + pp.eatContextual = function(name) { + if (!this.isContextual(name)) { return false } + this.next(); + return true + }; + + // Asserts that following token is given contextual keyword. + + pp.expectContextual = function(name) { + if (!this.eatContextual(name)) { this.unexpected(); } + }; + + // Test whether a semicolon can be inserted at the current position. + + 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 + } + }; + + // Consume a semicolon, or, failing that, see if we are allowed to + // pretend that there is a semicolon at this position. + + 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 + } + }; + + // Expect a token of a given type. If found, consume it, otherwise, + // raise an unexpected token error. + + pp.expect = function(type) { + this.eat(type) || this.unexpected(); + }; + + // Raise an unexpected token error. + + 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; + + // ### Statement parsing + + // Parse a program. Initializes the parser, reads any number of + // statements, and wraps them in a Program node. Optionally takes a + // `program` argument. If present, the statements will be appended + // to its body instead of creating a new node. + + pp$1.parseTopLevel = function(node) { + var exports = {}; + if (!node.body) { node.body = []; } + while (this.type !== types.eof) { + var stmt = this.parseStatement(null, true, exports); + node.body.push(stmt); + } + if (this.inModule) + { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1) + { + var name = list[i]; + + this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined")); + } } + this.adaptDirectivePrologue(node.body); + this.next(); + node.sourceType = this.options.sourceType; + return this.finishNode(node, "Program") + }; + + var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}; + + pp$1.isLet = function(context) { + 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); + // For ambiguous cases, determine if a LexicalDeclaration (or only a + // Statement) is allowed here. If context is not empty then only a Statement + // is allowed. However, `let [` is an explicit negative lookahead for + // ExpressionStatement, so special-case it first. + if (nextCh === 91) { return true } // '[' + if (context) { return false } + + if (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 + }; + + // check 'async [no LineTerminator here] function' + // - 'async /*foo*/ function' is OK. + // - 'async /*\n*/ function' is invalid. + 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))) + }; + + // Parse a single statement. + // + // If expecting a statement and finding a slash operator, parse a + // regular expression literal. This is to handle cases like + // `if (foo) /blah/.exec(foo)`, where looking at the previous token + // does not help. + + pp$1.parseStatement = function(context, topLevel, exports) { + var starttype = this.type, node = this.startNode(), kind; + + if (this.isLet(context)) { + starttype = types._var; + kind = "let"; + } + + // Most types of statements are recognized by the keyword they + // start with. Many are trivial to parse, some require a bit of + // complexity. + + 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: + // Function as sole body of either an if statement or a labeled statement + // works, but not when it is part of a labeled statement that is the sole + // body of an if statement. + if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); } + return this.parseFunctionStatement(node, false, !context) + case types._class: + if (context) { 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 (context && 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(true, node) + case types.semi: return this.parseEmptyStatement(node) + case types._export: + case types._import: + if (this.options.ecmaVersion > 10 && starttype === types._import) { + skipWhiteSpace.lastIndex = this.pos; + var skip = skipWhiteSpace.exec(this.input); + var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next); + if (nextCh === 40 || nextCh === 46) // '(' or '.' + { return this.parseExpressionStatement(node, this.parseExpression()) } + } + + 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) + + // If the statement does not start with a statement keyword or a + // brace, it's an ExpressionStatement or LabeledStatement. We + // simply start parsing an expression, and afterwards, if the + // next token is a colon and the expression was a simple + // Identifier node, we switch to interpreting it as a label. + default: + if (this.isAsyncFunction()) { + if (context) { this.unexpected(); } + this.next(); + return this.parseFunctionStatement(node, true, !context) + } + + var maybeName = this.value, expr = this.parseExpression(); + if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon)) + { return this.parseLabeledStatement(node, maybeName, expr, context) } + else { return this.parseExpressionStatement(node, expr) } + } + }; + + pp$1.parseBreakContinueStatement = function(node, keyword) { + 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(); + } + + // Verify that there is an actual destination to break or + // continue to. + var i = 0; + for (; i < this.labels.length; ++i) { + var lab = this.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("do"); + 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") + }; + + // Disambiguating between a `for` and a `for`/`in` or `for`/`of` + // loop is non-trivial. Basically, we have to parse the init `var` + // statement or expression, disallowing the `in` operator (see + // the second parameter to `parseExpression`), and then check + // whether the next token is `in` or `of`. When there is no init + // part (semicolon immediately after the opening parenthesis), it + // is a regular `for` loop. + + 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.enterScope(0); + 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) { + 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 { + this.checkExpressionErrors(refDestructuringErrors, true); + } + if (awaitAt > -1) { this.unexpected(awaitAt); } + return this.parseFor(node, init) + }; + + pp$1.parseFunctionStatement = function(node, isAsync, declarationPosition) { + this.next(); + return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync) + }; + + pp$1.parseIfStatement = function(node) { + this.next(); + node.test = this.parseParenExpression(); + // allow function declarations in branches, but only in non-strict mode + node.consequent = this.parseStatement("if"); + node.alternate = this.eat(types._else) ? this.parseStatement("if") : 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(); + + // In `return` (and `break`/`continue`), the keywords with + // optional arguments, we eagerly look for a semicolon or the + // possibility to insert one. + + 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) { + this.next(); + node.discriminant = this.parseParenExpression(); + node.cases = []; + this.expect(types.braceL); + this.labels.push(switchLabel); + this.enterScope(0); + + // Statements under must be grouped (by label) in SwitchCase + // nodes. `cur` is used to keep the node that we are currently + // adding statements to. + + var cur; + for (var sawDefault = false; this.type !== types.braceR;) { + if (this.type === types._case || this.type === types._default) { + var isCase = this.type === types._case; + if (cur) { this.finishNode(cur, "SwitchCase"); } + node.cases.push(cur = this.startNode()); + cur.consequent = []; + this.next(); + if (isCase) { + cur.test = this.parseExpression(); + } else { + if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); } + sawDefault = true; + cur.test = null; + } + this.expect(types.colon); + } else { + if (!cur) { this.unexpected(); } + cur.consequent.push(this.parseStatement(null)); + } + } + this.exitScope(); + if (cur) { this.finishNode(cur, "SwitchCase"); } + this.next(); // Closing brace + 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") + }; + + // Reused empty array added for node fields that are always empty. + + 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(); + var simple = clause.param.type === "Identifier"; + this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0); + this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL); + this.expect(types.parenR); + } else { + if (this.options.ecmaVersion < 10) { this.unexpected(); } + clause.param = null; + this.enterScope(0); + } + clause.body = this.parseBlock(false); + this.exitScope(); + 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("while"); + 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("with"); + return this.finishNode(node, "WithStatement") + }; + + pp$1.parseEmptyStatement = function(node) { + this.next(); + return this.finishNode(node, "EmptyStatement") + }; + + pp$1.parseLabeledStatement = function(node, maybeName, expr, context) { + for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1) + { + var label = list[i$1]; + + if (label.name === maybeName) + { this.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.labels[i]; + if (label$1.statementStart === node.start) { + // Update information about previous labels on this node + label$1.statementStart = this.start; + label$1.kind = kind; + } else { break } + } + this.labels.push({name: maybeName, kind: kind, statementStart: this.start}); + node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label"); + 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") + }; + + // Parse a semicolon-enclosed block of statements, handling `"use + // strict"` declarations when `allowStrict` is true (used for + // function bodies). + + pp$1.parseBlock = function(createNewLexicalScope, node, exitStrict) { + if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true; + if ( node === void 0 ) node = this.startNode(); + + node.body = []; + this.expect(types.braceL); + if (createNewLexicalScope) { this.enterScope(0); } + while (this.type !== types.braceR) { + var stmt = this.parseStatement(null); + node.body.push(stmt); + } + if (exitStrict) { this.strict = false; } + this.next(); + if (createNewLexicalScope) { this.exitScope(); } + return this.finishNode(node, "BlockStatement") + }; + + // Parse a regular `for` loop. The disambiguation code in + // `parseStatement` will already have parsed the init statement or + // expression. + + 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); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, "ForStatement") + }; + + // Parse a `for`/`in` and `for`/`of` loop, which are almost + // same from parser's perspective. + + pp$1.parseForIn = function(node, init) { + var isForIn = this.type === types._in; + this.next(); + + if ( + init.type === "VariableDeclaration" && + init.declarations[0].init != null && + ( + !isForIn || + this.options.ecmaVersion < 8 || + this.strict || + init.kind !== "var" || + init.declarations[0].id.type !== "Identifier" + ) + ) { + this.raise( + init.start, + ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer") + ); + } else if (init.type === "AssignmentPattern") { + this.raise(init.start, "Invalid left-hand side in for-loop"); + } + node.left = init; + node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign(); + this.expect(types.parenR); + node.body = this.parseStatement("for"); + this.exitScope(); + this.labels.pop(); + return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement") + }; + + // Parse a list of variable declarations. + + pp$1.parseVar = function(node, isFor, kind) { + node.declarations = []; + node.kind = kind; + for (;;) { + var decl = this.startNode(); + this.parseVarId(decl, kind); + if (this.eat(types.eq)) { + decl.init = this.parseMaybeAssign(isFor); + } else if (kind === "const" && !(this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) { + this.unexpected(); + } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types._in || this.isContextual("of")))) { + this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value"); + } else { + decl.init = null; + } + node.declarations.push(this.finishNode(decl, "VariableDeclarator")); + if (!this.eat(types.comma)) { break } + } + return node + }; + + pp$1.parseVarId = function(decl, kind) { + decl.id = this.parseBindingAtom(); + this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false); + }; + + var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4; + + // Parse a function declaration or literal (depending on the + // `statement & FUNC_STATEMENT`). + + // Remove `allowExpressionBody` for 7.0.0, as it is only called with false + pp$1.parseFunction = function(node, statement, allowExpressionBody, isAsync) { + this.initFunction(node); + if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) { + if (this.type === types.star && (statement & FUNC_HANGING_STATEMENT)) + { this.unexpected(); } + node.generator = this.eat(types.star); + } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + if (statement & FUNC_STATEMENT) { + node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types.name ? null : this.parseIdent(); + if (node.id && !(statement & FUNC_HANGING_STATEMENT)) + // If it is a regular function declaration in sloppy mode, then it is + // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding + // mode depends on properties of the current scope (see + // treatFunctionsAsVar). + { this.checkLVal(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); } + } + + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(node.async, node.generator)); + + if (!(statement & FUNC_STATEMENT)) + { node.id = this.type === types.name ? this.parseIdent() : null; } + + this.parseFunctionParams(node); + this.parseFunctionBody(node, allowExpressionBody, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression") + }; + + pp$1.parseFunctionParams = function(node) { + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + }; + + // Parse a class declaration or literal (depending on the + // `isStatement` parameter). + + pp$1.parseClass = function(node, isStatement) { + this.next(); + + // ecma-262 14.6 Class Definitions + // A class definition is always strict mode code. + var oldStrict = this.strict; + this.strict = true; + + this.parseClassId(node, isStatement); + this.parseClassSuper(node); + var classBody = this.startNode(); + var hadConstructor = false; + classBody.body = []; + this.expect(types.braceL); + while (this.type !== types.braceR) { + var element = this.parseClassElement(node.superClass !== null); + if (element) { + classBody.body.push(element); + if (element.type === "MethodDefinition" && element.kind === "constructor") { + if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); } + hadConstructor = true; + } + } + } + this.strict = oldStrict; + this.next(); + node.body = this.finishNode(classBody, "ClassBody"); + return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression") + }; + + pp$1.parseClassElement = function(constructorAllowsSuper) { + 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; + var allowsDirectSuper = false; + 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"; + allowsDirectSuper = constructorAllowsSuper; + } 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(method, isGenerator, isAsync, allowsDirectSuper); + 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(method, isGenerator, isAsync, allowsDirectSuper) { + method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper); + return this.finishNode(method, "MethodDefinition") + }; + + pp$1.parseClassId = function(node, isStatement) { + if (this.type === types.name) { + node.id = this.parseIdent(); + if (isStatement) + { this.checkLVal(node.id, BIND_LEXICAL, false); } + } else { + if (isStatement === true) + { this.unexpected(); } + node.id = null; + } + }; + + pp$1.parseClassSuper = function(node) { + node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null; + }; + + // Parses module export declaration. + + pp$1.parseExport = function(node, exports) { + this.next(); + // export * from '...' + if (this.eat(types.star)) { + if (this.options.ecmaVersion >= 11) { + if (this.eatContextual("as")) { + node.exported = this.parseIdent(true); + this.checkExport(exports, node.exported.name, this.lastTokStart); + } else { + node.exported = null; + } + } + 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)) { // export 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, FUNC_STATEMENT | FUNC_NULLABLE_ID, 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") + } + // export var|const|let|function|class ... + if (this.shouldParseExportStatement()) { + node.declaration = this.parseStatement(null); + 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 { // export { x, y as z } [from '...'] + 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) { + // check for keywords used as local names + var spec = list[i]; + + this.checkUnreserved(spec.local); + // check if export is defined + this.checkLocalExport(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 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.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.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) { + if (!exports) { return } + for (var i = 0, list = decls; i < list.length; i += 1) + { + var decl = list[i]; + + this.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() + }; + + // Parses a comma-separated list of module exports. + + pp$1.parseExportSpecifiers = function(exports) { + var nodes = [], first = true; + // export { x, y as z } [from '...'] + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node = this.startNode(); + node.local = this.parseIdent(true); + node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local; + this.checkExport(exports, node.exported.name, node.exported.start); + nodes.push(this.finishNode(node, "ExportSpecifier")); + } + return nodes + }; + + // Parses import declaration. + + pp$1.parseImport = function(node) { + this.next(); + // import '...' + 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") + }; + + // Parses a comma-separated list of module imports. + + pp$1.parseImportSpecifiers = function() { + var nodes = [], first = true; + if (this.type === types.name) { + // import defaultObj, { x, y as z } from '...' + var node = this.startNode(); + node.local = this.parseIdent(); + this.checkLVal(node.local, BIND_LEXICAL); + 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, BIND_LEXICAL); + nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier")); + return nodes + } + this.expect(types.braceL); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var node$2 = this.startNode(); + node$2.imported = this.parseIdent(true); + if (this.eatContextual("as")) { + node$2.local = this.parseIdent(); + } else { + this.checkUnreserved(node$2.imported); + node$2.local = node$2.imported; + } + this.checkLVal(node$2.local, BIND_LEXICAL); + nodes.push(this.finishNode(node$2, "ImportSpecifier")); + } + return nodes + }; + + // Set `ExpressionStatement#directive` property for directive prologues. + 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" && + // Reject parenthesized strings. + (this.input[statement.start] === "\"" || this.input[statement.start] === "'") + ) + }; + + var pp$2 = Parser.prototype; + + // Convert existing expression atom to assignable pattern + // if possible. + + pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) { + if (this.options.ecmaVersion >= 6 && node) { + switch (node.type) { + case "Identifier": + if (this.inAsync && node.name === "await") + { this.raise(node.start, "Cannot 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.toAssignable(prop, isBinding); + // Early error: + // AssignmentRestProperty[Yield, Await] : + // `...` DestructuringAssignmentTarget[Yield, Await] + // + // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|. + if ( + prop.type === "RestElement" && + (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern") + ) { + this.raise(prop.argument.start, "Unexpected token"); + } + } + break + + case "Property": + // AssignmentProperty has type === "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); + // falls through to AssignmentPattern + + case "AssignmentPattern": + break + + case "ParenthesizedExpression": + this.toAssignable(node.expression, isBinding, refDestructuringErrors); + break + + case "ChainExpression": + this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side"); + break + + case "MemberExpression": + if (!isBinding) { break } + + default: + this.raise(node.start, "Assigning to rvalue"); + } + } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); } + return node + }; + + // Convert list of expression atoms to binding list. + + pp$2.toAssignableList = function(exprList, isBinding) { + var end = exprList.length; + for (var i = 0; i < end; i++) { + var elt = exprList[i]; + if (elt) { this.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 + }; + + // Parses spread element. + + 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(); + + // RestElement inside of a function parameter must be an identifier + if (this.options.ecmaVersion === 6 && this.type !== types.name) + { this.unexpected(); } + + node.argument = this.parseBindingAtom(); + + return this.finishNode(node, "RestElement") + }; + + // Parses lvalue (assignable) atom. + + 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 elts = [], first = true; + while (!this.eat(close)) { + if (first) { first = false; } + else { this.expect(types.comma); } + if (allowEmpty && this.type === types.comma) { + elts.push(null); + } else if (allowTrailingComma && this.afterTrailingComma(close)) { + break + } else if (this.type === types.ellipsis) { + var rest = this.parseRestBinding(); + this.parseBindingListItem(rest); + elts.push(rest); + if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } + this.expect(close); + break + } else { + var elem = this.parseMaybeDefault(this.start, this.startLoc); + this.parseBindingListItem(elem); + elts.push(elem); + } + } + return elts + }; + + pp$2.parseBindingListItem = function(param) { + return param + }; + + // Parses assignment pattern around given atom if possible. + + 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") + }; + + // Verify that a node is an lval — something that can be assigned + // to. + // bindingType can be either: + // 'var' indicating that the lval creates a 'var' binding + // 'let' indicating that the lval creates a lexical ('let' or 'const') binding + // 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references + + pp$2.checkLVal = function(expr, bindingType, checkClashes) { + if ( bindingType === void 0 ) bindingType = BIND_NONE; + + switch (expr.type) { + case "Identifier": + if (bindingType === BIND_LEXICAL && expr.name === "let") + { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); } + 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 !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); } + break + + case "ChainExpression": + this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side"); + 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.checkLVal(prop, bindingType, checkClashes); + } + break + + case "Property": + // AssignmentProperty has type === "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.checkLVal(elem, bindingType, checkClashes); } + } + 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"); + } + }; + + // A recursive descent parser operates by defining functions for all + + var pp$3 = Parser.prototype; + + // Check if property name clashes with already added. + // Object/class getters and setters are not allowed to clash — + // either with each other or with an init property — and in + // strict mode, init properties are also not allowed to be repeated. + + 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) { + if (refDestructuringErrors.doubleProto < 0) + { refDestructuringErrors.doubleProto = key.start; } + // Backwards-compat kludge. Can be removed in version 6.0 + } else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); } + } + propHash.proto = true; + } + return + } + name = "$" + name; + var other = propHash[name]; + if (other) { + var redefinition; + if (kind === "init") { + redefinition = this.strict && other.init || other.get || other.set; + } 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; + }; + + // ### Expression parsing + + // These nest, from the most general expression type at the top to + // 'atomic', nondivisible expression types at the bottom. Most of + // the functions will simply let the function(s) below them parse, + // and, *if* the syntactic construct they handle is present, wrap + // the AST node that the inner parser gave them in another node. + + // Parse a full expression. The optional arguments are used to + // forbid the `in` operator (in for loops initalization expressions) + // and provide reference for storing '=' operator inside shorthand + // property assignment in contexts where both object expression + // and object pattern might appear (so it's possible to raise + // delayed syntax error at correct position). + + pp$3.parseExpression = function(noIn, refDestructuringErrors) { + 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.parseMaybeAssign(noIn, refDestructuringErrors)); } + return this.finishNode(node, "SequenceExpression") + } + return expr + }; + + // Parse an assignment expression. This includes applications of + // operators like `+=`. + + pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) { + if (this.isContextual("yield")) { + if (this.inGenerator) { return this.parseYield(noIn) } + // The tokenizer will assume an expression is allowed after + // `yield`, but this isn't that kind of yield + else { this.exprAllowed = false; } + } + + 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) { + refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1; + } + if (refDestructuringErrors.shorthandAssign >= node.left.start) + { refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly + 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 + }; + + // Parse a ternary conditional (`?:`) operator. + + 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 + }; + + // Start the precedence parser. + + 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) + }; + + // Parse binary operators with the operator precedence parsing + // algorithm. `left` is the left-hand side of the operator. + // `minPrec` provides context that allows the function to stop and + // defer further parser to one of its callers when it encounters an + // operator that has a lower precedence than the set it is parsing. + + 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 coalesce = this.type === types.coalesce; + if (coalesce) { + // Handle the precedence of `tt.coalesce` as equal to the range of logical expressions. + // In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error. + prec = types.logicalAND.binop; + } + 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 || coalesce); + if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) { + this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses"); + } + 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") + }; + + // Parse unary operators, both prefix and postfix. + + pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) { + 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 { + expr = this.parseExprSubscripts(refDestructuringErrors); + if (this.checkExpressionErrors(refDestructuringErrors)) { return expr } + while (this.type.postfix && !this.canInsertSemicolon()) { + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.operator = this.value; + node$1.prefix = false; + node$1.argument = expr; + this.checkLVal(expr); + this.next(); + expr = this.finishNode(node$1, "UpdateExpression"); + } + } + + if (!sawUnary && this.eat(types.starstar)) + { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) } + else + { return expr } + }; + + // Parse call, dot, and `[]`-subscript expressions. + + pp$3.parseExprSubscripts = function(refDestructuringErrors) { + var startPos = this.start, startLoc = this.startLoc; + var expr = this.parseExprAtom(refDestructuringErrors); + if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")") + { 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 maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" && + this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && + this.potentialArrowAt === base.start; + var optionalChained = false; + + while (true) { + var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained); + + if (element.optional) { optionalChained = true; } + if (element === base || element.type === "ArrowFunctionExpression") { + if (optionalChained) { + var chainNode = this.startNodeAt(startPos, startLoc); + chainNode.expression = element; + element = this.finishNode(chainNode, "ChainExpression"); + } + return element + } + + base = element; + } + }; + + pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained) { + var optionalSupported = this.options.ecmaVersion >= 11; + var optional = optionalSupported && this.eat(types.questionDot); + if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); } + + var computed = this.eat(types.bracketL); + if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) { + var node = this.startNodeAt(startPos, startLoc); + node.object = base; + node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never"); + node.computed = !!computed; + if (computed) { this.expect(types.bracketR); } + if (optionalSupported) { + node.optional = optional; + } + base = this.finishNode(node, "MemberExpression"); + } else if (!noCalls && this.eat(types.parenL)) { + var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors); + if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types.arrow)) { + this.checkPatternErrors(refDestructuringErrors, false); + this.checkYieldAwaitInDefaultParams(); + if (this.awaitIdentPos > 0) + { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); } + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true) + } + this.checkExpressionErrors(refDestructuringErrors, true); + this.yieldPos = oldYieldPos || this.yieldPos; + this.awaitPos = oldAwaitPos || this.awaitPos; + this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos; + var node$1 = this.startNodeAt(startPos, startLoc); + node$1.callee = base; + node$1.arguments = exprList; + if (optionalSupported) { + node$1.optional = optional; + } + base = this.finishNode(node$1, "CallExpression"); + } else if (this.type === types.backQuote) { + if (optional || optionalChained) { + this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions"); + } + var node$2 = this.startNodeAt(startPos, startLoc); + node$2.tag = base; + node$2.quasi = this.parseTemplate({isTagged: true}); + base = this.finishNode(node$2, "TaggedTemplateExpression"); + } + return base + }; + + // Parse an atomic expression — either a single token that is an + // expression, an expression started by a keyword like `function` or + // `new`, or an expression wrapped in punctuation like `()`, `[]`, + // or `{}`. + + pp$3.parseExprAtom = function(refDestructuringErrors) { + // If a division operator appears in an expression position, the + // tokenizer got confused, and we force it to read a regexp instead. + if (this.type === types.slash) { this.readRegexp(); } + + var node, canBeArrow = this.potentialArrowAt === this.start; + switch (this.type) { + case types._super: + if (!this.allowSuper) + { this.raise(this.start, "'super' keyword outside a method"); } + node = this.startNode(); + this.next(); + if (this.type === types.parenL && !this.allowDirectSuper) + { this.raise(node.start, "super() call outside constructor of a subclass"); } + // The `super` keyword can appear at below: + // SuperProperty: + // super [ Expression ] + // super . IdentifierName + // SuperCall: + // super ( Arguments ) + 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(false); + if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function)) + { return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, 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(false); + 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, 0) + + case types._class: + return this.parseClass(this.startNode(), false) + + case types._new: + return this.parseNew() + + case types.backQuote: + return this.parseTemplate() + + case types._import: + if (this.options.ecmaVersion >= 11) { + return this.parseExprImport() + } else { + return this.unexpected() + } + + default: + this.unexpected(); + } + }; + + pp$3.parseExprImport = function() { + var node = this.startNode(); + + // Consume `import` as an identifier for `import.meta`. + // Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`. + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); } + var meta = this.parseIdent(true); + + switch (this.type) { + case types.parenL: + return this.parseDynamicImport(node) + case types.dot: + node.meta = meta; + return this.parseImportMeta(node) + default: + this.unexpected(); + } + }; + + pp$3.parseDynamicImport = function(node) { + this.next(); // skip `(` + + // Parse node.source. + node.source = this.parseMaybeAssign(); + + // Verify ending. + if (!this.eat(types.parenR)) { + var errorPos = this.start; + if (this.eat(types.comma) && this.eat(types.parenR)) { + this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()"); + } else { + this.unexpected(errorPos); + } + } + + return this.finishNode(node, "ImportExpression") + }; + + pp$3.parseImportMeta = function(node) { + this.next(); // skip `.` + + var containsEsc = this.containsEsc; + node.property = this.parseIdent(true); + + if (node.property.name !== "meta") + { this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); } + if (this.options.sourceType !== "module") + { this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); } + + return this.finishNode(node, "MetaProperty") + }; + + pp$3.parseLiteral = function(value) { + var node = this.startNode(); + node.value = value; + node.raw = this.input.slice(this.start, this.end); + if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); } + 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 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; + // Do not save awaitIdentPos to allow checking awaits nested in parameters + while (this.type !== types.parenR) { + first ? first = false : this.expect(types.comma); + if (allowTrailingComma && this.afterTrailingComma(types.parenR, true)) { + lastIsComma = true; + break + } else if (this.type === types.ellipsis) { + spreadStart = this.start; + exprList.push(this.parseParenItem(this.parseRestBinding())); + if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); } + break + } else { + exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.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 (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) + }; + + // New's precedence is slightly tricky. It must allow its argument to + // be a `[]` or dot subscript expression, but not a call — at least, + // not without wrapping it in parentheses. Thus, it uses the noCalls + // argument to parseSubscripts to prevent it from consuming the + // argument list. + + var empty$1 = []; + + pp$3.parseNew = function() { + if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); } + 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") + { this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); } + if (containsEsc) + { this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); } + if (!this.inNonArrowFunction()) + { this.raiseRecoverable(node.start, "'new.target' can only be used in functions"); } + return this.finishNode(node, "MetaProperty") + } + var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types._import; + node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true); + if (isImport && node.callee.type === "ImportExpression") { + this.raise(startPos, "Cannot use new with import()"); + } + 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") + }; + + // Parse template expression. + + 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) { + 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.type === types.eof) { this.raise(this.pos, "Unterminated template literal"); } + this.expect(types.dollarBraceL); + node.expressions.push(this.parseExpression()); + this.expect(types.braceR); + node.quasis.push(curElt = this.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)) + }; + + // Parse an object literal or binding pattern. + + pp$3.parseObj = function(isPattern, refDestructuringErrors) { + var node = this.startNode(), first = true, propHash = {}; + node.properties = []; + this.next(); + while (!this.eat(types.braceR)) { + if (!first) { + this.expect(types.comma); + if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types.braceR)) { break } + } else { first = false; } + + var prop = this.parseProperty(isPattern, refDestructuringErrors); + if (!isPattern) { this.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") + } + // To disallow parenthesized identifier via `this.toAssignable()`. + if (this.type === types.parenL && refDestructuringErrors) { + if (refDestructuringErrors.parenthesizedAssign < 0) { + refDestructuringErrors.parenthesizedAssign = this.start; + } + if (refDestructuringErrors.parenthesizedBind < 0) { + refDestructuringErrors.parenthesizedBind = this.start; + } + } + // Parse argument. + prop.argument = this.parseMaybeAssign(false, refDestructuringErrors); + // To disallow trailing comma via `this.toAssignable()`. + if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) { + refDestructuringErrors.trailingComma = this.start; + } + // Finish + 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 && this.type !== types.eq)) { + 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") { + if (isGenerator || isAsync) { this.unexpected(); } + this.checkUnreserved(prop.key); + if (prop.key.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = startPos; } + 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; + } + 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; + } + } + return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never") + }; + + // Initialize empty function node. + + pp$3.initFunction = function(node) { + node.id = null; + if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; } + if (this.options.ecmaVersion >= 8) { node.async = false; } + }; + + // Parse object or class method. + + pp$3.parseMethod = function(isGenerator, isAsync, allowDirectSuper) { + var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.initFunction(node); + if (this.options.ecmaVersion >= 6) + { node.generator = isGenerator; } + if (this.options.ecmaVersion >= 8) + { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0)); + + this.expect(types.parenL); + node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8); + this.checkYieldAwaitInDefaultParams(); + this.parseFunctionBody(node, false, true); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "FunctionExpression") + }; + + // Parse arrow function expression with given parameters. + + pp$3.parseArrowExpression = function(node, params, isAsync) { + var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos; + + this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW); + this.initFunction(node); + if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; } + + this.yieldPos = 0; + this.awaitPos = 0; + this.awaitIdentPos = 0; + + node.params = this.toAssignableList(params, true); + this.parseFunctionBody(node, true, false); + + this.yieldPos = oldYieldPos; + this.awaitPos = oldAwaitPos; + this.awaitIdentPos = oldAwaitIdentPos; + return this.finishNode(node, "ArrowFunctionExpression") + }; + + // Parse function body and check parameters. + + pp$3.parseFunctionBody = function(node, isArrowFunction, isMethod) { + 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 this is a strict mode function, verify that argument names + // are not repeated, and it does not try to bind the words `eval` + // or `arguments`. + if (useStrict && nonSimple) + { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); } + } + // Start a new scope with regard to labels and the `inFunction` + // flag (restore them to their old value afterwards). + var oldLabels = this.labels; + this.labels = []; + if (useStrict) { this.strict = true; } + + // Add the params to varDeclaredNames to ensure that an error is thrown + // if a let/const declaration in the function clashes with one of the params. + this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params)); + // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval' + if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); } + node.body = this.parseBlock(false, undefined, useStrict && !oldStrict); + node.expression = false; + this.adaptDirectivePrologue(node.body.body); + this.labels = oldLabels; + } + this.exitScope(); + }; + + 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 + }; + + // Checks function params for various disallowed patterns such as using "eval" + // or "arguments" and duplicate parameters. + + pp$3.checkParams = function(node, allowDuplicates) { + var nameHash = {}; + for (var i = 0, list = node.params; i < list.length; i += 1) + { + var param = list[i]; + + this.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash); + } + }; + + // Parses a comma-separated list of expressions, and returns them as + // an array. `close` is the token type that ends the list, and + // `allowEmpty` can be turned on to allow subsequent commas with + // nothing in between them to be parsed as `null` (which is needed + // for array literals). + + pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) { + var elts = [], first = true; + while (!this.eat(close)) { + if (!first) { + this.expect(types.comma); + if (allowTrailingComma && this.afterTrailingComma(close)) { break } + } else { first = false; } + + var elt = (void 0); + if (allowEmpty && this.type === types.comma) + { elt = null; } + else if (this.type === types.ellipsis) { + elt = this.parseSpread(refDestructuringErrors); + if (refDestructuringErrors && this.type === types.comma && refDestructuringErrors.trailingComma < 0) + { refDestructuringErrors.trailingComma = this.start; } + } else { + elt = this.parseMaybeAssign(false, refDestructuringErrors); + } + 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, "Cannot use 'yield' as identifier inside a generator"); } + if (this.inAsync && name === "await") + { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); } + if (this.keywords.test(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, "Cannot use keyword 'await' outside an async function"); } + this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved")); + } + }; + + // Parse the next token as an identifier. If `liberal` is true (used + // when parsing properties), it will also convert keywords into + // identifiers. + + pp$3.parseIdent = function(liberal, isBinding) { + var node = this.startNode(); + if (this.type === types.name) { + node.name = this.value; + } else if (this.type.keyword) { + node.name = this.type.keyword; + + // To fix https://github.com/acornjs/acorn/issues/575 + // `class` and `function` keywords push new context into this.context. + // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name. + // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword + if ((node.name === "class" || node.name === "function") && + (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) { + this.context.pop(); + } + } else { + this.unexpected(); + } + this.next(!!liberal); + this.finishNode(node, "Identifier"); + if (!liberal) { + this.checkUnreserved(node); + if (node.name === "await" && !this.awaitIdentPos) + { this.awaitIdentPos = node.start; } + } + return node + }; + + // Parses yield expression inside generator. + + pp$3.parseYield = function(noIn) { + 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(noIn); + } + 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, false); + return this.finishNode(node, "AwaitExpression") + }; + + var pp$4 = Parser.prototype; + + // This function is used to raise exceptions on parse errors. It + // takes an offset integer (into the current `input`) to indicate + // the location of the error, attaches the position to the end + // of the error message, and then raises a `SyntaxError` with that + // message. + + 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 Scope = function Scope(flags) { + this.flags = flags; + // A list of var-declared names in the current lexical scope + this.var = []; + // A list of lexically-declared names in the current lexical scope + this.lexical = []; + // A list of lexically-declared FunctionDeclaration names in the current lexical scope + this.functions = []; + }; + + // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names. + + pp$5.enterScope = function(flags) { + this.scopeStack.push(new Scope(flags)); + }; + + pp$5.exitScope = function() { + this.scopeStack.pop(); + }; + + // The spec says: + // > At the top level of a function, or script, function declarations are + // > treated like var declarations rather than like lexical declarations. + pp$5.treatFunctionsAsVarInScope = function(scope) { + return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP) + }; + + pp$5.declareName = function(name, bindingType, pos) { + var redeclared = false; + if (bindingType === BIND_LEXICAL) { + var scope = this.currentScope(); + redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1; + scope.lexical.push(name); + if (this.inModule && (scope.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + } else if (bindingType === BIND_SIMPLE_CATCH) { + var scope$1 = this.currentScope(); + scope$1.lexical.push(name); + } else if (bindingType === BIND_FUNCTION) { + var scope$2 = this.currentScope(); + if (this.treatFunctionsAsVar) + { redeclared = scope$2.lexical.indexOf(name) > -1; } + else + { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; } + scope$2.functions.push(name); + } else { + for (var i = this.scopeStack.length - 1; i >= 0; --i) { + var scope$3 = this.scopeStack[i]; + if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) || + !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) { + redeclared = true; + break + } + scope$3.var.push(name); + if (this.inModule && (scope$3.flags & SCOPE_TOP)) + { delete this.undefinedExports[name]; } + if (scope$3.flags & SCOPE_VAR) { break } + } + } + if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); } + }; + + pp$5.checkLocalExport = function(id) { + // scope.functions must be empty as Module code is always strict. + if (this.scopeStack[0].lexical.indexOf(id.name) === -1 && + this.scopeStack[0].var.indexOf(id.name) === -1) { + this.undefinedExports[id.name] = id; + } + }; + + pp$5.currentScope = function() { + return this.scopeStack[this.scopeStack.length - 1] + }; + + pp$5.currentVarScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & SCOPE_VAR) { return scope } + } + }; + + // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`. + pp$5.currentThisScope = function() { + for (var i = this.scopeStack.length - 1;; i--) { + var scope = this.scopeStack[i]; + if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope } + } + }; + + 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]; } + }; + + // Start an AST node, attaching a start offset. + + 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) + }; + + // Finish an AST node, adding `type` and `end` properties. + + 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) + }; + + // Finish node at given position + + pp$6.finishNodeAt = function(node, type, pos, loc) { + return finishNodeAt.call(this, node, type, pos, loc) + }; + + // The algorithm used to determine whether a regexp can appear at a + + 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 } + + // The check for `tt.name && exprAllowed` detects whether we are + // after a `yield` or `of` construct. See the `updateContext` for + // `tt.name`. + 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._const || prevType === types.name) + { return false } + return !this.exprAllowed + }; + + pp$7.inGeneratorContext = function() { + for (var i = this.context.length - 1; i >= 1; i--) { + var context = this.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; } + }; + + // Token-specific context update code + + 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; + }; + + 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() { + // tokExprAllowed stays unchanged + }; + + types._function.updateContext = types._class.updateContext = function(prevType) { + if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else && + !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && + !((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; } + 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; + }; + + // This file contains Unicode properties extracted from the ECMAScript + // specification. The lists are extracted like so: + // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText) + + // #table-binary-unicode-properties + var ecma9BinaryProperties = "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"; + var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic"; + var ecma11BinaryProperties = ecma10BinaryProperties; + var unicodeBinaryProperties = { + 9: ecma9BinaryProperties, + 10: ecma10BinaryProperties, + 11: ecma11BinaryProperties + }; + + // #table-unicode-general-category-values + var unicodeGeneralCategoryValues = "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"; + + // #table-unicode-script-values + var ecma9ScriptValues = "Adlam Adlm Ahom 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 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 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 Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa 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 Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb"; + var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd"; + var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho"; + var unicodeScriptValues = { + 9: ecma9ScriptValues, + 10: ecma10ScriptValues, + 11: ecma11ScriptValues + }; + + var data = {}; + function buildUnicodeData(ecmaVersion) { + var d = data[ecmaVersion] = { + binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues), + nonBinary: { + General_Category: wordsRegexp(unicodeGeneralCategoryValues), + Script: wordsRegexp(unicodeScriptValues[ecmaVersion]) + } + }; + d.nonBinary.Script_Extensions = d.nonBinary.Script; + + d.nonBinary.gc = d.nonBinary.General_Category; + d.nonBinary.sc = d.nonBinary.Script; + d.nonBinary.scx = d.nonBinary.Script_Extensions; + } + buildUnicodeData(9); + buildUnicodeData(10); + buildUnicodeData(11); + + var pp$8 = Parser.prototype; + + var RegExpValidationState = function RegExpValidationState(parser) { + this.parser = parser; + this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : ""); + this.unicodeProperties = data[parser.options.ecmaVersion >= 11 ? 11 : parser.options.ecmaVersion]; + 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)); + }; + + // If u flag is given, this returns the code point at the index (it combines a surrogate pair). + // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair). + RegExpValidationState.prototype.at = function at (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return -1 + } + var c = s.charCodeAt(i); + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) { + return c + } + var next = s.charCodeAt(i + 1); + return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c + }; + + RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) { + if ( forceU === void 0 ) forceU = false; + + var s = this.source; + var l = s.length; + if (i >= l) { + return l + } + var c = s.charCodeAt(i), next; + if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l || + (next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) { + return i + 1 + } + return i + 2 + }; + + RegExpValidationState.prototype.current = function current (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.pos, forceU) + }; + + RegExpValidationState.prototype.lookahead = function lookahead (forceU) { + if ( forceU === void 0 ) forceU = false; + + return this.at(this.nextIndex(this.pos, forceU), forceU) + }; + + RegExpValidationState.prototype.advance = function advance (forceU) { + if ( forceU === void 0 ) forceU = false; + + this.pos = this.nextIndex(this.pos, forceU); + }; + + RegExpValidationState.prototype.eat = function eat (ch, forceU) { + if ( forceU === void 0 ) forceU = false; + + if (this.current(forceU) === ch) { + this.advance(forceU); + return true + } + return false + }; + + function codePointToString(ch) { + if (ch <= 0xFFFF) { return String.fromCharCode(ch) } + ch -= 0x10000; + return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00) + } + + /** + * Validate the flags part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$8.validateRegExpFlags = function(state) { + 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.raise(state.start, "Invalid regular expression flag"); + } + if (flags.indexOf(flag, i + 1) > -1) { + this.raise(state.start, "Duplicate regular expression flag"); + } + } + }; + + /** + * Validate the pattern part of a given RegExpLiteral. + * + * @param {RegExpValidationState} state The state to validate RegExp. + * @returns {void} + */ + pp$8.validateRegExpPattern = function(state) { + this.regexp_pattern(state); + + // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of + // parsing contains a |GroupName|, reparse with the goal symbol + // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError* + // exception if _P_ did not conform to the grammar, if any elements of _P_ + // were not matched by the parse, or if any Early Error conditions exist. + if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) { + state.switchN = true; + this.regexp_pattern(state); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern + pp$8.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) { + // Make the same messages as V8. + if (state.eat(0x29 /* ) */)) { + state.raise("Unmatched ')'"); + } + if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) { + state.raise("Lone quantifier brackets"); + } + } + 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"); + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction + pp$8.regexp_disjunction = function(state) { + this.regexp_alternative(state); + while (state.eat(0x7C /* | */)) { + this.regexp_alternative(state); + } + + // Make the same message as V8. + if (this.regexp_eatQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + if (state.eat(0x7B /* { */)) { + state.raise("Lone quantifier brackets"); + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative + pp$8.regexp_alternative = function(state) { + while (state.pos < state.source.length && this.regexp_eatTerm(state)) + { } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term + pp$8.regexp_eatTerm = function(state) { + if (this.regexp_eatAssertion(state)) { + // Handle `QuantifiableAssertion Quantifier` alternative. + // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion + // is a QuantifiableAssertion. + if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) { + // Make the same message as V8. + if (state.switchU) { + state.raise("Invalid quantifier"); + } + } + return true + } + + if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) { + this.regexp_eatQuantifier(state); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion + pp$8.regexp_eatAssertion = function(state) { + var start = state.pos; + state.lastAssertionIsQuantifiable = false; + + // ^, $ + if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) { + return true + } + + // \b \B + if (state.eat(0x5C /* \ */)) { + if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) { + return true + } + state.pos = start; + } + + // Lookahead / Lookbehind + 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 + } + } + + state.pos = start; + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier + pp$8.regexp_eatQuantifier = function(state, noError) { + if ( noError === void 0 ) noError = false; + + if (this.regexp_eatQuantifierPrefix(state, noError)) { + state.eat(0x3F /* ? */); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix + pp$8.regexp_eatQuantifierPrefix = function(state, noError) { + return ( + state.eat(0x2A /* * */) || + state.eat(0x2B /* + */) || + state.eat(0x3F /* ? */) || + this.regexp_eatBracedQuantifier(state, noError) + ) + }; + pp$8.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 /* } */)) { + // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term + if (max !== -1 && max < min && !noError) { + state.raise("numbers out of order in {} quantifier"); + } + return true + } + } + if (state.switchU && !noError) { + state.raise("Incomplete quantifier"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom + pp$8.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$8.regexp_eatReverseSolidusAtomEscape = function(state) { + var start = state.pos; + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatAtomEscape(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$8.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; + } + return false + }; + pp$8.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 + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom + pp$8.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) + ) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier + pp$8.regexp_eatInvalidBracedQuantifier = function(state) { + if (this.regexp_eatBracedQuantifier(state, true)) { + state.raise("Nothing to repeat"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter + pp$8.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 /* } */ + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter + // But eat eager. + pp$8.regexp_eatPatternCharacters = function(state) { + var start = state.pos; + var ch = 0; + while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) { + state.advance(); + } + return state.pos !== start + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter + pp$8.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 + }; + + // GroupSpecifier :: + // [empty] + // `?` GroupName + pp$8.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"); + } + }; + + // GroupName :: + // `<` RegExpIdentifierName `>` + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$8.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 + }; + + // RegExpIdentifierName :: + // RegExpIdentifierStart + // RegExpIdentifierName RegExpIdentifierPart + // Note: this updates `state.lastStringValue` property with the eaten name. + pp$8.regexp_eatRegExpIdentifierName = function(state) { + state.lastStringValue = ""; + if (this.regexp_eatRegExpIdentifierStart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + while (this.regexp_eatRegExpIdentifierPart(state)) { + state.lastStringValue += codePointToString(state.lastIntValue); + } + return true + } + return false + }; + + // RegExpIdentifierStart :: + // UnicodeIDStart + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + pp$8.regexp_eatRegExpIdentifierStart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + 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 /* _ */ + } + + // RegExpIdentifierPart :: + // UnicodeIDContinue + // `$` + // `_` + // `\` RegExpUnicodeEscapeSequence[+U] + // + // + pp$8.regexp_eatRegExpIdentifierPart = function(state) { + var start = state.pos; + var forceU = this.options.ecmaVersion >= 11; + var ch = state.current(forceU); + state.advance(forceU); + + if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) { + 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 /* */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape + pp$8.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) { + // Make the same message as V8. + if (state.current() === 0x63 /* c */) { + state.raise("Invalid unicode escape"); + } + state.raise("Invalid escape"); + } + return false + }; + pp$8.regexp_eatBackReference = function(state) { + var start = state.pos; + if (this.regexp_eatDecimalEscape(state)) { + var n = state.lastIntValue; + if (state.switchU) { + // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape + if (n > state.maxBackReference) { + state.maxBackReference = n; + } + return true + } + if (n <= state.numCapturingParens) { + return true + } + state.pos = start; + } + return false + }; + pp$8.regexp_eatKGroupName = function(state) { + if (state.eat(0x6B /* k */)) { + if (this.regexp_eatGroupName(state)) { + state.backReferenceNames.push(state.lastStringValue); + return true + } + state.raise("Invalid named reference"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape + pp$8.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, false) || + (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) || + this.regexp_eatIdentityEscape(state) + ) + }; + pp$8.regexp_eatCControlLetter = function(state) { + var start = state.pos; + if (state.eat(0x63 /* c */)) { + if (this.regexp_eatControlLetter(state)) { + return true + } + state.pos = start; + } + return false + }; + pp$8.regexp_eatZero = function(state) { + if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) { + state.lastIntValue = 0; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape + pp$8.regexp_eatControlEscape = function(state) { + var ch = state.current(); + if (ch === 0x74 /* t */) { + state.lastIntValue = 0x09; /* \t */ + state.advance(); + return true + } + if (ch === 0x6E /* n */) { + state.lastIntValue = 0x0A; /* \n */ + state.advance(); + return true + } + if (ch === 0x76 /* v */) { + state.lastIntValue = 0x0B; /* \v */ + state.advance(); + return true + } + if (ch === 0x66 /* f */) { + state.lastIntValue = 0x0C; /* \f */ + state.advance(); + return true + } + if (ch === 0x72 /* r */) { + state.lastIntValue = 0x0D; /* \r */ + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter + pp$8.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 /* A */ && ch <= 0x5A /* Z */) || + (ch >= 0x61 /* a */ && ch <= 0x7A /* z */) + ) + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence + pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) { + if ( forceU === void 0 ) forceU = false; + + var start = state.pos; + var switchU = forceU || state.switchU; + + if (state.eat(0x75 /* u */)) { + if (this.regexp_eatFixedHexDigits(state, 4)) { + var lead = state.lastIntValue; + if (switchU && lead >= 0xD800 && lead <= 0xDBFF) { + var leadSurrogateEnd = state.pos; + if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && 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 ( + switchU && + state.eat(0x7B /* { */) && + this.regexp_eatHexDigits(state) && + state.eat(0x7D /* } */) && + isValidUnicode(state.lastIntValue) + ) { + return true + } + if (switchU) { + state.raise("Invalid unicode escape"); + } + state.pos = start; + } + + return false + }; + function isValidUnicode(ch) { + return ch >= 0 && ch <= 0x10FFFF + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape + pp$8.regexp_eatIdentityEscape = function(state) { + if (state.switchU) { + if (this.regexp_eatSyntaxCharacter(state)) { + return true + } + if (state.eat(0x2F /* / */)) { + state.lastIntValue = 0x2F; /* / */ + return true + } + return false + } + + var ch = state.current(); + if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) { + state.lastIntValue = ch; + state.advance(); + return true + } + + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape + pp$8.regexp_eatDecimalEscape = function(state) { + state.lastIntValue = 0; + var ch = state.current(); + if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) { + do { + state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */); + state.advance(); + } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape + pp$8.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 /* P */ || ch === 0x70 /* p */) + ) { + 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 /* d */ || + ch === 0x44 /* D */ || + ch === 0x73 /* s */ || + ch === 0x53 /* S */ || + ch === 0x77 /* w */ || + ch === 0x57 /* W */ + ) + } + + // UnicodePropertyValueExpression :: + // UnicodePropertyName `=` UnicodePropertyValue + // LoneUnicodePropertyNameOrValue + pp$8.regexp_eatUnicodePropertyValueExpression = function(state) { + var start = state.pos; + + // UnicodePropertyName `=` UnicodePropertyValue + 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; + + // LoneUnicodePropertyNameOrValue + if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) { + var nameOrValue = state.lastStringValue; + this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue); + return true + } + return false + }; + pp$8.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) { + if (!has(state.unicodeProperties.nonBinary, name)) + { state.raise("Invalid property name"); } + if (!state.unicodeProperties.nonBinary[name].test(value)) + { state.raise("Invalid property value"); } + }; + pp$8.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) { + if (!state.unicodeProperties.binary.test(nameOrValue)) + { state.raise("Invalid property name"); } + }; + + // UnicodePropertyName :: + // UnicodePropertyNameCharacters + pp$8.regexp_eatUnicodePropertyName = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyNameCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyNameCharacter(ch) { + return isControlLetter(ch) || ch === 0x5F /* _ */ + } + + // UnicodePropertyValue :: + // UnicodePropertyValueCharacters + pp$8.regexp_eatUnicodePropertyValue = function(state) { + var ch = 0; + state.lastStringValue = ""; + while (isUnicodePropertyValueCharacter(ch = state.current())) { + state.lastStringValue += codePointToString(ch); + state.advance(); + } + return state.lastStringValue !== "" + }; + function isUnicodePropertyValueCharacter(ch) { + return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch) + } + + // LoneUnicodePropertyNameOrValue :: + // UnicodePropertyValueCharacters + pp$8.regexp_eatLoneUnicodePropertyNameOrValue = function(state) { + return this.regexp_eatUnicodePropertyValue(state) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass + pp$8.regexp_eatCharacterClass = function(state) { + if (state.eat(0x5B /* [ */)) { + state.eat(0x5E /* ^ */); + this.regexp_classRanges(state); + if (state.eat(0x5D /* ] */)) { + return true + } + // Unreachable since it threw "unterminated regular expression" error before. + state.raise("Unterminated character class"); + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges + // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash + pp$8.regexp_classRanges = function(state) { + while (this.regexp_eatClassAtom(state)) { + var left = state.lastIntValue; + if (state.eat(0x2D /* - */) && this.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"); + } + } + } + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom + // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash + pp$8.regexp_eatClassAtom = function(state) { + var start = state.pos; + + if (state.eat(0x5C /* \ */)) { + if (this.regexp_eatClassEscape(state)) { + return true + } + if (state.switchU) { + // Make the same message as V8. + var ch$1 = state.current(); + if (ch$1 === 0x63 /* c */ || 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 + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape + pp$8.regexp_eatClassEscape = function(state) { + var start = state.pos; + + if (state.eat(0x62 /* b */)) { + state.lastIntValue = 0x08; /* */ + return true + } + + if (state.switchU && state.eat(0x2D /* - */)) { + state.lastIntValue = 0x2D; /* - */ + return true + } + + if (!state.switchU && state.eat(0x63 /* c */)) { + if (this.regexp_eatClassControlLetter(state)) { + return true + } + state.pos = start; + } + + return ( + this.regexp_eatCharacterClassEscape(state) || + this.regexp_eatCharacterEscape(state) + ) + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter + pp$8.regexp_eatClassControlLetter = function(state) { + var ch = state.current(); + if (isDecimalDigit(ch) || ch === 0x5F /* _ */) { + state.lastIntValue = ch % 0x20; + state.advance(); + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$8.regexp_eatHexEscapeSequence = function(state) { + var start = state.pos; + if (state.eat(0x78 /* x */)) { + if (this.regexp_eatFixedHexDigits(state, 2)) { + return true + } + if (state.switchU) { + state.raise("Invalid escape"); + } + state.pos = start; + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits + pp$8.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 /* 0 */); + state.advance(); + } + return state.pos !== start + }; + function isDecimalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits + pp$8.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 /* 0 */ && ch <= 0x39 /* 9 */) || + (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) || + (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) + ) + } + function hexToInt(ch) { + if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) { + return 10 + (ch - 0x41 /* A */) + } + if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) { + return 10 + (ch - 0x61 /* a */) + } + return ch - 0x30 /* 0 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence + // Allows only 0-377(octal) i.e. 0-255(decimal). + pp$8.regexp_eatLegacyOctalEscapeSequence = function(state) { + if (this.regexp_eatOctalDigit(state)) { + 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; + } + return true + } + return false + }; + + // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit + pp$8.regexp_eatOctalDigit = function(state) { + var ch = state.current(); + if (isOctalDigit(ch)) { + state.lastIntValue = ch - 0x30; /* 0 */ + state.advance(); + return true + } + state.lastIntValue = 0; + return false + }; + function isOctalDigit(ch) { + return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */ + } + + // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits + // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit + // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence + pp$8.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(); + } + return true + }; + + // Object type used to represent tokens. Note that normally, tokens + // simply exist as properties on the parser object. This is only + // used for the onToken callback and the external tokenizer. + + 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]; } + }; + + // ## Tokenizer + + var pp$9 = Parser.prototype; + + // Move to the next token + + pp$9.next = function(ignoreEscapeSequenceInKeyword) { + if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc) + { this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); } + 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$9.getToken = function() { + this.next(); + return new Token(this) + }; + + // If we're in an ES6 environment, make parsers iterable + if (typeof Symbol !== "undefined") + { pp$9[Symbol.iterator] = function() { + var this$1 = this; + + return { + next: function () { + var token = this$1.getToken(); + return { + done: token.type === types.eof, + value: token + } + } + } + }; } + + // Toggle strict mode. Re-reads the next number or string to please + // pedantic tests (`"use strict"; 010;` should fail). + + pp$9.curContext = function() { + return this.context[this.context.length - 1] + }; + + // Read a single token, updating the parser object's token-related + // properties. + + pp$9.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$9.readToken = function(code) { + // Identifier or keyword. '\uXXXX' sequences are allowed in + // identifiers, so '\' also dispatches to that. + if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */) + { return this.readWord() } + + return this.getTokenFromCode(code) + }; + + pp$9.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$9.skipBlockComment = function() { + 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.curLine; + this.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$9.skipLineComment = function(startSkip) { + 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.input.charCodeAt(++this.pos); + } + if (this.options.onComment) + { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, + startLoc, this.curPosition()); } + }; + + // Called at the start of the parse and after every token. Skips + // whitespace and comments, and. + + pp$9.skipSpace = function() { + loop: while (this.pos < this.input.length) { + var ch = this.input.charCodeAt(this.pos); + switch (ch) { + case 32: case 160: // ' ' + ++this.pos; + break + case 13: + if (this.input.charCodeAt(this.pos + 1) === 10) { + ++this.pos; + } + case 10: case 8232: case 8233: + ++this.pos; + if (this.options.locations) { + ++this.curLine; + this.lineStart = this.pos; + } + break + case 47: // '/' + switch (this.input.charCodeAt(this.pos + 1)) { + case 42: // '*' + this.skipBlockComment(); + break + case 47: + this.skipLineComment(2); + break + default: + break loop + } + break + default: + if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) { + ++this.pos; + } else { + break loop + } + } + } + }; + + // Called at the end of every token. Sets `end`, `val`, and + // maintains `context` and `exprAllowed`, and skips the space after + // the token, so that the next one's `start` will point at the + // right position. + + pp$9.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); + }; + + // ### Token reading + + // This is the function that is called to fetch the next token. It + // is somewhat obscure, because it works in character codes rather + // than characters, and because operator parsing has been inlined + // into it. + // + // All in the name of speed. + // + pp$9.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) { // 46 = dot '.' + this.pos += 3; + return this.finishToken(types.ellipsis) + } else { + ++this.pos; + return this.finishToken(types.dot) + } + }; + + pp$9.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$9.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; + + // exponentiation operator ** and **= + 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$9.readToken_pipe_amp = function(code) { // '|&' + var next = this.input.charCodeAt(this.pos + 1); + if (next === code) { + if (this.options.ecmaVersion >= 12) { + var next2 = this.input.charCodeAt(this.pos + 2); + if (next2 === 61) { return this.finishOp(types.assign, 3) } + } + 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$9.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$9.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)))) { + // A `-->` line comment + this.skipLineComment(3); + this.skipSpace(); + return this.nextToken() + } + return this.finishOp(types.incDec, 2) + } + if (next === 61) { return this.finishOp(types.assign, 2) } + return this.finishOp(types.plusMin, 1) + }; + + pp$9.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) { + // ` * (any, kinda silly) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 +function replaceTildes (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceTilde(comp, options) + }).join(' ') +} + +function replaceTilde (comp, options) { + var r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] + return comp.replace(r, function (_, M, m, p, pr) { + debug('tilde', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + // ~1.2 == >=1.2.0 <1.3.0 + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else if (pr) { + debug('replaceTilde pr', pr) + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } else { + // ~1.2.3 == >=1.2.3 <1.3.0 + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + + debug('tilde return', ret) + return ret + }) +} + +// ^ --> * (any, kinda silly) +// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 +// ^1.2.3 --> >=1.2.3 <2.0.0 +// ^1.2.0 --> >=1.2.0 <2.0.0 +function replaceCarets (comp, options) { + return comp.trim().split(/\s+/).map(function (comp) { + return replaceCaret(comp, options) + }).join(' ') +} + +function replaceCaret (comp, options) { + debug('caret', comp, options) + var r = options.loose ? re[t.CARETLOOSE] : re[t.CARET] + return comp.replace(r, function (_, M, m, p, pr) { + debug('caret', comp, _, M, m, p, pr) + var ret + + if (isX(M)) { + ret = '' + } else if (isX(m)) { + ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0' + } else if (isX(p)) { + if (M === '0') { + ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0' + } else { + ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0' + } + } else if (pr) { + debug('replaceCaret pr', pr) + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + '-' + pr + + ' <' + (+M + 1) + '.0.0' + } + } else { + debug('no pr') + if (M === '0') { + if (m === '0') { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + m + '.' + (+p + 1) + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + M + '.' + (+m + 1) + '.0' + } + } else { + ret = '>=' + M + '.' + m + '.' + p + + ' <' + (+M + 1) + '.0.0' + } + } + + debug('caret return', ret) + return ret + }) +} + +function replaceXRanges (comp, options) { + debug('replaceXRanges', comp, options) + return comp.split(/\s+/).map(function (comp) { + return replaceXRange(comp, options) + }).join(' ') +} + +function replaceXRange (comp, options) { + comp = comp.trim() + var r = options.loose ? re[t.XRANGELOOSE] : re[t.XRANGE] + return comp.replace(r, function (ret, gtlt, M, m, p, pr) { + debug('xRange', comp, ret, gtlt, M, m, p, pr) + var xM = isX(M) + var xm = xM || isX(m) + var xp = xm || isX(p) + var anyX = xp + + if (gtlt === '=' && anyX) { + gtlt = '' + } + + // if we're including prereleases in the match, then we need + // to fix this to -0, the lowest possible prerelease value + pr = options.includePrerelease ? '-0' : '' + + if (xM) { + if (gtlt === '>' || gtlt === '<') { + // nothing is allowed + ret = '<0.0.0-0' + } else { + // nothing is forbidden + ret = '*' + } + } else if (gtlt && anyX) { + // we know patch is an x, because we have any x at all. + // replace X with 0 + if (xm) { + m = 0 + } + p = 0 + + if (gtlt === '>') { + // >1 => >=2.0.0 + // >1.2 => >=1.3.0 + // >1.2.3 => >= 1.2.4 + gtlt = '>=' + if (xm) { + M = +M + 1 + m = 0 + p = 0 + } else { + m = +m + 1 + p = 0 + } + } else if (gtlt === '<=') { + // <=0.7.x is actually <0.8.0, since any 0.7.x should + // pass. Similarly, <=7.x is actually <8.0.0, etc. + gtlt = '<' + if (xm) { + M = +M + 1 + } else { + m = +m + 1 + } + } + + ret = gtlt + M + '.' + m + '.' + p + pr + } else if (xm) { + ret = '>=' + M + '.0.0' + pr + ' <' + (+M + 1) + '.0.0' + pr + } else if (xp) { + ret = '>=' + M + '.' + m + '.0' + pr + + ' <' + M + '.' + (+m + 1) + '.0' + pr + } + + debug('xRange return', ret) + + return ret + }) +} + +// Because * is AND-ed with everything else in the comparator, +// and '' means "any version", just remove the *s entirely. +function replaceStars (comp, options) { + debug('replaceStars', comp, options) + // Looseness is ignored here. star is always as loose as it gets! + return comp.trim().replace(re[t.STAR], '') +} + +// This function is passed to string.replace(re[t.HYPHENRANGE]) +// M, m, patch, prerelease, build +// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 +// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do +// 1.2 - 3.4 => >=1.2.0 <3.5.0 +function hyphenReplace ($0, + from, fM, fm, fp, fpr, fb, + to, tM, tm, tp, tpr, tb) { + if (isX(fM)) { + from = '' + } else if (isX(fm)) { + from = '>=' + fM + '.0.0' + } else if (isX(fp)) { + from = '>=' + fM + '.' + fm + '.0' + } else { + from = '>=' + from + } + + if (isX(tM)) { + to = '' + } else if (isX(tm)) { + to = '<' + (+tM + 1) + '.0.0' + } else if (isX(tp)) { + to = '<' + tM + '.' + (+tm + 1) + '.0' + } else if (tpr) { + to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr + } else { + to = '<=' + to + } + + return (from + ' ' + to).trim() +} + +// if ANY of the sets match ALL of its comparators, then pass +Range.prototype.test = function (version) { + if (!version) { + return false + } + + if (typeof version === 'string') { + try { + version = new SemVer(version, this.options) + } catch (er) { + return false + } + } + + for (var i = 0; i < this.set.length; i++) { + if (testSet(this.set[i], version, this.options)) { + return true + } + } + return false +} + +function testSet (set, version, options) { + for (var i = 0; i < set.length; i++) { + if (!set[i].test(version)) { + return false + } + } + + if (version.prerelease.length && !options.includePrerelease) { + // Find the set of versions that are allowed to have prereleases + // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 + // That should allow `1.2.3-pr.2` to pass. + // However, `1.2.4-alpha.notready` should NOT be allowed, + // even though it's within the range set by the comparators. + for (i = 0; i < set.length; i++) { + debug(set[i].semver) + if (set[i].semver === ANY) { + continue + } + + if (set[i].semver.prerelease.length > 0) { + var allowed = set[i].semver + if (allowed.major === version.major && + allowed.minor === version.minor && + allowed.patch === version.patch) { + return true + } + } + } + + // Version has a -pre, but it's not one of the ones we like. + return false + } + + return true +} + +exports.satisfies = satisfies +function satisfies (version, range, options) { + try { + range = new Range(range, options) + } catch (er) { + return false + } + return range.test(version) +} + +exports.maxSatisfying = maxSatisfying +function maxSatisfying (versions, range, options) { + var max = null + var maxSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!max || maxSV.compare(v) === -1) { + // compare(max, v, true) + max = v + maxSV = new SemVer(max, options) + } + } + }) + return max +} + +exports.minSatisfying = minSatisfying +function minSatisfying (versions, range, options) { + var min = null + var minSV = null + try { + var rangeObj = new Range(range, options) + } catch (er) { + return null + } + versions.forEach(function (v) { + if (rangeObj.test(v)) { + // satisfies(v, range, options) + if (!min || minSV.compare(v) === 1) { + // compare(min, v, true) + min = v + minSV = new SemVer(min, options) + } + } + }) + return min +} + +exports.minVersion = minVersion +function minVersion (range, loose) { + range = new Range(range, loose) + + var minver = new SemVer('0.0.0') + if (range.test(minver)) { + return minver + } + + minver = new SemVer('0.0.0-0') + if (range.test(minver)) { + return minver + } + + minver = null + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + comparators.forEach(function (comparator) { + // Clone to avoid manipulating the comparator's semver object. + var compver = new SemVer(comparator.semver.version) + switch (comparator.operator) { + case '>': + if (compver.prerelease.length === 0) { + compver.patch++ + } else { + compver.prerelease.push(0) + } + compver.raw = compver.format() + /* fallthrough */ + case '': + case '>=': + if (!minver || gt(minver, compver)) { + minver = compver + } + break + case '<': + case '<=': + /* Ignore maximum versions */ + break + /* istanbul ignore next */ + default: + throw new Error('Unexpected operation: ' + comparator.operator) + } + }) + } + + if (minver && range.test(minver)) { + return minver + } + + return null +} + +exports.validRange = validRange +function validRange (range, options) { + try { + // Return '*' instead of '' so that truthiness works. + // This will throw if it's invalid anyway + return new Range(range, options).range || '*' + } catch (er) { + return null + } +} + +// Determine if version is less than all the versions possible in the range +exports.ltr = ltr +function ltr (version, range, options) { + return outside(version, range, '<', options) +} + +// Determine if version is greater than all the versions possible in the range. +exports.gtr = gtr +function gtr (version, range, options) { + return outside(version, range, '>', options) +} + +exports.outside = outside +function outside (version, range, hilo, options) { + version = new SemVer(version, options) + range = new Range(range, options) + + var gtfn, ltefn, ltfn, comp, ecomp + switch (hilo) { + case '>': + gtfn = gt + ltefn = lte + ltfn = lt + comp = '>' + ecomp = '>=' + break + case '<': + gtfn = lt + ltefn = gte + ltfn = gt + comp = '<' + ecomp = '<=' + break + default: + throw new TypeError('Must provide a hilo val of "<" or ">"') + } + + // If it satisifes the range it is not outside + if (satisfies(version, range, options)) { + return false + } + + // From now on, variable terms are as if we're in "gtr" mode. + // but note that everything is flipped for the "ltr" function. + + for (var i = 0; i < range.set.length; ++i) { + var comparators = range.set[i] + + var high = null + var low = null + + comparators.forEach(function (comparator) { + if (comparator.semver === ANY) { + comparator = new Comparator('>=0.0.0') + } + high = high || comparator + low = low || comparator + if (gtfn(comparator.semver, high.semver, options)) { + high = comparator + } else if (ltfn(comparator.semver, low.semver, options)) { + low = comparator + } + }) + + // If the edge version comparator has a operator then our version + // isn't outside it + if (high.operator === comp || high.operator === ecomp) { + return false + } + + // If the lowest version comparator has an operator and our version + // is less than it then it isn't higher than the range + if ((!low.operator || low.operator === comp) && + ltefn(version, low.semver)) { + return false + } else if (low.operator === ecomp && ltfn(version, low.semver)) { + return false + } + } + return true +} + +exports.prerelease = prerelease +function prerelease (version, options) { + var parsed = parse(version, options) + return (parsed && parsed.prerelease.length) ? parsed.prerelease : null +} + +exports.intersects = intersects +function intersects (r1, r2, options) { + r1 = new Range(r1, options) + r2 = new Range(r2, options) + return r1.intersects(r2) +} + +exports.coerce = coerce +function coerce (version, options) { + if (version instanceof SemVer) { + return version + } + + if (typeof version === 'number') { + version = String(version) + } + + if (typeof version !== 'string') { + return null + } + + options = options || {} + + var match = null + if (!options.rtl) { + match = version.match(re[t.COERCE]) + } else { + // Find the right-most coercible string that does not share + // a terminus with a more left-ward coercible string. + // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' + // + // Walk through the string checking with a /g regexp + // Manually set the index so as to pick up overlapping matches. + // Stop when we get a match that ends at the string end, since no + // coercible string can be more right-ward without the same terminus. + var next + while ((next = re[t.COERCERTL].exec(version)) && + (!match || match.index + match[0].length !== version.length) + ) { + if (!match || + next.index + next[0].length !== match.index + match[0].length) { + match = next + } + re[t.COERCERTL].lastIndex = next.index + next[1].length + next[2].length + } + // leave it in a clean state + re[t.COERCERTL].lastIndex = -1 + } + + if (match === null) { + return null + } + + return parse(match[2] + + '.' + (match[3] || '0') + + '.' + (match[4] || '0'), options) +} + +}).call(this,require('_process')) +},{"_process":432}],378:[function(require,module,exports){ +'use strict'; + +const { PassThrough } = require('stream'); + +module.exports = function (/*streams...*/) { + var sources = [] + var output = new PassThrough({objectMode: true}) + + output.setMaxListeners(0) + + output.add = add + output.isEmpty = isEmpty + + output.on('unpipe', remove) + + Array.prototype.slice.call(arguments).forEach(add) + + return output + + function add (source) { + if (Array.isArray(source)) { + source.forEach(add) + return this + } + + sources.push(source); + source.once('end', remove.bind(null, source)) + source.once('error', output.emit.bind(output, 'error')) + source.pipe(output, {end: false}) + return this + } + + function isEmpty () { + return sources.length == 0; + } + + function remove (source) { + sources = sources.filter(function (it) { return it !== source }) + if (!sources.length && output.readable) { output.end() } + } +} + +},{"stream":503}],379:[function(require,module,exports){ +(function (process){ +'use strict' +/* + * merge2 + * https://github.com/teambition/merge2 + * + * Copyright (c) 2014-2016 Teambition + * Licensed under the MIT license. + */ +const Stream = require('stream') +const PassThrough = Stream.PassThrough +const slice = Array.prototype.slice + +module.exports = merge2 + +function merge2 () { + const streamsQueue = [] + let merging = false + const args = slice.call(arguments) + let options = args[args.length - 1] + + if (options && !Array.isArray(options) && options.pipe == null) args.pop() + else options = {} + + const doEnd = options.end !== false + if (options.objectMode == null) options.objectMode = true + if (options.highWaterMark == null) options.highWaterMark = 64 * 1024 + const mergedStream = PassThrough(options) + + function addStream () { + for (let i = 0, len = arguments.length; i < len; i++) { + streamsQueue.push(pauseStreams(arguments[i], options)) + } + mergeStream() + return this + } + + function mergeStream () { + if (merging) return + merging = true + + let streams = streamsQueue.shift() + if (!streams) { + process.nextTick(endStream) + return + } + if (!Array.isArray(streams)) streams = [streams] + + let pipesCount = streams.length + 1 + + function next () { + if (--pipesCount > 0) return + merging = false + mergeStream() + } + + function pipe (stream) { + function onend () { + stream.removeListener('merge2UnpipeEnd', onend) + stream.removeListener('end', onend) + next() + } + // skip ended stream + if (stream._readableState.endEmitted) return next() + + stream.on('merge2UnpipeEnd', onend) + stream.on('end', onend) + stream.pipe(mergedStream, { end: false }) + // compatible for old stream + stream.resume() + } + + for (let i = 0; i < streams.length; i++) pipe(streams[i]) + + next() + } + + function endStream () { + merging = false + // emit 'queueDrain' when all streams merged. + mergedStream.emit('queueDrain') + return doEnd && mergedStream.end() + } + + mergedStream.setMaxListeners(0) + mergedStream.add = addStream + mergedStream.on('unpipe', function (stream) { + stream.emit('merge2UnpipeEnd') + }) + + if (args.length) addStream.apply(null, args) + return mergedStream +} + +// check and pause streams for pipe. +function pauseStreams (streams, options) { + if (!Array.isArray(streams)) { + // Backwards-compat with old-style streams + if (!streams._readableState && streams.pipe) streams = streams.pipe(PassThrough(options)) + if (!streams._readableState || !streams.pause || !streams.pipe) { + throw new Error('Only readable stream can be merged.') + } + streams.pause() + } else { + for (let i = 0, len = streams.length; i < len; i++) streams[i] = pauseStreams(streams[i], options) + } + return streams +} + +}).call(this,require('_process')) +},{"_process":432,"stream":503}],380:[function(require,module,exports){ +(function (process){ +var path = require('path'); +var fs = require('fs'); + +function Mime() { + // Map of extension -> mime type + this.types = Object.create(null); + + // Map of mime type -> extension + this.extensions = Object.create(null); +} + +/** + * Define mimetype -> extension mappings. Each key is a mime-type that maps + * to an array of extensions associated with the type. The first extension is + * used as the default extension for the type. + * + * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']}); + * + * @param map (Object) type definitions + */ +Mime.prototype.define = function (map) { + for (var type in map) { + var exts = map[type]; + for (var i = 0; i < exts.length; i++) { + if (process.env.DEBUG_MIME && this.types[exts[i]]) { + console.warn((this._loading || "define()").replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' + + this.types[exts[i]] + ' to ' + type); + } + + this.types[exts[i]] = type; + } + + // Default extension is the first one we encounter + if (!this.extensions[type]) { + this.extensions[type] = exts[0]; + } + } +}; + +/** + * Load an Apache2-style ".types" file + * + * This may be called multiple times (it's expected). Where files declare + * overlapping types/extensions, the last file wins. + * + * @param file (String) path of file to load. + */ +Mime.prototype.load = function(file) { + this._loading = file; + // Read file and split into lines + var map = {}, + content = fs.readFileSync(file, 'ascii'), + lines = content.split(/[\r\n]+/); + + lines.forEach(function(line) { + // Clean up whitespace/comments, and split into fields + var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/); + map[fields.shift()] = fields; + }); + + this.define(map); + + this._loading = null; +}; + +/** + * Lookup a mime type based on extension + */ +Mime.prototype.lookup = function(path, fallback) { + var ext = path.replace(/^.*[\.\/\\]/, '').toLowerCase(); + + return this.types[ext] || fallback || this.default_type; +}; + +/** + * Return file extension associated with a mime type + */ +Mime.prototype.extension = function(mimeType) { + var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase(); + return this.extensions[type]; +}; + +// Default instance +var mime = new Mime(); + +// Define built-in types +mime.define(require('./types.json')); + +// Default type +mime.default_type = mime.lookup('bin'); + +// +// Additional API specific to the default instance +// + +mime.Mime = Mime; + +/** + * Lookup a charset based on mime type. + */ +mime.charsets = { + lookup: function(mimeType, fallback) { + // Assume text types are utf8 + return (/^text\/|^application\/(javascript|json)/).test(mimeType) ? 'UTF-8' : fallback; + } +}; + +module.exports = mime; + +}).call(this,require('_process')) +},{"./types.json":381,"_process":432,"fs":296,"path":402}],381:[function(require,module,exports){ +module.exports={"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomsvc+xml":["atomsvc"],"application/bdoc":["bdoc"],"application/ccxml+xml":["ccxml"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["ecma"],"application/emma+xml":["emma"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/font-tdpfr":["pfr"],"application/font-woff":[],"application/font-woff2":[],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/patch-ops-error+xml":["xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/prs.cww":["cww"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/vnd.3gpp.pic-bw-large":["plb"],"application/vnd.3gpp.pic-bw-small":["psb"],"application/vnd.3gpp.pic-bw-var":["pvb"],"application/vnd.3gpp2.tcap":["tcap"],"application/vnd.3m.post-it-notes":["pwn"],"application/vnd.accpac.simply.aso":["aso"],"application/vnd.accpac.simply.imp":["imp"],"application/vnd.acucobol":["acu"],"application/vnd.acucorp":["atc","acutc"],"application/vnd.adobe.air-application-installer-package+zip":["air"],"application/vnd.adobe.formscentral.fcdt":["fcdt"],"application/vnd.adobe.fxp":["fxp","fxpl"],"application/vnd.adobe.xdp+xml":["xdp"],"application/vnd.adobe.xfdf":["xfdf"],"application/vnd.ahead.space":["ahead"],"application/vnd.airzip.filesecure.azf":["azf"],"application/vnd.airzip.filesecure.azs":["azs"],"application/vnd.amazon.ebook":["azw"],"application/vnd.americandynamics.acc":["acc"],"application/vnd.amiga.ami":["ami"],"application/vnd.android.package-archive":["apk"],"application/vnd.anser-web-certificate-issue-initiation":["cii"],"application/vnd.anser-web-funds-transfer-initiation":["fti"],"application/vnd.antix.game-component":["atx"],"application/vnd.apple.installer+xml":["mpkg"],"application/vnd.apple.mpegurl":["m3u8"],"application/vnd.apple.pkpass":["pkpass"],"application/vnd.aristanetworks.swi":["swi"],"application/vnd.astraea-software.iota":["iota"],"application/vnd.audiograph":["aep"],"application/vnd.blueice.multipass":["mpm"],"application/vnd.bmi":["bmi"],"application/vnd.businessobjects":["rep"],"application/vnd.chemdraw+xml":["cdxml"],"application/vnd.chipnuts.karaoke-mmd":["mmd"],"application/vnd.cinderella":["cdy"],"application/vnd.claymore":["cla"],"application/vnd.cloanto.rp9":["rp9"],"application/vnd.clonk.c4group":["c4g","c4d","c4f","c4p","c4u"],"application/vnd.cluetrust.cartomobile-config":["c11amc"],"application/vnd.cluetrust.cartomobile-config-pkg":["c11amz"],"application/vnd.commonspace":["csp"],"application/vnd.contact.cmsg":["cdbcmsg"],"application/vnd.cosmocaller":["cmc"],"application/vnd.crick.clicker":["clkx"],"application/vnd.crick.clicker.keyboard":["clkk"],"application/vnd.crick.clicker.palette":["clkp"],"application/vnd.crick.clicker.template":["clkt"],"application/vnd.crick.clicker.wordbank":["clkw"],"application/vnd.criticaltools.wbs+xml":["wbs"],"application/vnd.ctc-posml":["pml"],"application/vnd.cups-ppd":["ppd"],"application/vnd.curl.car":["car"],"application/vnd.curl.pcurl":["pcurl"],"application/vnd.dart":["dart"],"application/vnd.data-vision.rdz":["rdz"],"application/vnd.dece.data":["uvf","uvvf","uvd","uvvd"],"application/vnd.dece.ttml+xml":["uvt","uvvt"],"application/vnd.dece.unspecified":["uvx","uvvx"],"application/vnd.dece.zip":["uvz","uvvz"],"application/vnd.denovo.fcselayout-link":["fe_launch"],"application/vnd.dna":["dna"],"application/vnd.dolby.mlp":["mlp"],"application/vnd.dpgraph":["dpg"],"application/vnd.dreamfactory":["dfac"],"application/vnd.ds-keypoint":["kpxx"],"application/vnd.dvb.ait":["ait"],"application/vnd.dvb.service":["svc"],"application/vnd.dynageo":["geo"],"application/vnd.ecowin.chart":["mag"],"application/vnd.enliven":["nml"],"application/vnd.epson.esf":["esf"],"application/vnd.epson.msf":["msf"],"application/vnd.epson.quickanime":["qam"],"application/vnd.epson.salt":["slt"],"application/vnd.epson.ssf":["ssf"],"application/vnd.eszigno3+xml":["es3","et3"],"application/vnd.ezpix-album":["ez2"],"application/vnd.ezpix-package":["ez3"],"application/vnd.fdf":["fdf"],"application/vnd.fdsn.mseed":["mseed"],"application/vnd.fdsn.seed":["seed","dataless"],"application/vnd.flographit":["gph"],"application/vnd.fluxtime.clip":["ftc"],"application/vnd.framemaker":["fm","frame","maker","book"],"application/vnd.frogans.fnc":["fnc"],"application/vnd.frogans.ltf":["ltf"],"application/vnd.fsc.weblaunch":["fsc"],"application/vnd.fujitsu.oasys":["oas"],"application/vnd.fujitsu.oasys2":["oa2"],"application/vnd.fujitsu.oasys3":["oa3"],"application/vnd.fujitsu.oasysgp":["fg5"],"application/vnd.fujitsu.oasysprs":["bh2"],"application/vnd.fujixerox.ddd":["ddd"],"application/vnd.fujixerox.docuworks":["xdw"],"application/vnd.fujixerox.docuworks.binder":["xbd"],"application/vnd.fuzzysheet":["fzs"],"application/vnd.genomatix.tuxedo":["txd"],"application/vnd.geogebra.file":["ggb"],"application/vnd.geogebra.tool":["ggt"],"application/vnd.geometry-explorer":["gex","gre"],"application/vnd.geonext":["gxt"],"application/vnd.geoplan":["g2w"],"application/vnd.geospace":["g3w"],"application/vnd.gmx":["gmx"],"application/vnd.google-apps.document":["gdoc"],"application/vnd.google-apps.presentation":["gslides"],"application/vnd.google-apps.spreadsheet":["gsheet"],"application/vnd.google-earth.kml+xml":["kml"],"application/vnd.google-earth.kmz":["kmz"],"application/vnd.grafeq":["gqf","gqs"],"application/vnd.groove-account":["gac"],"application/vnd.groove-help":["ghf"],"application/vnd.groove-identity-message":["gim"],"application/vnd.groove-injector":["grv"],"application/vnd.groove-tool-message":["gtm"],"application/vnd.groove-tool-template":["tpl"],"application/vnd.groove-vcard":["vcg"],"application/vnd.hal+xml":["hal"],"application/vnd.handheld-entertainment+xml":["zmm"],"application/vnd.hbci":["hbci"],"application/vnd.hhe.lesson-player":["les"],"application/vnd.hp-hpgl":["hpgl"],"application/vnd.hp-hpid":["hpid"],"application/vnd.hp-hps":["hps"],"application/vnd.hp-jlyt":["jlt"],"application/vnd.hp-pcl":["pcl"],"application/vnd.hp-pclxl":["pclxl"],"application/vnd.hydrostatix.sof-data":["sfd-hdstx"],"application/vnd.ibm.minipay":["mpy"],"application/vnd.ibm.modcap":["afp","listafp","list3820"],"application/vnd.ibm.rights-management":["irm"],"application/vnd.ibm.secure-container":["sc"],"application/vnd.iccprofile":["icc","icm"],"application/vnd.igloader":["igl"],"application/vnd.immervision-ivp":["ivp"],"application/vnd.immervision-ivu":["ivu"],"application/vnd.insors.igm":["igm"],"application/vnd.intercon.formnet":["xpw","xpx"],"application/vnd.intergeo":["i2g"],"application/vnd.intu.qbo":["qbo"],"application/vnd.intu.qfx":["qfx"],"application/vnd.ipunplugged.rcprofile":["rcprofile"],"application/vnd.irepository.package+xml":["irp"],"application/vnd.is-xpr":["xpr"],"application/vnd.isac.fcs":["fcs"],"application/vnd.jam":["jam"],"application/vnd.jcp.javame.midlet-rms":["rms"],"application/vnd.jisp":["jisp"],"application/vnd.joost.joda-archive":["joda"],"application/vnd.kahootz":["ktz","ktr"],"application/vnd.kde.karbon":["karbon"],"application/vnd.kde.kchart":["chrt"],"application/vnd.kde.kformula":["kfo"],"application/vnd.kde.kivio":["flw"],"application/vnd.kde.kontour":["kon"],"application/vnd.kde.kpresenter":["kpr","kpt"],"application/vnd.kde.kspread":["ksp"],"application/vnd.kde.kword":["kwd","kwt"],"application/vnd.kenameaapp":["htke"],"application/vnd.kidspiration":["kia"],"application/vnd.kinar":["kne","knp"],"application/vnd.koan":["skp","skd","skt","skm"],"application/vnd.kodak-descriptor":["sse"],"application/vnd.las.las+xml":["lasxml"],"application/vnd.llamagraphics.life-balance.desktop":["lbd"],"application/vnd.llamagraphics.life-balance.exchange+xml":["lbe"],"application/vnd.lotus-1-2-3":["123"],"application/vnd.lotus-approach":["apr"],"application/vnd.lotus-freelance":["pre"],"application/vnd.lotus-notes":["nsf"],"application/vnd.lotus-organizer":["org"],"application/vnd.lotus-screencam":["scm"],"application/vnd.lotus-wordpro":["lwp"],"application/vnd.macports.portpkg":["portpkg"],"application/vnd.mcd":["mcd"],"application/vnd.medcalcdata":["mc1"],"application/vnd.mediastation.cdkey":["cdkey"],"application/vnd.mfer":["mwf"],"application/vnd.mfmp":["mfm"],"application/vnd.micrografx.flo":["flo"],"application/vnd.micrografx.igx":["igx"],"application/vnd.mif":["mif"],"application/vnd.mobius.daf":["daf"],"application/vnd.mobius.dis":["dis"],"application/vnd.mobius.mbk":["mbk"],"application/vnd.mobius.mqy":["mqy"],"application/vnd.mobius.msl":["msl"],"application/vnd.mobius.plc":["plc"],"application/vnd.mobius.txf":["txf"],"application/vnd.mophun.application":["mpn"],"application/vnd.mophun.certificate":["mpc"],"application/vnd.mozilla.xul+xml":["xul"],"application/vnd.ms-artgalry":["cil"],"application/vnd.ms-cab-compressed":["cab"],"application/vnd.ms-excel":["xls","xlm","xla","xlc","xlt","xlw"],"application/vnd.ms-excel.addin.macroenabled.12":["xlam"],"application/vnd.ms-excel.sheet.binary.macroenabled.12":["xlsb"],"application/vnd.ms-excel.sheet.macroenabled.12":["xlsm"],"application/vnd.ms-excel.template.macroenabled.12":["xltm"],"application/vnd.ms-fontobject":["eot"],"application/vnd.ms-htmlhelp":["chm"],"application/vnd.ms-ims":["ims"],"application/vnd.ms-lrm":["lrm"],"application/vnd.ms-officetheme":["thmx"],"application/vnd.ms-outlook":["msg"],"application/vnd.ms-pki.seccat":["cat"],"application/vnd.ms-pki.stl":["stl"],"application/vnd.ms-powerpoint":["ppt","pps","pot"],"application/vnd.ms-powerpoint.addin.macroenabled.12":["ppam"],"application/vnd.ms-powerpoint.presentation.macroenabled.12":["pptm"],"application/vnd.ms-powerpoint.slide.macroenabled.12":["sldm"],"application/vnd.ms-powerpoint.slideshow.macroenabled.12":["ppsm"],"application/vnd.ms-powerpoint.template.macroenabled.12":["potm"],"application/vnd.ms-project":["mpp","mpt"],"application/vnd.ms-word.document.macroenabled.12":["docm"],"application/vnd.ms-word.template.macroenabled.12":["dotm"],"application/vnd.ms-works":["wps","wks","wcm","wdb"],"application/vnd.ms-wpl":["wpl"],"application/vnd.ms-xpsdocument":["xps"],"application/vnd.mseq":["mseq"],"application/vnd.musician":["mus"],"application/vnd.muvee.style":["msty"],"application/vnd.mynfc":["taglet"],"application/vnd.neurolanguage.nlu":["nlu"],"application/vnd.nitf":["ntf","nitf"],"application/vnd.noblenet-directory":["nnd"],"application/vnd.noblenet-sealer":["nns"],"application/vnd.noblenet-web":["nnw"],"application/vnd.nokia.n-gage.data":["ngdat"],"application/vnd.nokia.n-gage.symbian.install":["n-gage"],"application/vnd.nokia.radio-preset":["rpst"],"application/vnd.nokia.radio-presets":["rpss"],"application/vnd.novadigm.edm":["edm"],"application/vnd.novadigm.edx":["edx"],"application/vnd.novadigm.ext":["ext"],"application/vnd.oasis.opendocument.chart":["odc"],"application/vnd.oasis.opendocument.chart-template":["otc"],"application/vnd.oasis.opendocument.database":["odb"],"application/vnd.oasis.opendocument.formula":["odf"],"application/vnd.oasis.opendocument.formula-template":["odft"],"application/vnd.oasis.opendocument.graphics":["odg"],"application/vnd.oasis.opendocument.graphics-template":["otg"],"application/vnd.oasis.opendocument.image":["odi"],"application/vnd.oasis.opendocument.image-template":["oti"],"application/vnd.oasis.opendocument.presentation":["odp"],"application/vnd.oasis.opendocument.presentation-template":["otp"],"application/vnd.oasis.opendocument.spreadsheet":["ods"],"application/vnd.oasis.opendocument.spreadsheet-template":["ots"],"application/vnd.oasis.opendocument.text":["odt"],"application/vnd.oasis.opendocument.text-master":["odm"],"application/vnd.oasis.opendocument.text-template":["ott"],"application/vnd.oasis.opendocument.text-web":["oth"],"application/vnd.olpc-sugar":["xo"],"application/vnd.oma.dd2+xml":["dd2"],"application/vnd.openofficeorg.extension":["oxt"],"application/vnd.openxmlformats-officedocument.presentationml.presentation":["pptx"],"application/vnd.openxmlformats-officedocument.presentationml.slide":["sldx"],"application/vnd.openxmlformats-officedocument.presentationml.slideshow":["ppsx"],"application/vnd.openxmlformats-officedocument.presentationml.template":["potx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":["xlsx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.template":["xltx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.document":["docx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.template":["dotx"],"application/vnd.osgeo.mapguide.package":["mgp"],"application/vnd.osgi.dp":["dp"],"application/vnd.osgi.subsystem":["esa"],"application/vnd.palm":["pdb","pqa","oprc"],"application/vnd.pawaafile":["paw"],"application/vnd.pg.format":["str"],"application/vnd.pg.osasli":["ei6"],"application/vnd.picsel":["efif"],"application/vnd.pmi.widget":["wg"],"application/vnd.pocketlearn":["plf"],"application/vnd.powerbuilder6":["pbd"],"application/vnd.previewsystems.box":["box"],"application/vnd.proteus.magazine":["mgz"],"application/vnd.publishare-delta-tree":["qps"],"application/vnd.pvi.ptid1":["ptid"],"application/vnd.quark.quarkxpress":["qxd","qxt","qwd","qwt","qxl","qxb"],"application/vnd.realvnc.bed":["bed"],"application/vnd.recordare.musicxml":["mxl"],"application/vnd.recordare.musicxml+xml":["musicxml"],"application/vnd.rig.cryptonote":["cryptonote"],"application/vnd.rim.cod":["cod"],"application/vnd.rn-realmedia":["rm"],"application/vnd.rn-realmedia-vbr":["rmvb"],"application/vnd.route66.link66+xml":["link66"],"application/vnd.sailingtracker.track":["st"],"application/vnd.seemail":["see"],"application/vnd.sema":["sema"],"application/vnd.semd":["semd"],"application/vnd.semf":["semf"],"application/vnd.shana.informed.formdata":["ifm"],"application/vnd.shana.informed.formtemplate":["itp"],"application/vnd.shana.informed.interchange":["iif"],"application/vnd.shana.informed.package":["ipk"],"application/vnd.simtech-mindmapper":["twd","twds"],"application/vnd.smaf":["mmf"],"application/vnd.smart.teacher":["teacher"],"application/vnd.solent.sdkm+xml":["sdkm","sdkd"],"application/vnd.spotfire.dxp":["dxp"],"application/vnd.spotfire.sfs":["sfs"],"application/vnd.stardivision.calc":["sdc"],"application/vnd.stardivision.draw":["sda"],"application/vnd.stardivision.impress":["sdd"],"application/vnd.stardivision.math":["smf"],"application/vnd.stardivision.writer":["sdw","vor"],"application/vnd.stardivision.writer-global":["sgl"],"application/vnd.stepmania.package":["smzip"],"application/vnd.stepmania.stepchart":["sm"],"application/vnd.sun.wadl+xml":["wadl"],"application/vnd.sun.xml.calc":["sxc"],"application/vnd.sun.xml.calc.template":["stc"],"application/vnd.sun.xml.draw":["sxd"],"application/vnd.sun.xml.draw.template":["std"],"application/vnd.sun.xml.impress":["sxi"],"application/vnd.sun.xml.impress.template":["sti"],"application/vnd.sun.xml.math":["sxm"],"application/vnd.sun.xml.writer":["sxw"],"application/vnd.sun.xml.writer.global":["sxg"],"application/vnd.sun.xml.writer.template":["stw"],"application/vnd.sus-calendar":["sus","susp"],"application/vnd.svd":["svd"],"application/vnd.symbian.install":["sis","sisx"],"application/vnd.syncml+xml":["xsm"],"application/vnd.syncml.dm+wbxml":["bdm"],"application/vnd.syncml.dm+xml":["xdm"],"application/vnd.tao.intent-module-archive":["tao"],"application/vnd.tcpdump.pcap":["pcap","cap","dmp"],"application/vnd.tmobile-livetv":["tmo"],"application/vnd.trid.tpt":["tpt"],"application/vnd.triscape.mxs":["mxs"],"application/vnd.trueapp":["tra"],"application/vnd.ufdl":["ufd","ufdl"],"application/vnd.uiq.theme":["utz"],"application/vnd.umajin":["umj"],"application/vnd.unity":["unityweb"],"application/vnd.uoml+xml":["uoml"],"application/vnd.vcx":["vcx"],"application/vnd.visio":["vsd","vst","vss","vsw"],"application/vnd.visionary":["vis"],"application/vnd.vsf":["vsf"],"application/vnd.wap.wbxml":["wbxml"],"application/vnd.wap.wmlc":["wmlc"],"application/vnd.wap.wmlscriptc":["wmlsc"],"application/vnd.webturbo":["wtb"],"application/vnd.wolfram.player":["nbp"],"application/vnd.wordperfect":["wpd"],"application/vnd.wqd":["wqd"],"application/vnd.wt.stf":["stf"],"application/vnd.xara":["xar"],"application/vnd.xfdl":["xfdl"],"application/vnd.yamaha.hv-dic":["hvd"],"application/vnd.yamaha.hv-script":["hvs"],"application/vnd.yamaha.hv-voice":["hvp"],"application/vnd.yamaha.openscoreformat":["osf"],"application/vnd.yamaha.openscoreformat.osfpvg+xml":["osfpvg"],"application/vnd.yamaha.smaf-audio":["saf"],"application/vnd.yamaha.smaf-phrase":["spf"],"application/vnd.yellowriver-custom-menu":["cmp"],"application/vnd.zul":["zir","zirz"],"application/vnd.zzazz.deck+xml":["zaz"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/x-7z-compressed":["7z"],"application/x-abiword":["abw"],"application/x-ace-compressed":["ace"],"application/x-apple-diskimage":[],"application/x-arj":["arj"],"application/x-authorware-bin":["aab","x32","u32","vox"],"application/x-authorware-map":["aam"],"application/x-authorware-seg":["aas"],"application/x-bcpio":["bcpio"],"application/x-bdoc":[],"application/x-bittorrent":["torrent"],"application/x-blorb":["blb","blorb"],"application/x-bzip":["bz"],"application/x-bzip2":["bz2","boz"],"application/x-cbr":["cbr","cba","cbt","cbz","cb7"],"application/x-cdlink":["vcd"],"application/x-cfs-compressed":["cfs"],"application/x-chat":["chat"],"application/x-chess-pgn":["pgn"],"application/x-chrome-extension":["crx"],"application/x-cocoa":["cco"],"application/x-conference":["nsc"],"application/x-cpio":["cpio"],"application/x-csh":["csh"],"application/x-debian-package":["udeb"],"application/x-dgc-compressed":["dgc"],"application/x-director":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"],"application/x-doom":["wad"],"application/x-dtbncx+xml":["ncx"],"application/x-dtbook+xml":["dtb"],"application/x-dtbresource+xml":["res"],"application/x-dvi":["dvi"],"application/x-envoy":["evy"],"application/x-eva":["eva"],"application/x-font-bdf":["bdf"],"application/x-font-ghostscript":["gsf"],"application/x-font-linux-psf":["psf"],"application/x-font-pcf":["pcf"],"application/x-font-snf":["snf"],"application/x-font-type1":["pfa","pfb","pfm","afm"],"application/x-freearc":["arc"],"application/x-futuresplash":["spl"],"application/x-gca-compressed":["gca"],"application/x-glulx":["ulx"],"application/x-gnumeric":["gnumeric"],"application/x-gramps-xml":["gramps"],"application/x-gtar":["gtar"],"application/x-hdf":["hdf"],"application/x-httpd-php":["php"],"application/x-install-instructions":["install"],"application/x-iso9660-image":[],"application/x-java-archive-diff":["jardiff"],"application/x-java-jnlp-file":["jnlp"],"application/x-latex":["latex"],"application/x-lua-bytecode":["luac"],"application/x-lzh-compressed":["lzh","lha"],"application/x-makeself":["run"],"application/x-mie":["mie"],"application/x-mobipocket-ebook":["prc","mobi"],"application/x-ms-application":["application"],"application/x-ms-shortcut":["lnk"],"application/x-ms-wmd":["wmd"],"application/x-ms-wmz":["wmz"],"application/x-ms-xbap":["xbap"],"application/x-msaccess":["mdb"],"application/x-msbinder":["obd"],"application/x-mscardfile":["crd"],"application/x-msclip":["clp"],"application/x-msdos-program":[],"application/x-msdownload":["com","bat"],"application/x-msmediaview":["mvb","m13","m14"],"application/x-msmetafile":["wmf","emf","emz"],"application/x-msmoney":["mny"],"application/x-mspublisher":["pub"],"application/x-msschedule":["scd"],"application/x-msterminal":["trm"],"application/x-mswrite":["wri"],"application/x-netcdf":["nc","cdf"],"application/x-ns-proxy-autoconfig":["pac"],"application/x-nzb":["nzb"],"application/x-perl":["pl","pm"],"application/x-pilot":[],"application/x-pkcs12":["p12","pfx"],"application/x-pkcs7-certificates":["p7b","spc"],"application/x-pkcs7-certreqresp":["p7r"],"application/x-rar-compressed":["rar"],"application/x-redhat-package-manager":["rpm"],"application/x-research-info-systems":["ris"],"application/x-sea":["sea"],"application/x-sh":["sh"],"application/x-shar":["shar"],"application/x-shockwave-flash":["swf"],"application/x-silverlight-app":["xap"],"application/x-sql":["sql"],"application/x-stuffit":["sit"],"application/x-stuffitx":["sitx"],"application/x-subrip":["srt"],"application/x-sv4cpio":["sv4cpio"],"application/x-sv4crc":["sv4crc"],"application/x-t3vm-image":["t3"],"application/x-tads":["gam"],"application/x-tar":["tar"],"application/x-tcl":["tcl","tk"],"application/x-tex":["tex"],"application/x-tex-tfm":["tfm"],"application/x-texinfo":["texinfo","texi"],"application/x-tgif":["obj"],"application/x-ustar":["ustar"],"application/x-virtualbox-hdd":["hdd"],"application/x-virtualbox-ova":["ova"],"application/x-virtualbox-ovf":["ovf"],"application/x-virtualbox-vbox":["vbox"],"application/x-virtualbox-vbox-extpack":["vbox-extpack"],"application/x-virtualbox-vdi":["vdi"],"application/x-virtualbox-vhd":["vhd"],"application/x-virtualbox-vmdk":["vmdk"],"application/x-wais-source":["src"],"application/x-web-app-manifest+json":["webapp"],"application/x-x509-ca-cert":["der","crt","pem"],"application/x-xfig":["fig"],"application/x-xliff+xml":["xlf"],"application/x-xpinstall":["xpi"],"application/x-xz":["xz"],"application/x-zmachine":["z1","z2","z3","z4","z5","z6","z7","z8"],"application/xaml+xml":["xaml"],"application/xcap-diff+xml":["xdf"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":[],"audio/adpcm":["adp"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mp3":[],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/vnd.dece.audio":["uva","uvva"],"audio/vnd.digital-winds":["eol"],"audio/vnd.dra":["dra"],"audio/vnd.dts":["dts"],"audio/vnd.dts.hd":["dtshd"],"audio/vnd.lucent.voice":["lvp"],"audio/vnd.ms-playready.media.pya":["pya"],"audio/vnd.nuera.ecelp4800":["ecelp4800"],"audio/vnd.nuera.ecelp7470":["ecelp7470"],"audio/vnd.nuera.ecelp9600":["ecelp9600"],"audio/vnd.rip":["rip"],"audio/wav":["wav"],"audio/wave":[],"audio/webm":["weba"],"audio/x-aac":["aac"],"audio/x-aiff":["aif","aiff","aifc"],"audio/x-caf":["caf"],"audio/x-flac":["flac"],"audio/x-m4a":[],"audio/x-matroska":["mka"],"audio/x-mpegurl":["m3u"],"audio/x-ms-wax":["wax"],"audio/x-ms-wma":["wma"],"audio/x-pn-realaudio":["ram","ra"],"audio/x-pn-realaudio-plugin":["rmp"],"audio/x-realaudio":[],"audio/x-wav":[],"audio/xm":["xm"],"chemical/x-cdx":["cdx"],"chemical/x-cif":["cif"],"chemical/x-cmdf":["cmdf"],"chemical/x-cml":["cml"],"chemical/x-csml":["csml"],"chemical/x-xyz":["xyz"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/apng":["apng"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/g3fax":["g3"],"image/gif":["gif"],"image/ief":["ief"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/ktx":["ktx"],"image/png":["png"],"image/prs.btif":["btif"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/tiff":["tiff","tif"],"image/vnd.adobe.photoshop":["psd"],"image/vnd.dece.graphic":["uvi","uvvi","uvg","uvvg"],"image/vnd.djvu":["djvu","djv"],"image/vnd.dvb.subtitle":[],"image/vnd.dwg":["dwg"],"image/vnd.dxf":["dxf"],"image/vnd.fastbidsheet":["fbs"],"image/vnd.fpx":["fpx"],"image/vnd.fst":["fst"],"image/vnd.fujixerox.edmics-mmr":["mmr"],"image/vnd.fujixerox.edmics-rlc":["rlc"],"image/vnd.ms-modi":["mdi"],"image/vnd.ms-photo":["wdp"],"image/vnd.net-fpx":["npx"],"image/vnd.wap.wbmp":["wbmp"],"image/vnd.xiff":["xif"],"image/webp":["webp"],"image/x-3ds":["3ds"],"image/x-cmu-raster":["ras"],"image/x-cmx":["cmx"],"image/x-freehand":["fh","fhc","fh4","fh5","fh7"],"image/x-icon":["ico"],"image/x-jng":["jng"],"image/x-mrsid-image":["sid"],"image/x-ms-bmp":[],"image/x-pcx":["pcx"],"image/x-pict":["pic","pct"],"image/x-portable-anymap":["pnm"],"image/x-portable-bitmap":["pbm"],"image/x-portable-graymap":["pgm"],"image/x-portable-pixmap":["ppm"],"image/x-rgb":["rgb"],"image/x-tga":["tga"],"image/x-xbitmap":["xbm"],"image/x-xpixmap":["xpm"],"image/x-xwindowdump":["xwd"],"message/rfc822":["eml","mime"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/vnd.collada+xml":["dae"],"model/vnd.dwf":["dwf"],"model/vnd.gdl":["gdl"],"model/vnd.gtw":["gtw"],"model/vnd.mts":["mts"],"model/vnd.vtu":["vtu"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["x3db","x3dbz"],"model/x3d+vrml":["x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/hjson":["hjson"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/prs.lines.tag":["dsc"],"text/richtext":["rtx"],"text/rtf":[],"text/sgml":["sgml","sgm"],"text/slim":["slim","slm"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vnd.curl":["curl"],"text/vnd.curl.dcurl":["dcurl"],"text/vnd.curl.mcurl":["mcurl"],"text/vnd.curl.scurl":["scurl"],"text/vnd.dvb.subtitle":["sub"],"text/vnd.fly":["fly"],"text/vnd.fmi.flexstor":["flx"],"text/vnd.graphviz":["gv"],"text/vnd.in3d.3dml":["3dml"],"text/vnd.in3d.spot":["spot"],"text/vnd.sun.j2me.app-descriptor":["jad"],"text/vnd.wap.wml":["wml"],"text/vnd.wap.wmlscript":["wmls"],"text/vtt":["vtt"],"text/x-asm":["s","asm"],"text/x-c":["c","cc","cxx","cpp","h","hh","dic"],"text/x-component":["htc"],"text/x-fortran":["f","for","f77","f90"],"text/x-handlebars-template":["hbs"],"text/x-java-source":["java"],"text/x-lua":["lua"],"text/x-markdown":["mkd"],"text/x-nfo":["nfo"],"text/x-opml":["opml"],"text/x-org":[],"text/x-pascal":["p","pas"],"text/x-processing":["pde"],"text/x-sass":["sass"],"text/x-scss":["scss"],"text/x-setext":["etx"],"text/x-sfv":["sfv"],"text/x-suse-ymp":["ymp"],"text/x-uuencode":["uu"],"text/x-vcalendar":["vcs"],"text/x-vcard":["vcf"],"text/xml":[],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/jpeg":["jpgv"],"video/jpm":["jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/vnd.dece.hd":["uvh","uvvh"],"video/vnd.dece.mobile":["uvm","uvvm"],"video/vnd.dece.pd":["uvp","uvvp"],"video/vnd.dece.sd":["uvs","uvvs"],"video/vnd.dece.video":["uvv","uvvv"],"video/vnd.dvb.file":["dvb"],"video/vnd.fvt":["fvt"],"video/vnd.mpegurl":["mxu","m4u"],"video/vnd.ms-playready.media.pyv":["pyv"],"video/vnd.uvvu.mp4":["uvu","uvvu"],"video/vnd.vivo":["viv"],"video/webm":["webm"],"video/x-f4v":["f4v"],"video/x-fli":["fli"],"video/x-flv":["flv"],"video/x-m4v":["m4v"],"video/x-matroska":["mkv","mk3d","mks"],"video/x-mng":["mng"],"video/x-ms-asf":["asf","asx"],"video/x-ms-vob":["vob"],"video/x-ms-wm":["wm"],"video/x-ms-wmv":["wmv"],"video/x-ms-wmx":["wmx"],"video/x-ms-wvx":["wvx"],"video/x-msvideo":["avi"],"video/x-sgi-movie":["movie"],"video/x-smv":["smv"],"x-conference/x-cooltalk":["ice"]} +},{}],382:[function(require,module,exports){ +'use strict'; + +const mimicFn = (to, from) => { + for (const prop of Reflect.ownKeys(from)) { + Object.defineProperty(to, prop, Object.getOwnPropertyDescriptor(from, prop)); + } + + return to; +}; + +module.exports = mimicFn; +// TODO: Remove this for the next major release +module.exports.default = mimicFn; + +},{}],383:[function(require,module,exports){ +module.exports = minimatch +minimatch.Minimatch = Minimatch + +var path = { sep: '/' } +try { + path = require('path') +} catch (er) {} + +var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {} +var expand = require('brace-expansion') + +var plTypes = { + '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, + '?': { open: '(?:', close: ')?' }, + '+': { open: '(?:', close: ')+' }, + '*': { open: '(?:', close: ')*' }, + '@': { open: '(?:', close: ')' } +} + +// any single thing other than / +// don't need to escape / when using new RegExp() +var qmark = '[^/]' + +// * => any number of characters +var star = qmark + '*?' + +// ** when dots are allowed. Anything goes, except .. and . +// not (^ or / followed by one or two dots followed by $ or /), +// followed by anything, any number of times. +var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?' + +// not a ^ or / followed by a dot, +// followed by anything, any number of times. +var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?' + +// characters that need to be escaped in RegExp. +var reSpecials = charSet('().*{}+?[]^$\\!') + +// "abc" -> { a:true, b:true, c:true } +function charSet (s) { + return s.split('').reduce(function (set, c) { + set[c] = true + return set + }, {}) +} + +// normalizes slashes. +var slashSplit = /\/+/ + +minimatch.filter = filter +function filter (pattern, options) { + options = options || {} + return function (p, i, list) { + return minimatch(p, pattern, options) + } +} + +function ext (a, b) { + a = a || {} + b = b || {} + var t = {} + Object.keys(b).forEach(function (k) { + t[k] = b[k] + }) + Object.keys(a).forEach(function (k) { + t[k] = a[k] + }) + return t +} + +minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return minimatch + + var orig = minimatch + + var m = function minimatch (p, pattern, options) { + return orig.minimatch(p, pattern, ext(def, options)) + } + + m.Minimatch = function Minimatch (pattern, options) { + return new orig.Minimatch(pattern, ext(def, options)) + } + + return m +} + +Minimatch.defaults = function (def) { + if (!def || !Object.keys(def).length) return Minimatch + return minimatch.defaults(def).Minimatch +} + +function minimatch (p, pattern, options) { + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + + // shortcut: comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + return false + } + + // "" only matches "" + if (pattern.trim() === '') return p === '' + + return new Minimatch(pattern, options).match(p) +} + +function Minimatch (pattern, options) { + if (!(this instanceof Minimatch)) { + return new Minimatch(pattern, options) + } + + if (typeof pattern !== 'string') { + throw new TypeError('glob pattern string required') + } + + if (!options) options = {} + pattern = pattern.trim() + + // windows support: need to use /, not \ + if (path.sep !== '/') { + pattern = pattern.split(path.sep).join('/') + } + + this.options = options + this.set = [] + this.pattern = pattern + this.regexp = null + this.negate = false + this.comment = false + this.empty = false + + // make the set of regexps etc. + this.make() +} + +Minimatch.prototype.debug = function () {} + +Minimatch.prototype.make = make +function make () { + // don't do it more than once. + if (this._made) return + + var pattern = this.pattern + var options = this.options + + // empty patterns and comments match nothing. + if (!options.nocomment && pattern.charAt(0) === '#') { + this.comment = true + return + } + if (!pattern) { + this.empty = true + return + } + + // step 1: figure out negation, etc. + this.parseNegate() + + // step 2: expand braces + var set = this.globSet = this.braceExpand() + + if (options.debug) this.debug = console.error + + this.debug(this.pattern, set) + + // step 3: now we have a set, so turn each one into a series of path-portion + // matching patterns. + // These will be regexps, except in the case of "**", which is + // set to the GLOBSTAR object for globstar behavior, + // and will not contain any / characters + set = this.globParts = set.map(function (s) { + return s.split(slashSplit) + }) + + this.debug(this.pattern, set) + + // glob --> regexps + set = set.map(function (s, si, set) { + return s.map(this.parse, this) + }, this) + + this.debug(this.pattern, set) + + // filter out everything that didn't compile properly. + set = set.filter(function (s) { + return s.indexOf(false) === -1 + }) + + this.debug(this.pattern, set) + + this.set = set +} + +Minimatch.prototype.parseNegate = parseNegate +function parseNegate () { + var pattern = this.pattern + var negate = false + var options = this.options + var negateOffset = 0 + + if (options.nonegate) return + + for (var i = 0, l = pattern.length + ; i < l && pattern.charAt(i) === '!' + ; i++) { + negate = !negate + negateOffset++ + } + + if (negateOffset) this.pattern = pattern.substr(negateOffset) + this.negate = negate +} + +// Brace expansion: +// a{b,c}d -> abd acd +// a{b,}c -> abc ac +// a{0..3}d -> a0d a1d a2d a3d +// a{b,c{d,e}f}g -> abg acdfg acefg +// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg +// +// Invalid sets are not expanded. +// a{2..}b -> a{2..}b +// a{b}c -> a{b}c +minimatch.braceExpand = function (pattern, options) { + return braceExpand(pattern, options) +} + +Minimatch.prototype.braceExpand = braceExpand + +function braceExpand (pattern, options) { + if (!options) { + if (this instanceof Minimatch) { + options = this.options + } else { + options = {} + } + } + + pattern = typeof pattern === 'undefined' + ? this.pattern : pattern + + if (typeof pattern === 'undefined') { + throw new TypeError('undefined pattern') + } + + if (options.nobrace || + !pattern.match(/\{.*\}/)) { + // shortcut. no need to expand. + return [pattern] + } + + return expand(pattern) +} + +// parse a component of the expanded set. +// At this point, no pattern may contain "/" in it +// so we're going to return a 2d array, where each entry is the full +// pattern, split on '/', and then turned into a regular expression. +// A regexp is made at the end which joins each array with an +// escaped /, and another full one which joins each regexp with |. +// +// Following the lead of Bash 4.1, note that "**" only has special meaning +// when it is the *only* thing in a path portion. Otherwise, any series +// of * is equivalent to a single *. Globstar behavior is enabled by +// default, and can be disabled by setting options.noglobstar. +Minimatch.prototype.parse = parse +var SUBPARSE = {} +function parse (pattern, isSub) { + if (pattern.length > 1024 * 64) { + throw new TypeError('pattern is too long') + } + + var options = this.options + + // shortcuts + if (!options.noglobstar && pattern === '**') return GLOBSTAR + if (pattern === '') return '' + + var re = '' + var hasMagic = !!options.nocase + var escaping = false + // ? => one single character + var patternListStack = [] + var negativeLists = [] + var stateChar + var inClass = false + var reClassStart = -1 + var classStart = -1 + // . and .. never match anything that doesn't start with ., + // even when options.dot is set. + var patternStart = pattern.charAt(0) === '.' ? '' // anything + // not (start or / followed by . or .. followed by / or end) + : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' + : '(?!\\.)' + var self = this + + function clearStateChar () { + if (stateChar) { + // we had some state-tracking character + // that wasn't consumed by this pass. + switch (stateChar) { + case '*': + re += star + hasMagic = true + break + case '?': + re += qmark + hasMagic = true + break + default: + re += '\\' + stateChar + break + } + self.debug('clearStateChar %j %j', stateChar, re) + stateChar = false + } + } + + for (var i = 0, len = pattern.length, c + ; (i < len) && (c = pattern.charAt(i)) + ; i++) { + this.debug('%s\t%s %s %j', pattern, i, re, c) + + // skip over any that are escaped. + if (escaping && reSpecials[c]) { + re += '\\' + c + escaping = false + continue + } + + switch (c) { + case '/': + // completely not allowed, even escaped. + // Should already be path-split by now. + return false + + case '\\': + clearStateChar() + escaping = true + continue + + // the various stateChar values + // for the "extglob" stuff. + case '?': + case '*': + case '+': + case '@': + case '!': + this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c) + + // all of those are literals inside a class, except that + // the glob [!a] means [^a] in regexp + if (inClass) { + this.debug(' in class') + if (c === '!' && i === classStart + 1) c = '^' + re += c + continue + } + + // if we already have a stateChar, then it means + // that there was something like ** or +? in there. + // Handle the stateChar, then proceed with this one. + self.debug('call clearStateChar %j', stateChar) + clearStateChar() + stateChar = c + // if extglob is disabled, then +(asdf|foo) isn't a thing. + // just clear the statechar *now*, rather than even diving into + // the patternList stuff. + if (options.noext) clearStateChar() + continue + + case '(': + if (inClass) { + re += '(' + continue + } + + if (!stateChar) { + re += '\\(' + continue + } + + patternListStack.push({ + type: stateChar, + start: i - 1, + reStart: re.length, + open: plTypes[stateChar].open, + close: plTypes[stateChar].close + }) + // negation is (?:(?!js)[^/]*) + re += stateChar === '!' ? '(?:(?!(?:' : '(?:' + this.debug('plType %j %j', stateChar, re) + stateChar = false + continue + + case ')': + if (inClass || !patternListStack.length) { + re += '\\)' + continue + } + + clearStateChar() + hasMagic = true + var pl = patternListStack.pop() + // negation is (?:(?!js)[^/]*) + // The others are (?:) + re += pl.close + if (pl.type === '!') { + negativeLists.push(pl) + } + pl.reEnd = re.length + continue + + case '|': + if (inClass || !patternListStack.length || escaping) { + re += '\\|' + escaping = false + continue + } + + clearStateChar() + re += '|' + continue + + // these are mostly the same in regexp and glob + case '[': + // swallow any state-tracking char before the [ + clearStateChar() + + if (inClass) { + re += '\\' + c + continue + } + + inClass = true + classStart = i + reClassStart = re.length + re += c + continue + + case ']': + // a right bracket shall lose its special + // meaning and represent itself in + // a bracket expression if it occurs + // first in the list. -- POSIX.2 2.8.3.2 + if (i === classStart + 1 || !inClass) { + re += '\\' + c + escaping = false + continue + } + + // handle the case where we left a class open. + // "[z-a]" is valid, equivalent to "\[z-a\]" + if (inClass) { + // split where the last [ was, make sure we don't have + // an invalid re. if so, re-walk the contents of the + // would-be class to re-translate any characters that + // were passed through as-is + // TODO: It would probably be faster to determine this + // without a try/catch and a new RegExp, but it's tricky + // to do safely. For now, this is safe and works. + var cs = pattern.substring(classStart + 1, i) + try { + RegExp('[' + cs + ']') + } catch (er) { + // not a valid class! + var sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]' + hasMagic = hasMagic || sp[1] + inClass = false + continue + } + } + + // finish up the class. + hasMagic = true + inClass = false + re += c + continue + + default: + // swallow any state char that wasn't consumed + clearStateChar() + + if (escaping) { + // no need + escaping = false + } else if (reSpecials[c] + && !(c === '^' && inClass)) { + re += '\\' + } + + re += c + + } // switch + } // for + + // handle the case where we left a class open. + // "[abc" is valid, equivalent to "\[abc" + if (inClass) { + // split where the last [ was, and escape it + // this is a huge pita. We now have to re-walk + // the contents of the would-be class to re-translate + // any characters that were passed through as-is + cs = pattern.substr(classStart + 1) + sp = this.parse(cs, SUBPARSE) + re = re.substr(0, reClassStart) + '\\[' + sp[0] + hasMagic = hasMagic || sp[1] + } + + // handle the case where we had a +( thing at the *end* + // of the pattern. + // each pattern list stack adds 3 chars, and we need to go through + // and escape any | chars that were passed through as-is for the regexp. + // Go through and escape them, taking care not to double-escape any + // | chars that were already escaped. + for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { + var tail = re.slice(pl.reStart + pl.open.length) + this.debug('setting tail', re, pl) + // maybe some even number of \, then maybe 1 \, followed by a | + tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { + if (!$2) { + // the | isn't already escaped, so escape it. + $2 = '\\' + } + + // need to escape all those slashes *again*, without escaping the + // one that we need for escaping the | character. As it works out, + // escaping an even number of slashes can be done by simply repeating + // it exactly after itself. That's why this trick works. + // + // I am sorry that you have to see this. + return $1 + $1 + $2 + '|' + }) + + this.debug('tail=%j\n %s', tail, tail, pl, re) + var t = pl.type === '*' ? star + : pl.type === '?' ? qmark + : '\\' + pl.type + + hasMagic = true + re = re.slice(0, pl.reStart) + t + '\\(' + tail + } + + // handle trailing things that only matter at the very end. + clearStateChar() + if (escaping) { + // trailing \\ + re += '\\\\' + } + + // only need to apply the nodot start if the re starts with + // something that could conceivably capture a dot + var addPatternStart = false + switch (re.charAt(0)) { + case '.': + case '[': + case '(': addPatternStart = true + } + + // Hack to work around lack of negative lookbehind in JS + // A pattern like: *.!(x).!(y|z) needs to ensure that a name + // like 'a.xyz.yz' doesn't match. So, the first negative + // lookahead, has to look ALL the way ahead, to the end of + // the pattern. + for (var n = negativeLists.length - 1; n > -1; n--) { + var nl = negativeLists[n] + + var nlBefore = re.slice(0, nl.reStart) + var nlFirst = re.slice(nl.reStart, nl.reEnd - 8) + var nlLast = re.slice(nl.reEnd - 8, nl.reEnd) + var nlAfter = re.slice(nl.reEnd) + + nlLast += nlAfter + + // Handle nested stuff like *(*.js|!(*.json)), where open parens + // mean that we should *not* include the ) in the bit that is considered + // "after" the negated section. + var openParensBefore = nlBefore.split('(').length - 1 + var cleanAfter = nlAfter + for (i = 0; i < openParensBefore; i++) { + cleanAfter = cleanAfter.replace(/\)[+*?]?/, '') + } + nlAfter = cleanAfter + + var dollar = '' + if (nlAfter === '' && isSub !== SUBPARSE) { + dollar = '$' + } + var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + re = newRe + } + + // if the re is not "" at this point, then we need to make sure + // it doesn't match against an empty path part. + // Otherwise a/* will match a/, which it should not. + if (re !== '' && hasMagic) { + re = '(?=.)' + re + } + + if (addPatternStart) { + re = patternStart + re + } + + // parsing just a piece of a larger pattern. + if (isSub === SUBPARSE) { + return [re, hasMagic] + } + + // skip the regexp for non-magical patterns + // unescape anything in it, though, so that it'll be + // an exact match against a file etc. + if (!hasMagic) { + return globUnescape(pattern) + } + + var flags = options.nocase ? 'i' : '' + try { + var regExp = new RegExp('^' + re + '$', flags) + } catch (er) { + // If it was an invalid regular expression, then it can't match + // anything. This trick looks for a character after the end of + // the string, which is of course impossible, except in multi-line + // mode, but it's not a /m regex. + return new RegExp('$.') + } + + regExp._glob = pattern + regExp._src = re + + return regExp +} + +minimatch.makeRe = function (pattern, options) { + return new Minimatch(pattern, options || {}).makeRe() +} + +Minimatch.prototype.makeRe = makeRe +function makeRe () { + if (this.regexp || this.regexp === false) return this.regexp + + // at this point, this.set is a 2d array of partial + // pattern strings, or "**". + // + // It's better to use .match(). This function shouldn't + // be used, really, but it's pretty convenient sometimes, + // when you just want to work with a regex. + var set = this.set + + if (!set.length) { + this.regexp = false + return this.regexp + } + var options = this.options + + var twoStar = options.noglobstar ? star + : options.dot ? twoStarDot + : twoStarNoDot + var flags = options.nocase ? 'i' : '' + + var re = set.map(function (pattern) { + return pattern.map(function (p) { + return (p === GLOBSTAR) ? twoStar + : (typeof p === 'string') ? regExpEscape(p) + : p._src + }).join('\\\/') + }).join('|') + + // must match entire pattern + // ending in a * or ** will make it less strict. + re = '^(?:' + re + ')$' + + // can match anything, as long as it's not this. + if (this.negate) re = '^(?!' + re + ').*$' + + try { + this.regexp = new RegExp(re, flags) + } catch (ex) { + this.regexp = false + } + return this.regexp +} + +minimatch.match = function (list, pattern, options) { + options = options || {} + var mm = new Minimatch(pattern, options) + list = list.filter(function (f) { + return mm.match(f) + }) + if (mm.options.nonull && !list.length) { + list.push(pattern) + } + return list +} + +Minimatch.prototype.match = match +function match (f, partial) { + this.debug('match', f, this.pattern) + // short-circuit in the case of busted things. + // comments, etc. + if (this.comment) return false + if (this.empty) return f === '' + + if (f === '/' && partial) return true + + var options = this.options + + // windows: need to use /, not \ + if (path.sep !== '/') { + f = f.split(path.sep).join('/') + } + + // treat the test path as a set of pathparts. + f = f.split(slashSplit) + this.debug(this.pattern, 'split', f) + + // just ONE of the pattern sets in this.set needs to match + // in order for it to be valid. If negating, then just one + // match means that we have failed. + // Either way, return on the first hit. + + var set = this.set + this.debug(this.pattern, 'set', set) + + // Find the basename of the path by looking for the last non-empty segment + var filename + var i + for (i = f.length - 1; i >= 0; i--) { + filename = f[i] + if (filename) break + } + + for (i = 0; i < set.length; i++) { + var pattern = set[i] + var file = f + if (options.matchBase && pattern.length === 1) { + file = [filename] + } + var hit = this.matchOne(file, pattern, partial) + if (hit) { + if (options.flipNegate) return true + return !this.negate + } + } + + // didn't get any hits. this is success if it's a negative + // pattern, failure otherwise. + if (options.flipNegate) return false + return this.negate +} + +// set partial to true to test if, for example, +// "/a/b" matches the start of "/*/b/*/d" +// Partial means, if you run out of file before you run +// out of pattern, then that's fine, as long as all +// the parts match. +Minimatch.prototype.matchOne = function (file, pattern, partial) { + var options = this.options + + this.debug('matchOne', + { 'this': this, file: file, pattern: pattern }) + + this.debug('matchOne', file.length, pattern.length) + + for (var fi = 0, + pi = 0, + fl = file.length, + pl = pattern.length + ; (fi < fl) && (pi < pl) + ; fi++, pi++) { + this.debug('matchOne loop') + var p = pattern[pi] + var f = file[fi] + + this.debug(pattern, p, f) + + // should be impossible. + // some invalid regexp stuff in the set. + if (p === false) return false + + if (p === GLOBSTAR) { + this.debug('GLOBSTAR', [pattern, p, f]) + + // "**" + // a/**/b/**/c would match the following: + // a/b/x/y/z/c + // a/x/y/z/b/c + // a/b/x/b/x/c + // a/b/c + // To do this, take the rest of the pattern after + // the **, and see if it would match the file remainder. + // If so, return success. + // If not, the ** "swallows" a segment, and try again. + // This is recursively awful. + // + // a/**/b/**/c matching a/b/x/y/z/c + // - a matches a + // - doublestar + // - matchOne(b/x/y/z/c, b/**/c) + // - b matches b + // - doublestar + // - matchOne(x/y/z/c, c) -> no + // - matchOne(y/z/c, c) -> no + // - matchOne(z/c, c) -> no + // - matchOne(c, c) yes, hit + var fr = fi + var pr = pi + 1 + if (pr === pl) { + this.debug('** at the end') + // a ** at the end will just swallow the rest. + // We have found a match. + // however, it will not swallow /.x, unless + // options.dot is set. + // . and .. are *never* matched by **, for explosively + // exponential reasons. + for (; fi < fl; fi++) { + if (file[fi] === '.' || file[fi] === '..' || + (!options.dot && file[fi].charAt(0) === '.')) return false + } + return true + } + + // ok, let's see if we can swallow whatever we can. + while (fr < fl) { + var swallowee = file[fr] + + this.debug('\nglobstar while', file, fr, pattern, pr, swallowee) + + // XXX remove this slice. Just pass the start index. + if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { + this.debug('globstar found match!', fr, fl, swallowee) + // found a match. + return true + } else { + // can't swallow "." or ".." ever. + // can only swallow ".foo" when explicitly asked. + if (swallowee === '.' || swallowee === '..' || + (!options.dot && swallowee.charAt(0) === '.')) { + this.debug('dot detected!', file, fr, pattern, pr) + break + } + + // ** swallows a segment, and continue. + this.debug('globstar swallow a segment, and continue') + fr++ + } + } + + // no match was found. + // However, in partial mode, we can't say this is necessarily over. + // If there's more *pattern* left, then + if (partial) { + // ran out of file + this.debug('\n>>> no match, partial?', file, fr, pattern, pr) + if (fr === fl) return true + } + return false + } + + // something other than ** + // non-magic patterns just have to match exactly + // patterns with magic have been turned into regexps. + var hit + if (typeof p === 'string') { + if (options.nocase) { + hit = f.toLowerCase() === p.toLowerCase() + } else { + hit = f === p + } + this.debug('string match', p, f, hit) + } else { + hit = f.match(p) + this.debug('pattern match', p, f, hit) + } + + if (!hit) return false + } + + // Note: ending in / means that we'll get a final "" + // at the end of the pattern. This can only match a + // corresponding "" at the end of the file. + // If the file ends in /, then it can only match a + // a pattern that ends in /, unless the pattern just + // doesn't have any more for it. But, a/b/ should *not* + // match "a/b/*", even though "" matches against the + // [^/]*? pattern, except in partial mode, where it might + // simply not be reached yet. + // However, a/b/ should still satisfy a/* + + // now either we fell off the end of the pattern, or we're done. + if (fi === fl && pi === pl) { + // ran out of pattern and filename at the same time. + // an exact hit! + return true + } else if (fi === fl) { + // ran out of file, but still had pattern left. + // this is ok if we're doing the match as part of + // a glob fs traversal. + return partial + } else if (pi === pl) { + // ran out of pattern, still have file left. + // this is only acceptable if we're on the very last + // empty segment of a file with a trailing slash. + // a/* should match a/b/ + var emptyFileEnd = (fi === fl - 1) && (file[fi] === '') + return emptyFileEnd + } + + // should be unreachable. + throw new Error('wtf?') +} + +// replace stuff like \* with * +function globUnescape (s) { + return s.replace(/\\(.)/g, '$1') +} + +function regExpEscape (s) { + return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') +} + +},{"brace-expansion":33,"path":402}],384:[function(require,module,exports){ +"use strict" + +var compile = require("cwise-compiler") + +var EmptyProc = { + body: "", + args: [], + thisVars: [], + localVars: [] +} + +function fixup(x) { + if(!x) { + return EmptyProc + } + for(var i=0; i>", + rrshift: ">>>" +} +;(function(){ + for(var id in assign_ops) { + var op = assign_ops[id] + exports[id] = makeOp({ + args: ["array","array","array"], + body: {args:["a","b","c"], + body: "a=b"+op+"c"}, + funcName: id + }) + exports[id+"eq"] = makeOp({ + args: ["array","array"], + body: {args:["a","b"], + body:"a"+op+"=b"}, + rvalue: true, + funcName: id+"eq" + }) + exports[id+"s"] = makeOp({ + args: ["array", "array", "scalar"], + body: {args:["a","b","s"], + body:"a=b"+op+"s"}, + funcName: id+"s" + }) + exports[id+"seq"] = makeOp({ + args: ["array","scalar"], + body: {args:["a","s"], + body:"a"+op+"=s"}, + rvalue: true, + funcName: id+"seq" + }) + } +})(); + +var unary_ops = { + not: "!", + bnot: "~", + neg: "-", + recip: "1.0/" +} +;(function(){ + for(var id in unary_ops) { + var op = unary_ops[id] + exports[id] = makeOp({ + args: ["array", "array"], + body: {args:["a","b"], + body:"a="+op+"b"}, + funcName: id + }) + exports[id+"eq"] = makeOp({ + args: ["array"], + body: {args:["a"], + body:"a="+op+"a"}, + rvalue: true, + count: 2, + funcName: id+"eq" + }) + } +})(); + +var binary_ops = { + and: "&&", + or: "||", + eq: "===", + neq: "!==", + lt: "<", + gt: ">", + leq: "<=", + geq: ">=" +} +;(function() { + for(var id in binary_ops) { + var op = binary_ops[id] + exports[id] = makeOp({ + args: ["array","array","array"], + body: {args:["a", "b", "c"], + body:"a=b"+op+"c"}, + funcName: id + }) + exports[id+"s"] = makeOp({ + args: ["array","array","scalar"], + body: {args:["a", "b", "s"], + body:"a=b"+op+"s"}, + funcName: id+"s" + }) + exports[id+"eq"] = makeOp({ + args: ["array", "array"], + body: {args:["a", "b"], + body:"a=a"+op+"b"}, + rvalue:true, + count:2, + funcName: id+"eq" + }) + exports[id+"seq"] = makeOp({ + args: ["array", "scalar"], + body: {args:["a","s"], + body:"a=a"+op+"s"}, + rvalue:true, + count:2, + funcName: id+"seq" + }) + } +})(); + +var math_unary = [ + "abs", + "acos", + "asin", + "atan", + "ceil", + "cos", + "exp", + "floor", + "log", + "round", + "sin", + "sqrt", + "tan" +] +;(function() { + for(var i=0; ithis_s){this_s=-a}else if(a>this_s){this_s=a}", localVars: [], thisVars: ["this_s"]}, + post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, + funcName: "norminf" +}) + +exports.norm1 = compile({ + args:["array"], + pre: {args:[], localVars:[], thisVars:["this_s"], body:"this_s=0"}, + body: {args:[{name:"a", lvalue:false, rvalue:true, count:3}], body: "this_s+=a<0?-a:a", localVars: [], thisVars: ["this_s"]}, + post: {args:[], localVars:[], thisVars:["this_s"], body:"return this_s"}, + funcName: "norm1" +}) + +exports.sup = compile({ + args: [ "array" ], + pre: + { body: "this_h=-Infinity", + args: [], + thisVars: [ "this_h" ], + localVars: [] }, + body: + { body: "if(_inline_1_arg0_>this_h)this_h=_inline_1_arg0_", + args: [{"name":"_inline_1_arg0_","lvalue":false,"rvalue":true,"count":2} ], + thisVars: [ "this_h" ], + localVars: [] }, + post: + { body: "return this_h", + args: [], + thisVars: [ "this_h" ], + localVars: [] } + }) + +exports.inf = compile({ + args: [ "array" ], + pre: + { body: "this_h=Infinity", + args: [], + thisVars: [ "this_h" ], + localVars: [] }, + body: + { body: "if(_inline_1_arg0_this_v){this_v=_inline_1_arg1_;for(var _inline_1_k=0;_inline_1_k<_inline_1_arg0_.length;++_inline_1_k){this_i[_inline_1_k]=_inline_1_arg0_[_inline_1_k]}}}", + args:[ + {name:"_inline_1_arg0_",lvalue:false,rvalue:true,count:2}, + {name:"_inline_1_arg1_",lvalue:false,rvalue:true,count:2}], + thisVars:["this_i","this_v"], + localVars:["_inline_1_k"]}, + post:{ + body:"{return this_i}", + args:[], + thisVars:["this_i"], + localVars:[]} +}) + +exports.random = makeOp({ + args: ["array"], + pre: {args:[], body:"this_f=Math.random", thisVars:["this_f"]}, + body: {args: ["a"], body:"a=this_f()", thisVars:["this_f"]}, + funcName: "random" +}) + +exports.assign = makeOp({ + args:["array", "array"], + body: {args:["a", "b"], body:"a=b"}, + funcName: "assign" }) + +exports.assigns = makeOp({ + args:["array", "scalar"], + body: {args:["a", "b"], body:"a=b"}, + funcName: "assigns" }) + + +exports.equals = compile({ + args:["array", "array"], + pre: EmptyProc, + body: {args:[{name:"x", lvalue:false, rvalue:true, count:1}, + {name:"y", lvalue:false, rvalue:true, count:1}], + body: "if(x!==y){return false}", + localVars: [], + thisVars: []}, + post: {args:[], localVars:[], thisVars:[], body:"return true"}, + funcName: "equals" +}) + + + +},{"cwise-compiler":48}],385:[function(require,module,exports){ +"use strict" + +var ndarray = require("ndarray") +var do_convert = require("./doConvert.js") + +module.exports = function convert(arr, result) { + var shape = [], c = arr, sz = 1 + while(Array.isArray(c)) { + shape.push(c.length) + sz *= c.length + c = c[0] + } + if(shape.length === 0) { + return ndarray() + } + if(!result) { + result = ndarray(new Float64Array(sz), shape) + } + do_convert(result, arr) + return result +} + +},{"./doConvert.js":386,"ndarray":387}],386:[function(require,module,exports){ +module.exports=require('cwise-compiler')({"args":["array","scalar","index"],"pre":{"body":"{}","args":[],"thisVars":[],"localVars":[]},"body":{"body":"{\nvar _inline_1_v=_inline_1_arg1_,_inline_1_i\nfor(_inline_1_i=0;_inline_1_i<_inline_1_arg2_.length-1;++_inline_1_i) {\n_inline_1_v=_inline_1_v[_inline_1_arg2_[_inline_1_i]]\n}\n_inline_1_arg0_=_inline_1_v[_inline_1_arg2_[_inline_1_arg2_.length-1]]\n}","args":[{"name":"_inline_1_arg0_","lvalue":true,"rvalue":false,"count":1},{"name":"_inline_1_arg1_","lvalue":false,"rvalue":true,"count":1},{"name":"_inline_1_arg2_","lvalue":false,"rvalue":true,"count":4}],"thisVars":[],"localVars":["_inline_1_i","_inline_1_v"]},"post":{"body":"{}","args":[],"thisVars":[],"localVars":[]},"funcName":"convert","blockSize":64}) + +},{"cwise-compiler":48}],387:[function(require,module,exports){ +var iota = require("iota-array") +var isBuffer = require("is-buffer") + +var hasTypedArrays = ((typeof Float64Array) !== "undefined") + +function compare1st(a, b) { + return a[0] - b[0] +} + +function order() { + var stride = this.stride + var terms = new Array(stride.length) + var i + for(i=0; iMath.abs(this.stride[1]))?[1,0]:[0,1]}})") + } else if(dimension === 3) { + code.push( +"var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);\ +if(s0>s1){\ +if(s1>s2){\ +return [2,1,0];\ +}else if(s0>s2){\ +return [1,2,0];\ +}else{\ +return [1,0,2];\ +}\ +}else if(s0>s2){\ +return [2,0,1];\ +}else if(s2>s1){\ +return [0,1,2];\ +}else{\ +return [0,2,1];\ +}}})") + } + } else { + code.push("ORDER})") + } + } + + //view.set(i0, ..., v): + code.push( +"proto.set=function "+className+"_set("+args.join(",")+",v){") + if(useGetters) { + code.push("return this.data.set("+index_str+",v)}") + } else { + code.push("return this.data["+index_str+"]=v}") + } + + //view.get(i0, ...): + code.push("proto.get=function "+className+"_get("+args.join(",")+"){") + if(useGetters) { + code.push("return this.data.get("+index_str+")}") + } else { + code.push("return this.data["+index_str+"]}") + } + + //view.index: + code.push( + "proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}") + + //view.hi(): + code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+ + indices.map(function(i) { + return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("") + }).join(",")+","+ + indices.map(function(i) { + return "this.stride["+i + "]" + }).join(",")+",this.offset)}") + + //view.lo(): + var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" }) + var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" }) + code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(",")) + for(var i=0; i=0){\ +d=i"+i+"|0;\ +b+=c"+i+"*d;\ +a"+i+"-=d}") + } + code.push("return new "+className+"(this.data,"+ + indices.map(function(i) { + return "a"+i + }).join(",")+","+ + indices.map(function(i) { + return "c"+i + }).join(",")+",b)}") + + //view.step(): + code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+ + indices.map(function(i) { + return "a"+i+"=this.shape["+i+"]" + }).join(",")+","+ + indices.map(function(i) { + return "b"+i+"=this.stride["+i+"]" + }).join(",")+",c=this.offset,d=0,ceil=Math.ceil") + for(var i=0; i=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}") + } + code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}") + + //Add return statement + code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+ + indices.map(function(i) { + return "shape["+i+"]" + }).join(",")+","+ + indices.map(function(i) { + return "stride["+i+"]" + }).join(",")+",offset)}") + + //Compile procedure + var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n")) + return procedure(CACHED_CONSTRUCTORS[dtype], order) +} + +function arrayDType(data) { + if(isBuffer(data)) { + return "buffer" + } + if(hasTypedArrays) { + switch(Object.prototype.toString.call(data)) { + case "[object Float64Array]": + return "float64" + case "[object Float32Array]": + return "float32" + case "[object Int8Array]": + return "int8" + case "[object Int16Array]": + return "int16" + case "[object Int32Array]": + return "int32" + case "[object Uint8Array]": + return "uint8" + case "[object Uint16Array]": + return "uint16" + case "[object Uint32Array]": + return "uint32" + case "[object Uint8ClampedArray]": + return "uint8_clamped" + case "[object BigInt64Array]": + return "bigint64" + case "[object BigUint64Array]": + return "biguint64" + } + } + if(Array.isArray(data)) { + return "array" + } + return "generic" +} + +var CACHED_CONSTRUCTORS = { + "float32":[], + "float64":[], + "int8":[], + "int16":[], + "int32":[], + "uint8":[], + "uint16":[], + "uint32":[], + "array":[], + "uint8_clamped":[], + "bigint64": [], + "biguint64": [], + "buffer":[], + "generic":[] +} + +;(function() { + for(var id in CACHED_CONSTRUCTORS) { + CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1)) + } +}); + +function wrappedNDArrayCtor(data, shape, stride, offset) { + if(data === undefined) { + var ctor = CACHED_CONSTRUCTORS.array[0] + return ctor([]) + } else if(typeof data === "number") { + data = [data] + } + if(shape === undefined) { + shape = [ data.length ] + } + var d = shape.length + if(stride === undefined) { + stride = new Array(d) + for(var i=d-1, sz=1; i>=0; --i) { + stride[i] = sz + sz *= shape[i] + } + } + if(offset === undefined) { + offset = 0 + for(var i=0; i 0) { + this._paused = false; + + this.emit('drain'); + } + }.bind(this)); +}; + +ChunkStream.prototype.write = function(data, encoding) { + + if (!this.writable) { + this.emit('error', new Error('Stream not writable')); + return false; + } + + if (!Buffer.isBuffer(data)) + data = new Buffer(data, encoding || this._encoding); + + this._buffers.push(data); + this._buffered += data.length; + + this._process(); + + // ok if there are no more read requests + if (this._reads && this._reads.length == 0) + this._paused = true; + + return this.writable && !this._paused; +}; + +ChunkStream.prototype.end = function(data, encoding) { + + if (data) this.write(data, encoding); + + this.writable = false; + + // already destroyed + if (!this._buffers) return; + + // enqueue or handle end + if (this._buffers.length == 0) { + this._end(); + } else { + this._buffers.push(null); + this._process(); + } +}; + +ChunkStream.prototype.destroySoon = ChunkStream.prototype.end; + +ChunkStream.prototype._end = function() { + + if (this._reads.length > 0) { + this.emit('error', + new Error('There are some read requests waitng on finished stream') + ); + } + + this.destroy(); +}; + +ChunkStream.prototype.destroy = function() { + + if (!this._buffers) return; + + this.writable = false; + this._reads = null; + this._buffers = null; + + this.emit('close'); +}; + +ChunkStream.prototype._process = function() { + + // as long as there is any data and read requests + while (this._buffered > 0 && this._reads && this._reads.length > 0) { + + var read = this._reads[0]; + + // read any data (but no more than length) + if (read.allowLess) { + + // ok there is any data so that we can satisfy this request + this._reads.shift(); // == read + + // first we need to peek into first buffer + var buf = this._buffers[0]; + + // ok there is more data than we need + if (buf.length > read.length) { + + this._buffered -= read.length; + this._buffers[0] = buf.slice(read.length); + + read.func.call(this, buf.slice(0, read.length)); + + } else { + // ok this is less than maximum length so use it all + this._buffered -= buf.length; + this._buffers.shift(); // == buf + + read.func.call(this, buf); + } + + } else if (this._buffered >= read.length) { + // ok we can meet some expectations + + this._reads.shift(); // == read + + var pos = 0, + count = 0, + data = new Buffer(read.length); + + // create buffer for all data + while (pos < read.length) { + + var buf = this._buffers[count++], + len = Math.min(buf.length, read.length - pos); + + buf.copy(data, pos, 0, len); + pos += len; + + // last buffer wasn't used all so just slice it and leave + if (len != buf.length) + this._buffers[--count] = buf.slice(len); + } + + // remove all used buffers + if (count > 0) + this._buffers.splice(0, count); + + this._buffered -= read.length; + + read.func.call(this, data); + + } else { + // not enought data to satisfy first request in queue + // so we need to wait for more + break; + } + } + + if (this._buffers && this._buffers.length > 0 && this._buffers[0] == null) { + this._end(); + } +}; + +}).call(this,require('_process'),require("buffer").Buffer) +},{"_process":432,"buffer":297,"stream":503,"util":523}],389:[function(require,module,exports){ +// Copyright (c) 2012 Kuba Niegowski +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +'use strict'; + + +module.exports = { + + PNG_SIGNATURE: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], + + TYPE_IHDR: 0x49484452, + TYPE_IEND: 0x49454e44, + TYPE_IDAT: 0x49444154, + TYPE_PLTE: 0x504c5445, + TYPE_tRNS: 0x74524e53, + TYPE_gAMA: 0x67414d41, + + COLOR_PALETTE: 1, + COLOR_COLOR: 2, + COLOR_ALPHA: 4 +}; + +},{}],390:[function(require,module,exports){ +// Copyright (c) 2012 Kuba Niegowski +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +'use strict'; + +var util = require('util'), + Stream = require('stream'); + + +var CrcStream = module.exports = function() { + Stream.call(this); + + this._crc = -1; + + this.writable = true; +}; +util.inherits(CrcStream, Stream); + + +CrcStream.prototype.write = function(data) { + + for (var i = 0; i < data.length; i++) { + this._crc = crcTable[(this._crc ^ data[i]) & 0xff] ^ (this._crc >>> 8); + } + return true; +}; + +CrcStream.prototype.end = function(data) { + if (data) this.write(data); + + this.emit('crc', this.crc32()); +}; + +CrcStream.prototype.crc32 = function() { + return this._crc ^ -1; +}; + + +CrcStream.crc32 = function(buf) { + + var crc = -1; + for (var i = 0; i < buf.length; i++) { + crc = crcTable[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8); + } + return crc ^ -1; +}; + + + +var crcTable = []; + +for (var i = 0; i < 256; i++) { + var c = i; + for (var j = 0; j < 8; j++) { + if (c & 1) { + c = 0xedb88320 ^ (c >>> 1); + } else { + c = c >>> 1; + } + } + crcTable[i] = c; +} + +},{"stream":503,"util":523}],391:[function(require,module,exports){ +(function (Buffer){ +// Copyright (c) 2012 Kuba Niegowski +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +'use strict'; + +var util = require('util'), + zlib = require('zlib'), + ChunkStream = require('./chunkstream'); + + +var Filter = module.exports = function(width, height, Bpp, data, options) { + ChunkStream.call(this); + + this._width = width; + this._height = height; + this._Bpp = Bpp; + this._data = data; + this._options = options; + + this._line = 0; + + if (!('filterType' in options) || options.filterType == -1) { + options.filterType = [0, 1, 2, 3, 4]; + } else if (typeof options.filterType == 'number') { + options.filterType = [options.filterType]; + } + + this._filters = { + 0: this._filterNone.bind(this), + 1: this._filterSub.bind(this), + 2: this._filterUp.bind(this), + 3: this._filterAvg.bind(this), + 4: this._filterPaeth.bind(this) + }; + + this.read(this._width * Bpp + 1, this._reverseFilterLine.bind(this)); +}; +util.inherits(Filter, ChunkStream); + + +var pixelBppMap = { + 1: { // L + 0: 0, + 1: 0, + 2: 0, + 3: 0xff + }, + 2: { // LA + 0: 0, + 1: 0, + 2: 0, + 3: 1 + }, + 3: { // RGB + 0: 0, + 1: 1, + 2: 2, + 3: 0xff + }, + 4: { // RGBA + 0: 0, + 1: 1, + 2: 2, + 3: 3 + } +}; + +Filter.prototype._reverseFilterLine = function(rawData) { + + var pxData = this._data, + pxLineLength = this._width << 2, + pxRowPos = this._line * pxLineLength, + filter = rawData[0]; + + if (filter == 0) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i]; + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] : 0xff; + } + } + + } else if (filter == 1) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i], + left = x > 0 ? pxData[pxPos + i - 4] : 0; + + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] + left : 0xff; + } + } + + } else if (filter == 2) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i], + up = this._line > 0 ? pxData[pxPos - pxLineLength + i] : 0; + + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] + up : 0xff; + } + + } + + } else if (filter == 3) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i], + left = x > 0 ? pxData[pxPos + i - 4] : 0, + up = this._line > 0 ? pxData[pxPos - pxLineLength + i] : 0, + add = Math.floor((left + up) / 2); + + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] + add : 0xff; + } + + } + + } else if (filter == 4) { + for (var x = 0; x < this._width; x++) { + var pxPos = pxRowPos + (x << 2), + rawPos = 1 + x * this._Bpp; + + for (var i = 0; i < 4; i++) { + var idx = pixelBppMap[this._Bpp][i], + left = x > 0 ? pxData[pxPos + i - 4] : 0, + up = this._line > 0 ? pxData[pxPos - pxLineLength + i] : 0, + upLeft = x > 0 && this._line > 0 + ? pxData[pxPos - pxLineLength + i - 4] : 0, + add = PaethPredictor(left, up, upLeft); + + pxData[pxPos + i] = idx != 0xff ? rawData[rawPos + idx] + add : 0xff; + } + } + } + + + this._line++; + + if (this._line < this._height) + this.read(this._width * this._Bpp + 1, this._reverseFilterLine.bind(this)); + else + this.emit('complete', this._data, this._width, this._height); +}; + + + + +Filter.prototype.filter = function() { + + var pxData = this._data, + rawData = new Buffer(((this._width << 2) + 1) * this._height); + + for (var y = 0; y < this._height; y++) { + + // find best filter for this line (with lowest sum of values) + var filterTypes = this._options.filterType, + min = Infinity, + sel = 0; + + for (var i = 0; i < filterTypes.length; i++) { + var sum = this._filters[filterTypes[i]](pxData, y, null); + if (sum < min) { + sel = filterTypes[i]; + min = sum; + } + } + + this._filters[sel](pxData, y, rawData); + } + return rawData; +}; + +Filter.prototype._filterNone = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (!rawData) { + for (var x = 0; x < pxRowLength; x++) + sum += Math.abs(pxData[y * pxRowLength + x]); + + } else { + rawData[y * rawRowLength] = 0; + pxData.copy(rawData, rawRowLength * y + 1, pxRowLength * y, pxRowLength * (y + 1)); + } + + return sum; +}; + +Filter.prototype._filterSub = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (rawData) + rawData[y * rawRowLength] = 1; + + for (var x = 0; x < pxRowLength; x++) { + + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + val = pxData[y * pxRowLength + x] - left; + + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; +}; + +Filter.prototype._filterUp = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (rawData) + rawData[y * rawRowLength] = 2; + + for (var x = 0; x < pxRowLength; x++) { + + var up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + val = pxData[y * pxRowLength + x] - up; + + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; +}; + +Filter.prototype._filterAvg = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (rawData) + rawData[y * rawRowLength] = 3; + + for (var x = 0; x < pxRowLength; x++) { + + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + val = pxData[y * pxRowLength + x] - ((left + up) >> 1); + + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; +}; + +Filter.prototype._filterPaeth = function(pxData, y, rawData) { + + var pxRowLength = this._width << 2, + rawRowLength = pxRowLength + 1, + sum = 0; + + if (rawData) + rawData[y * rawRowLength] = 4; + + for (var x = 0; x < pxRowLength; x++) { + + var left = x >= 4 ? pxData[y * pxRowLength + x - 4] : 0, + up = y > 0 ? pxData[(y - 1) * pxRowLength + x] : 0, + upLeft = x >= 4 && y > 0 ? pxData[(y - 1) * pxRowLength + x - 4] : 0, + val = pxData[y * pxRowLength + x] - PaethPredictor(left, up, upLeft); + + if (!rawData) sum += Math.abs(val); + else rawData[y * rawRowLength + 1 + x] = val; + } + return sum; +}; + + + +var PaethPredictor = function(left, above, upLeft) { + + var p = left + above - upLeft, + pLeft = Math.abs(p - left), + pAbove = Math.abs(p - above), + pUpLeft = Math.abs(p - upLeft); + + if (pLeft <= pAbove && pLeft <= pUpLeft) return left; + else if (pAbove <= pUpLeft) return above; + else return upLeft; +}; + +}).call(this,require("buffer").Buffer) +},{"./chunkstream":388,"buffer":297,"util":523,"zlib":295}],392:[function(require,module,exports){ +(function (Buffer){ +// Copyright (c) 2012 Kuba Niegowski +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +'use strict'; + + +var util = require('util'), + Stream = require('stream'), + zlib = require('zlib'), + Filter = require('./filter'), + CrcStream = require('./crc'), + constants = require('./constants'); + + +var Packer = module.exports = function(options) { + Stream.call(this); + + this._options = options; + + options.deflateChunkSize = options.deflateChunkSize || 32 * 1024; + options.deflateLevel = options.deflateLevel || 9; + options.deflateStrategy = options.deflateStrategy || 3; + + this.readable = true; +}; +util.inherits(Packer, Stream); + + +Packer.prototype.pack = function(data, width, height) { + + // Signature + this.emit('data', new Buffer(constants.PNG_SIGNATURE)); + this.emit('data', this._packIHDR(width, height)); + + // filter pixel data + var filter = new Filter(width, height, 4, data, this._options); + var data = filter.filter(); + + // compress it + var deflate = zlib.createDeflate({ + chunkSize: this._options.deflateChunkSize, + level: this._options.deflateLevel, + strategy: this._options.deflateStrategy + }); + deflate.on('error', this.emit.bind(this, 'error')); + + deflate.on('data', function(data) { + this.emit('data', this._packIDAT(data)); + }.bind(this)); + + deflate.on('end', function() { + this.emit('data', this._packIEND()); + this.emit('end'); + }.bind(this)); + + deflate.end(data); +}; + +Packer.prototype._packChunk = function(type, data) { + + var len = (data ? data.length : 0), + buf = new Buffer(len + 12); + + buf.writeUInt32BE(len, 0); + buf.writeUInt32BE(type, 4); + + if (data) data.copy(buf, 8); + + buf.writeInt32BE(CrcStream.crc32(buf.slice(4, buf.length - 4)), buf.length - 4); + return buf; +}; + +Packer.prototype._packIHDR = function(width, height) { + + var buf = new Buffer(13); + buf.writeUInt32BE(width, 0); + buf.writeUInt32BE(height, 4); + buf[8] = 8; + buf[9] = 6; // colorType + buf[10] = 0; // compression + buf[11] = 0; // filter + buf[12] = 0; // interlace + + return this._packChunk(constants.TYPE_IHDR, buf); +}; + +Packer.prototype._packIDAT = function(data) { + return this._packChunk(constants.TYPE_IDAT, data); +}; + +Packer.prototype._packIEND = function() { + return this._packChunk(constants.TYPE_IEND, null); +}; + +}).call(this,require("buffer").Buffer) +},{"./constants":389,"./crc":390,"./filter":391,"buffer":297,"stream":503,"util":523,"zlib":295}],393:[function(require,module,exports){ +(function (Buffer){ +// Copyright (c) 2012 Kuba Niegowski +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +'use strict'; + + +var util = require('util'), + zlib = require('zlib'), + CrcStream = require('./crc'), + ChunkStream = require('./chunkstream'), + constants = require('./constants'), + Filter = require('./filter'); + + +var Parser = module.exports = function(options) { + ChunkStream.call(this); + + this._options = options; + options.checkCRC = options.checkCRC !== false; + + this._hasIHDR = false; + this._hasIEND = false; + + this._inflate = null; + this._filter = null; + this._crc = null; + + // input flags/metadata + this._palette = []; + this._colorType = 0; + + this._chunks = {}; + this._chunks[constants.TYPE_IHDR] = this._handleIHDR.bind(this); + this._chunks[constants.TYPE_IEND] = this._handleIEND.bind(this); + this._chunks[constants.TYPE_IDAT] = this._handleIDAT.bind(this); + this._chunks[constants.TYPE_PLTE] = this._handlePLTE.bind(this); + this._chunks[constants.TYPE_tRNS] = this._handleTRNS.bind(this); + this._chunks[constants.TYPE_gAMA] = this._handleGAMA.bind(this); + + this.writable = true; + + this.on('error', this._handleError.bind(this)); + this._handleSignature(); +}; +util.inherits(Parser, ChunkStream); + + +Parser.prototype._handleError = function() { + + this.writable = false; + + this.destroy(); + + if (this._inflate) + this._inflate.destroy(); +}; + +Parser.prototype._handleSignature = function() { + this.read(constants.PNG_SIGNATURE.length, + this._parseSignature.bind(this) + ); +}; + +Parser.prototype._parseSignature = function(data) { + + var signature = constants.PNG_SIGNATURE; + + for (var i = 0; i < signature.length; i++) { + if (data[i] != signature[i]) { + this.emit('error', new Error('Invalid file signature')); + return; + } + } + this.read(8, this._parseChunkBegin.bind(this)); +}; + +Parser.prototype._parseChunkBegin = function(data) { + + // chunk content length + var length = data.readUInt32BE(0); + + // chunk type + var type = data.readUInt32BE(4), + name = ''; + for (var i = 4; i < 8; i++) + name += String.fromCharCode(data[i]); + + // console.log('chunk ', name, length); + + // chunk flags + var ancillary = !!(data[4] & 0x20), // or critical + priv = !!(data[5] & 0x20), // or public + safeToCopy = !!(data[7] & 0x20); // or unsafe + + if (!this._hasIHDR && type != constants.TYPE_IHDR) { + this.emit('error', new Error('Expected IHDR on beggining')); + return; + } + + this._crc = new CrcStream(); + this._crc.write(new Buffer(name)); + + if (this._chunks[type]) { + return this._chunks[type](length); + + } else if (!ancillary) { + this.emit('error', new Error('Unsupported critical chunk type ' + name)); + return; + } else { + this.read(length + 4, this._skipChunk.bind(this)); + } +}; + +Parser.prototype._skipChunk = function(data) { + this.read(8, this._parseChunkBegin.bind(this)); +}; + +Parser.prototype._handleChunkEnd = function() { + this.read(4, this._parseChunkEnd.bind(this)); +}; + +Parser.prototype._parseChunkEnd = function(data) { + + var fileCrc = data.readInt32BE(0), + calcCrc = this._crc.crc32(); + + // check CRC + if (this._options.checkCRC && calcCrc != fileCrc) { + this.emit('error', new Error('Crc error')); + return; + } + + if (this._hasIEND) { + this.destroySoon(); + + } else { + this.read(8, this._parseChunkBegin.bind(this)); + } +}; + + +Parser.prototype._handleIHDR = function(length) { + this.read(length, this._parseIHDR.bind(this)); +}; +Parser.prototype._parseIHDR = function(data) { + + this._crc.write(data); + + var width = data.readUInt32BE(0), + height = data.readUInt32BE(4), + depth = data[8], + colorType = data[9], // bits: 1 palette, 2 color, 4 alpha + compr = data[10], + filter = data[11], + interlace = data[12]; + + // console.log(' width', width, 'height', height, + // 'depth', depth, 'colorType', colorType, + // 'compr', compr, 'filter', filter, 'interlace', interlace + // ); + + if (depth != 8) { + this.emit('error', new Error('Unsupported bit depth ' + depth)); + return; + } + if (!(colorType in colorTypeToBppMap)) { + this.emit('error', new Error('Unsupported color type')); + return; + } + if (compr != 0) { + this.emit('error', new Error('Unsupported compression method')); + return; + } + if (filter != 0) { + this.emit('error', new Error('Unsupported filter method')); + return; + } + if (interlace != 0) { + this.emit('error', new Error('Unsupported interlace method')); + return; + } + + this._colorType = colorType; + + this._data = new Buffer(width * height * 4); + this._filter = new Filter( + width, height, + colorTypeToBppMap[this._colorType], + this._data, + this._options + ); + + this._hasIHDR = true; + + this.emit('metadata', { + width: width, + height: height, + palette: !!(colorType & constants.COLOR_PALETTE), + color: !!(colorType & constants.COLOR_COLOR), + alpha: !!(colorType & constants.COLOR_ALPHA), + data: this._data + }); + + this._handleChunkEnd(); +}; + + +Parser.prototype._handlePLTE = function(length) { + this.read(length, this._parsePLTE.bind(this)); +}; +Parser.prototype._parsePLTE = function(data) { + + this._crc.write(data); + + var entries = Math.floor(data.length / 3); + // console.log('Palette:', entries); + + for (var i = 0; i < entries; i++) { + this._palette.push([ + data.readUInt8(i * 3), + data.readUInt8(i * 3 + 1), + data.readUInt8(i * 3 + 2 ), + 0xff + ]); + } + + this._handleChunkEnd(); +}; + +Parser.prototype._handleTRNS = function(length) { + this.read(length, this._parseTRNS.bind(this)); +}; +Parser.prototype._parseTRNS = function(data) { + + this._crc.write(data); + + // palette + if (this._colorType == 3) { + if (this._palette.length == 0) { + this.emit('error', new Error('Transparency chunk must be after palette')); + return; + } + if (data.length > this._palette.length) { + this.emit('error', new Error('More transparent colors than palette size')); + return; + } + for (var i = 0; i < this._palette.length; i++) { + this._palette[i][3] = i < data.length ? data.readUInt8(i) : 0xff; + } + } + + // for colorType 0 (grayscale) and 2 (rgb) + // there might be one gray/color defined as transparent + + this._handleChunkEnd(); +}; + +Parser.prototype._handleGAMA = function(length) { + this.read(length, this._parseGAMA.bind(this)); +}; +Parser.prototype._parseGAMA = function(data) { + + this._crc.write(data); + this.emit('gamma', data.readUInt32BE(0) / 100000); + + this._handleChunkEnd(); +}; + +Parser.prototype._handleIDAT = function(length) { + this.read(-length, this._parseIDAT.bind(this, length)); +}; +Parser.prototype._parseIDAT = function(length, data) { + + this._crc.write(data); + + if (this._colorType == 3 && this._palette.length == 0) + throw new Error('Expected palette not found'); + + if (!this._inflate) { + this._inflate = zlib.createInflate(); + + this._inflate.on('error', this.emit.bind(this, 'error')); + this._filter.on('complete', this._reverseFiltered.bind(this)); + + this._inflate.pipe(this._filter); + } + + this._inflate.write(data); + length -= data.length; + + if (length > 0) + this._handleIDAT(length); + else + this._handleChunkEnd(); +}; + + +Parser.prototype._handleIEND = function(length) { + this.read(length, this._parseIEND.bind(this)); +}; +Parser.prototype._parseIEND = function(data) { + + this._crc.write(data); + + // no more data to inflate + this._inflate.end(); + + this._hasIEND = true; + this._handleChunkEnd(); +}; + + +var colorTypeToBppMap = { + 0: 1, + 2: 3, + 3: 1, + 4: 2, + 6: 4 +}; + +Parser.prototype._reverseFiltered = function(data, width, height) { + + if (this._colorType == 3) { // paletted + + // use values from palette + var pxLineLength = width << 2; + + for (var y = 0; y < height; y++) { + var pxRowPos = y * pxLineLength; + + for (var x = 0; x < width; x++) { + var pxPos = pxRowPos + (x << 2), + color = this._palette[data[pxPos]]; + + for (var i = 0; i < 4; i++) + data[pxPos + i] = color[i]; + } + } + } + + this.emit('parsed', data); +}; + +}).call(this,require("buffer").Buffer) +},{"./chunkstream":388,"./constants":389,"./crc":390,"./filter":391,"buffer":297,"util":523,"zlib":295}],394:[function(require,module,exports){ +(function (process,Buffer){ +// Copyright (c) 2012 Kuba Niegowski +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +'use strict'; + + +var util = require('util'), + Stream = require('stream'), + Parser = require('./parser'), + Packer = require('./packer'); + + +var PNG = exports.PNG = function(options) { + Stream.call(this); + + options = options || {}; + + this.width = options.width || 0; + this.height = options.height || 0; + + this.data = this.width > 0 && this.height > 0 + ? new Buffer(4 * this.width * this.height) : null; + + if(options.fill && this.data){this.data.fill(0)}; + + this.gamma = 0; + this.readable = this.writable = true; + + this._parser = new Parser(options || {}); + + this._parser.on('error', this.emit.bind(this, 'error')); + this._parser.on('close', this._handleClose.bind(this)); + this._parser.on('metadata', this._metadata.bind(this)); + this._parser.on('gamma', this._gamma.bind(this)); + this._parser.on('parsed', function(data) { + this.data = data; + this.emit('parsed', data); + }.bind(this)); + + this._packer = new Packer(options); + this._packer.on('data', this.emit.bind(this, 'data')); + this._packer.on('end', this.emit.bind(this, 'end')); + this._parser.on('close', this._handleClose.bind(this)); + this._packer.on('error', this.emit.bind(this, 'error')); + +}; +util.inherits(PNG, Stream); + + +PNG.prototype.pack = function() { + + process.nextTick(function() { + this._packer.pack(this.data, this.width, this.height); + }.bind(this)); + + return this; +}; + + +PNG.prototype.parse = function(data, callback) { + + if (callback) { + var onParsed = null, onError = null; + + this.once('parsed', onParsed = function(data) { + this.removeListener('error', onError); + + this.data = data; + callback(null, this); + + }.bind(this)); + + this.once('error', onError = function(err) { + this.removeListener('parsed', onParsed); + + callback(err, null); + }.bind(this)); + } + + this.end(data); + return this; +}; + +PNG.prototype.write = function(data) { + this._parser.write(data); + return true; +}; + +PNG.prototype.end = function(data) { + this._parser.end(data); +}; + +PNG.prototype._metadata = function(metadata) { + this.width = metadata.width; + this.height = metadata.height; + this.data = metadata.data; + + delete metadata.data; + this.emit('metadata', metadata); +}; + +PNG.prototype._gamma = function(gamma) { + this.gamma = gamma; +}; + +PNG.prototype._handleClose = function() { + if (!this._parser.writable && !this._packer.readable) + this.emit('close'); +}; + + +PNG.prototype.bitblt = function(dst, sx, sy, w, h, dx, dy) { + + var src = this; + + if (sx > src.width || sy > src.height + || sx + w > src.width || sy + h > src.height) + throw new Error('bitblt reading outside image'); + if (dx > dst.width || dy > dst.height + || dx + w > dst.width || dy + h > dst.height) + throw new Error('bitblt writing outside image'); + + for (var y = 0; y < h; y++) { + src.data.copy(dst.data, + ((dy + y) * dst.width + dx) << 2, + ((sy + y) * src.width + sx) << 2, + ((sy + y) * src.width + sx + w) << 2 + ); + } + + return this; +}; + +}).call(this,require('_process'),require("buffer").Buffer) +},{"./packer":392,"./parser":393,"_process":432,"buffer":297,"stream":503,"util":523}],395:[function(require,module,exports){ +(function (process){ +'use strict'; +const path = require('path'); +const pathKey = require('path-key'); + +module.exports = opts => { + opts = Object.assign({ + cwd: process.cwd(), + path: process.env[pathKey()] + }, opts); + + let prev; + let pth = path.resolve(opts.cwd); + const ret = []; + + while (prev !== pth) { + ret.push(path.join(pth, 'node_modules/.bin')); + prev = pth; + pth = path.resolve(pth, '..'); + } + + // ensure the running `node` binary is used + ret.push(path.dirname(process.execPath)); + + return ret.concat(opts.path).join(path.delimiter); +}; + +module.exports.env = opts => { + opts = Object.assign({ + env: process.env + }, opts); + + const env = Object.assign({}, opts.env); + const path = pathKey({env}); + + opts.path = env[path]; + env[path] = module.exports(opts); + + return env; +}; + +}).call(this,require('_process')) +},{"_process":432,"path":402,"path-key":404}],396:[function(require,module,exports){ +// (c) Dean McNamee , 2013. +// +// https://github.com/deanm/omggif +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// omggif is a JavaScript implementation of a GIF 89a encoder and decoder, +// including animation and compression. It does not rely on any specific +// underlying system, so should run in the browser, Node, or Plask. + +"use strict"; + +function GifWriter(buf, width, height, gopts) { + var p = 0; + + var gopts = gopts === undefined ? { } : gopts; + var loop_count = gopts.loop === undefined ? null : gopts.loop; + var global_palette = gopts.palette === undefined ? null : gopts.palette; + + if (width <= 0 || height <= 0 || width > 65535 || height > 65535) + throw new Error("Width/Height invalid."); + + function check_palette_and_num_colors(palette) { + var num_colors = palette.length; + if (num_colors < 2 || num_colors > 256 || num_colors & (num_colors-1)) { + throw new Error( + "Invalid code/color length, must be power of 2 and 2 .. 256."); + } + return num_colors; + } + + // - Header. + buf[p++] = 0x47; buf[p++] = 0x49; buf[p++] = 0x46; // GIF + buf[p++] = 0x38; buf[p++] = 0x39; buf[p++] = 0x61; // 89a + + // Handling of Global Color Table (palette) and background index. + var gp_num_colors_pow2 = 0; + var background = 0; + if (global_palette !== null) { + var gp_num_colors = check_palette_and_num_colors(global_palette); + while (gp_num_colors >>= 1) ++gp_num_colors_pow2; + gp_num_colors = 1 << gp_num_colors_pow2; + --gp_num_colors_pow2; + if (gopts.background !== undefined) { + background = gopts.background; + if (background >= gp_num_colors) + throw new Error("Background index out of range."); + // The GIF spec states that a background index of 0 should be ignored, so + // this is probably a mistake and you really want to set it to another + // slot in the palette. But actually in the end most browsers, etc end + // up ignoring this almost completely (including for dispose background). + if (background === 0) + throw new Error("Background index explicitly passed as 0."); + } + } + + // - Logical Screen Descriptor. + // NOTE(deanm): w/h apparently ignored by implementations, but set anyway. + buf[p++] = width & 0xff; buf[p++] = width >> 8 & 0xff; + buf[p++] = height & 0xff; buf[p++] = height >> 8 & 0xff; + // NOTE: Indicates 0-bpp original color resolution (unused?). + buf[p++] = (global_palette !== null ? 0x80 : 0) | // Global Color Table Flag. + gp_num_colors_pow2; // NOTE: No sort flag (unused?). + buf[p++] = background; // Background Color Index. + buf[p++] = 0; // Pixel aspect ratio (unused?). + + // - Global Color Table + if (global_palette !== null) { + for (var i = 0, il = global_palette.length; i < il; ++i) { + var rgb = global_palette[i]; + buf[p++] = rgb >> 16 & 0xff; + buf[p++] = rgb >> 8 & 0xff; + buf[p++] = rgb & 0xff; + } + } + + if (loop_count !== null) { // Netscape block for looping. + if (loop_count < 0 || loop_count > 65535) + throw new Error("Loop count invalid.") + // Extension code, label, and length. + buf[p++] = 0x21; buf[p++] = 0xff; buf[p++] = 0x0b; + // NETSCAPE2.0 + buf[p++] = 0x4e; buf[p++] = 0x45; buf[p++] = 0x54; buf[p++] = 0x53; + buf[p++] = 0x43; buf[p++] = 0x41; buf[p++] = 0x50; buf[p++] = 0x45; + buf[p++] = 0x32; buf[p++] = 0x2e; buf[p++] = 0x30; + // Sub-block + buf[p++] = 0x03; buf[p++] = 0x01; + buf[p++] = loop_count & 0xff; buf[p++] = loop_count >> 8 & 0xff; + buf[p++] = 0x00; // Terminator. + } + + + var ended = false; + + this.addFrame = function(x, y, w, h, indexed_pixels, opts) { + if (ended === true) { --p; ended = false; } // Un-end. + + opts = opts === undefined ? { } : opts; + + // TODO(deanm): Bounds check x, y. Do they need to be within the virtual + // canvas width/height, I imagine? + if (x < 0 || y < 0 || x > 65535 || y > 65535) + throw new Error("x/y invalid.") + + if (w <= 0 || h <= 0 || w > 65535 || h > 65535) + throw new Error("Width/Height invalid.") + + if (indexed_pixels.length < w * h) + throw new Error("Not enough pixels for the frame size."); + + var using_local_palette = true; + var palette = opts.palette; + if (palette === undefined || palette === null) { + using_local_palette = false; + palette = global_palette; + } + + if (palette === undefined || palette === null) + throw new Error("Must supply either a local or global palette."); + + var num_colors = check_palette_and_num_colors(palette); + + // Compute the min_code_size (power of 2), destroying num_colors. + var min_code_size = 0; + while (num_colors >>= 1) ++min_code_size; + num_colors = 1 << min_code_size; // Now we can easily get it back. + + var delay = opts.delay === undefined ? 0 : opts.delay; + + // From the spec: + // 0 - No disposal specified. The decoder is + // not required to take any action. + // 1 - Do not dispose. The graphic is to be left + // in place. + // 2 - Restore to background color. The area used by the + // graphic must be restored to the background color. + // 3 - Restore to previous. The decoder is required to + // restore the area overwritten by the graphic with + // what was there prior to rendering the graphic. + // 4-7 - To be defined. + // NOTE(deanm): Dispose background doesn't really work, apparently most + // browsers ignore the background palette index and clear to transparency. + var disposal = opts.disposal === undefined ? 0 : opts.disposal; + if (disposal < 0 || disposal > 3) // 4-7 is reserved. + throw new Error("Disposal out of range."); + + var use_transparency = false; + var transparent_index = 0; + if (opts.transparent !== undefined && opts.transparent !== null) { + use_transparency = true; + transparent_index = opts.transparent; + if (transparent_index < 0 || transparent_index >= num_colors) + throw new Error("Transparent color index."); + } + + if (disposal !== 0 || use_transparency || delay !== 0) { + // - Graphics Control Extension + buf[p++] = 0x21; buf[p++] = 0xf9; // Extension / Label. + buf[p++] = 4; // Byte size. + + buf[p++] = disposal << 2 | (use_transparency === true ? 1 : 0); + buf[p++] = delay & 0xff; buf[p++] = delay >> 8 & 0xff; + buf[p++] = transparent_index; // Transparent color index. + buf[p++] = 0; // Block Terminator. + } + + // - Image Descriptor + buf[p++] = 0x2c; // Image Seperator. + buf[p++] = x & 0xff; buf[p++] = x >> 8 & 0xff; // Left. + buf[p++] = y & 0xff; buf[p++] = y >> 8 & 0xff; // Top. + buf[p++] = w & 0xff; buf[p++] = w >> 8 & 0xff; + buf[p++] = h & 0xff; buf[p++] = h >> 8 & 0xff; + // NOTE: No sort flag (unused?). + // TODO(deanm): Support interlace. + buf[p++] = using_local_palette === true ? (0x80 | (min_code_size-1)) : 0; + + // - Local Color Table + if (using_local_palette === true) { + for (var i = 0, il = palette.length; i < il; ++i) { + var rgb = palette[i]; + buf[p++] = rgb >> 16 & 0xff; + buf[p++] = rgb >> 8 & 0xff; + buf[p++] = rgb & 0xff; + } + } + + p = GifWriterOutputLZWCodeStream( + buf, p, min_code_size < 2 ? 2 : min_code_size, indexed_pixels); + + return p; + }; + + this.end = function() { + if (ended === false) { + buf[p++] = 0x3b; // Trailer. + ended = true; + } + return p; + }; + + this.getOutputBuffer = function() { return buf; }; + this.setOutputBuffer = function(v) { buf = v; }; + this.getOutputBufferPosition = function() { return p; }; + this.setOutputBufferPosition = function(v) { p = v; }; +} + +// Main compression routine, palette indexes -> LZW code stream. +// |index_stream| must have at least one entry. +function GifWriterOutputLZWCodeStream(buf, p, min_code_size, index_stream) { + buf[p++] = min_code_size; + var cur_subblock = p++; // Pointing at the length field. + + var clear_code = 1 << min_code_size; + var code_mask = clear_code - 1; + var eoi_code = clear_code + 1; + var next_code = eoi_code + 1; + + var cur_code_size = min_code_size + 1; // Number of bits per code. + var cur_shift = 0; + // We have at most 12-bit codes, so we should have to hold a max of 19 + // bits here (and then we would write out). + var cur = 0; + + function emit_bytes_to_buffer(bit_block_size) { + while (cur_shift >= bit_block_size) { + buf[p++] = cur & 0xff; + cur >>= 8; cur_shift -= 8; + if (p === cur_subblock + 256) { // Finished a subblock. + buf[cur_subblock] = 255; + cur_subblock = p++; + } + } + } + + function emit_code(c) { + cur |= c << cur_shift; + cur_shift += cur_code_size; + emit_bytes_to_buffer(8); + } + + // I am not an expert on the topic, and I don't want to write a thesis. + // However, it is good to outline here the basic algorithm and the few data + // structures and optimizations here that make this implementation fast. + // The basic idea behind LZW is to build a table of previously seen runs + // addressed by a short id (herein called output code). All data is + // referenced by a code, which represents one or more values from the + // original input stream. All input bytes can be referenced as the same + // value as an output code. So if you didn't want any compression, you + // could more or less just output the original bytes as codes (there are + // some details to this, but it is the idea). In order to achieve + // compression, values greater then the input range (codes can be up to + // 12-bit while input only 8-bit) represent a sequence of previously seen + // inputs. The decompressor is able to build the same mapping while + // decoding, so there is always a shared common knowledge between the + // encoding and decoder, which is also important for "timing" aspects like + // how to handle variable bit width code encoding. + // + // One obvious but very important consequence of the table system is there + // is always a unique id (at most 12-bits) to map the runs. 'A' might be + // 4, then 'AA' might be 10, 'AAA' 11, 'AAAA' 12, etc. This relationship + // can be used for an effecient lookup strategy for the code mapping. We + // need to know if a run has been seen before, and be able to map that run + // to the output code. Since we start with known unique ids (input bytes), + // and then from those build more unique ids (table entries), we can + // continue this chain (almost like a linked list) to always have small + // integer values that represent the current byte chains in the encoder. + // This means instead of tracking the input bytes (AAAABCD) to know our + // current state, we can track the table entry for AAAABC (it is guaranteed + // to exist by the nature of the algorithm) and the next character D. + // Therefor the tuple of (table_entry, byte) is guaranteed to also be + // unique. This allows us to create a simple lookup key for mapping input + // sequences to codes (table indices) without having to store or search + // any of the code sequences. So if 'AAAA' has a table entry of 12, the + // tuple of ('AAAA', K) for any input byte K will be unique, and can be our + // key. This leads to a integer value at most 20-bits, which can always + // fit in an SMI value and be used as a fast sparse array / object key. + + // Output code for the current contents of the index buffer. + var ib_code = index_stream[0] & code_mask; // Load first input index. + var code_table = { }; // Key'd on our 20-bit "tuple". + + emit_code(clear_code); // Spec says first code should be a clear code. + + // First index already loaded, process the rest of the stream. + for (var i = 1, il = index_stream.length; i < il; ++i) { + var k = index_stream[i] & code_mask; + var cur_key = ib_code << 8 | k; // (prev, k) unique tuple. + var cur_code = code_table[cur_key]; // buffer + k. + + // Check if we have to create a new code table entry. + if (cur_code === undefined) { // We don't have buffer + k. + // Emit index buffer (without k). + // This is an inline version of emit_code, because this is the core + // writing routine of the compressor (and V8 cannot inline emit_code + // because it is a closure here in a different context). Additionally + // we can call emit_byte_to_buffer less often, because we can have + // 30-bits (from our 31-bit signed SMI), and we know our codes will only + // be 12-bits, so can safely have 18-bits there without overflow. + // emit_code(ib_code); + cur |= ib_code << cur_shift; + cur_shift += cur_code_size; + while (cur_shift >= 8) { + buf[p++] = cur & 0xff; + cur >>= 8; cur_shift -= 8; + if (p === cur_subblock + 256) { // Finished a subblock. + buf[cur_subblock] = 255; + cur_subblock = p++; + } + } + + if (next_code === 4096) { // Table full, need a clear. + emit_code(clear_code); + next_code = eoi_code + 1; + cur_code_size = min_code_size + 1; + code_table = { }; + } else { // Table not full, insert a new entry. + // Increase our variable bit code sizes if necessary. This is a bit + // tricky as it is based on "timing" between the encoding and + // decoder. From the encoders perspective this should happen after + // we've already emitted the index buffer and are about to create the + // first table entry that would overflow our current code bit size. + if (next_code >= (1 << cur_code_size)) ++cur_code_size; + code_table[cur_key] = next_code++; // Insert into code table. + } + + ib_code = k; // Index buffer to single input k. + } else { + ib_code = cur_code; // Index buffer to sequence in code table. + } + } + + emit_code(ib_code); // There will still be something in the index buffer. + emit_code(eoi_code); // End Of Information. + + // Flush / finalize the sub-blocks stream to the buffer. + emit_bytes_to_buffer(1); + + // Finish the sub-blocks, writing out any unfinished lengths and + // terminating with a sub-block of length 0. If we have already started + // but not yet used a sub-block it can just become the terminator. + if (cur_subblock + 1 === p) { // Started but unused. + buf[cur_subblock] = 0; + } else { // Started and used, write length and additional terminator block. + buf[cur_subblock] = p - cur_subblock - 1; + buf[p++] = 0; + } + return p; +} + +function GifReader(buf) { + var p = 0; + + // - Header (GIF87a or GIF89a). + if (buf[p++] !== 0x47 || buf[p++] !== 0x49 || buf[p++] !== 0x46 || + buf[p++] !== 0x38 || (buf[p++]+1 & 0xfd) !== 0x38 || buf[p++] !== 0x61) { + throw new Error("Invalid GIF 87a/89a header."); + } + + // - Logical Screen Descriptor. + var width = buf[p++] | buf[p++] << 8; + var height = buf[p++] | buf[p++] << 8; + var pf0 = buf[p++]; // . + var global_palette_flag = pf0 >> 7; + var num_global_colors_pow2 = pf0 & 0x7; + var num_global_colors = 1 << (num_global_colors_pow2 + 1); + var background = buf[p++]; + buf[p++]; // Pixel aspect ratio (unused?). + + var global_palette_offset = null; + var global_palette_size = null; + + if (global_palette_flag) { + global_palette_offset = p; + global_palette_size = num_global_colors; + p += num_global_colors * 3; // Seek past palette. + } + + var no_eof = true; + + var frames = [ ]; + + var delay = 0; + var transparent_index = null; + var disposal = 0; // 0 - No disposal specified. + var loop_count = null; + + this.width = width; + this.height = height; + + while (no_eof && p < buf.length) { + switch (buf[p++]) { + case 0x21: // Graphics Control Extension Block + switch (buf[p++]) { + case 0xff: // Application specific block + // Try if it's a Netscape block (with animation loop counter). + if (buf[p ] !== 0x0b || // 21 FF already read, check block size. + // NETSCAPE2.0 + buf[p+1 ] == 0x4e && buf[p+2 ] == 0x45 && buf[p+3 ] == 0x54 && + buf[p+4 ] == 0x53 && buf[p+5 ] == 0x43 && buf[p+6 ] == 0x41 && + buf[p+7 ] == 0x50 && buf[p+8 ] == 0x45 && buf[p+9 ] == 0x32 && + buf[p+10] == 0x2e && buf[p+11] == 0x30 && + // Sub-block + buf[p+12] == 0x03 && buf[p+13] == 0x01 && buf[p+16] == 0) { + p += 14; + loop_count = buf[p++] | buf[p++] << 8; + p++; // Skip terminator. + } else { // We don't know what it is, just try to get past it. + p += 12; + while (true) { // Seek through subblocks. + var block_size = buf[p++]; + // Bad block size (ex: undefined from an out of bounds read). + if (!(block_size >= 0)) throw Error("Invalid block size"); + if (block_size === 0) break; // 0 size is terminator + p += block_size; + } + } + break; + + case 0xf9: // Graphics Control Extension + if (buf[p++] !== 0x4 || buf[p+4] !== 0) + throw new Error("Invalid graphics extension block."); + var pf1 = buf[p++]; + delay = buf[p++] | buf[p++] << 8; + transparent_index = buf[p++]; + if ((pf1 & 1) === 0) transparent_index = null; + disposal = pf1 >> 2 & 0x7; + p++; // Skip terminator. + break; + + case 0xfe: // Comment Extension. + while (true) { // Seek through subblocks. + var block_size = buf[p++]; + // Bad block size (ex: undefined from an out of bounds read). + if (!(block_size >= 0)) throw Error("Invalid block size"); + if (block_size === 0) break; // 0 size is terminator + // console.log(buf.slice(p, p+block_size).toString('ascii')); + p += block_size; + } + break; + + default: + throw new Error( + "Unknown graphic control label: 0x" + buf[p-1].toString(16)); + } + break; + + case 0x2c: // Image Descriptor. + var x = buf[p++] | buf[p++] << 8; + var y = buf[p++] | buf[p++] << 8; + var w = buf[p++] | buf[p++] << 8; + var h = buf[p++] | buf[p++] << 8; + var pf2 = buf[p++]; + var local_palette_flag = pf2 >> 7; + var interlace_flag = pf2 >> 6 & 1; + var num_local_colors_pow2 = pf2 & 0x7; + var num_local_colors = 1 << (num_local_colors_pow2 + 1); + var palette_offset = global_palette_offset; + var palette_size = global_palette_size; + var has_local_palette = false; + if (local_palette_flag) { + var has_local_palette = true; + palette_offset = p; // Override with local palette. + palette_size = num_local_colors; + p += num_local_colors * 3; // Seek past palette. + } + + var data_offset = p; + + p++; // codesize + while (true) { + var block_size = buf[p++]; + // Bad block size (ex: undefined from an out of bounds read). + if (!(block_size >= 0)) throw Error("Invalid block size"); + if (block_size === 0) break; // 0 size is terminator + p += block_size; + } + + frames.push({x: x, y: y, width: w, height: h, + has_local_palette: has_local_palette, + palette_offset: palette_offset, + palette_size: palette_size, + data_offset: data_offset, + data_length: p - data_offset, + transparent_index: transparent_index, + interlaced: !!interlace_flag, + delay: delay, + disposal: disposal}); + break; + + case 0x3b: // Trailer Marker (end of file). + no_eof = false; + break; + + default: + throw new Error("Unknown gif block: 0x" + buf[p-1].toString(16)); + break; + } + } + + this.numFrames = function() { + return frames.length; + }; + + this.loopCount = function() { + return loop_count; + }; + + this.frameInfo = function(frame_num) { + if (frame_num < 0 || frame_num >= frames.length) + throw new Error("Frame index out of range."); + return frames[frame_num]; + } + + this.decodeAndBlitFrameBGRA = function(frame_num, pixels) { + var frame = this.frameInfo(frame_num); + var num_pixels = frame.width * frame.height; + var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices. + GifReaderLZWOutputIndexStream( + buf, frame.data_offset, index_stream, num_pixels); + var palette_offset = frame.palette_offset; + + // NOTE(deanm): It seems to be much faster to compare index to 256 than + // to === null. Not sure why, but CompareStub_EQ_STRICT shows up high in + // the profile, not sure if it's related to using a Uint8Array. + var trans = frame.transparent_index; + if (trans === null) trans = 256; + + // We are possibly just blitting to a portion of the entire frame. + // That is a subrect within the framerect, so the additional pixels + // must be skipped over after we finished a scanline. + var framewidth = frame.width; + var framestride = width - framewidth; + var xleft = framewidth; // Number of subrect pixels left in scanline. + + // Output indicies of the top left and bottom right corners of the subrect. + var opbeg = ((frame.y * width) + frame.x) * 4; + var opend = ((frame.y + frame.height) * width + frame.x) * 4; + var op = opbeg; + + var scanstride = framestride * 4; + + // Use scanstride to skip past the rows when interlacing. This is skipping + // 7 rows for the first two passes, then 3 then 1. + if (frame.interlaced === true) { + scanstride += width * 4 * 7; // Pass 1. + } + + var interlaceskip = 8; // Tracking the row interval in the current pass. + + for (var i = 0, il = index_stream.length; i < il; ++i) { + var index = index_stream[i]; + + if (xleft === 0) { // Beginning of new scan line + op += scanstride; + xleft = framewidth; + if (op >= opend) { // Catch the wrap to switch passes when interlacing. + scanstride = framestride * 4 + width * 4 * (interlaceskip-1); + // interlaceskip / 2 * 4 is interlaceskip << 1. + op = opbeg + (framewidth + framestride) * (interlaceskip << 1); + interlaceskip >>= 1; + } + } + + if (index === trans) { + op += 4; + } else { + var r = buf[palette_offset + index * 3]; + var g = buf[palette_offset + index * 3 + 1]; + var b = buf[palette_offset + index * 3 + 2]; + pixels[op++] = b; + pixels[op++] = g; + pixels[op++] = r; + pixels[op++] = 255; + } + --xleft; + } + }; + + // I will go to copy and paste hell one day... + this.decodeAndBlitFrameRGBA = function(frame_num, pixels) { + var frame = this.frameInfo(frame_num); + var num_pixels = frame.width * frame.height; + var index_stream = new Uint8Array(num_pixels); // At most 8-bit indices. + GifReaderLZWOutputIndexStream( + buf, frame.data_offset, index_stream, num_pixels); + var palette_offset = frame.palette_offset; + + // NOTE(deanm): It seems to be much faster to compare index to 256 than + // to === null. Not sure why, but CompareStub_EQ_STRICT shows up high in + // the profile, not sure if it's related to using a Uint8Array. + var trans = frame.transparent_index; + if (trans === null) trans = 256; + + // We are possibly just blitting to a portion of the entire frame. + // That is a subrect within the framerect, so the additional pixels + // must be skipped over after we finished a scanline. + var framewidth = frame.width; + var framestride = width - framewidth; + var xleft = framewidth; // Number of subrect pixels left in scanline. + + // Output indicies of the top left and bottom right corners of the subrect. + var opbeg = ((frame.y * width) + frame.x) * 4; + var opend = ((frame.y + frame.height) * width + frame.x) * 4; + var op = opbeg; + + var scanstride = framestride * 4; + + // Use scanstride to skip past the rows when interlacing. This is skipping + // 7 rows for the first two passes, then 3 then 1. + if (frame.interlaced === true) { + scanstride += width * 4 * 7; // Pass 1. + } + + var interlaceskip = 8; // Tracking the row interval in the current pass. + + for (var i = 0, il = index_stream.length; i < il; ++i) { + var index = index_stream[i]; + + if (xleft === 0) { // Beginning of new scan line + op += scanstride; + xleft = framewidth; + if (op >= opend) { // Catch the wrap to switch passes when interlacing. + scanstride = framestride * 4 + width * 4 * (interlaceskip-1); + // interlaceskip / 2 * 4 is interlaceskip << 1. + op = opbeg + (framewidth + framestride) * (interlaceskip << 1); + interlaceskip >>= 1; + } + } + + if (index === trans) { + op += 4; + } else { + var r = buf[palette_offset + index * 3]; + var g = buf[palette_offset + index * 3 + 1]; + var b = buf[palette_offset + index * 3 + 2]; + pixels[op++] = r; + pixels[op++] = g; + pixels[op++] = b; + pixels[op++] = 255; + } + --xleft; + } + }; +} + +function GifReaderLZWOutputIndexStream(code_stream, p, output, output_length) { + var min_code_size = code_stream[p++]; + + var clear_code = 1 << min_code_size; + var eoi_code = clear_code + 1; + var next_code = eoi_code + 1; + + var cur_code_size = min_code_size + 1; // Number of bits per code. + // NOTE: This shares the same name as the encoder, but has a different + // meaning here. Here this masks each code coming from the code stream. + var code_mask = (1 << cur_code_size) - 1; + var cur_shift = 0; + var cur = 0; + + var op = 0; // Output pointer. + + var subblock_size = code_stream[p++]; + + // TODO(deanm): Would using a TypedArray be any faster? At least it would + // solve the fast mode / backing store uncertainty. + // var code_table = Array(4096); + var code_table = new Int32Array(4096); // Can be signed, we only use 20 bits. + + var prev_code = null; // Track code-1. + + while (true) { + // Read up to two bytes, making sure we always 12-bits for max sized code. + while (cur_shift < 16) { + if (subblock_size === 0) break; // No more data to be read. + + cur |= code_stream[p++] << cur_shift; + cur_shift += 8; + + if (subblock_size === 1) { // Never let it get to 0 to hold logic above. + subblock_size = code_stream[p++]; // Next subblock. + } else { + --subblock_size; + } + } + + // TODO(deanm): We should never really get here, we should have received + // and EOI. + if (cur_shift < cur_code_size) + break; + + var code = cur & code_mask; + cur >>= cur_code_size; + cur_shift -= cur_code_size; + + // TODO(deanm): Maybe should check that the first code was a clear code, + // at least this is what you're supposed to do. But actually our encoder + // now doesn't emit a clear code first anyway. + if (code === clear_code) { + // We don't actually have to clear the table. This could be a good idea + // for greater error checking, but we don't really do any anyway. We + // will just track it with next_code and overwrite old entries. + + next_code = eoi_code + 1; + cur_code_size = min_code_size + 1; + code_mask = (1 << cur_code_size) - 1; + + // Don't update prev_code ? + prev_code = null; + continue; + } else if (code === eoi_code) { + break; + } + + // We have a similar situation as the decoder, where we want to store + // variable length entries (code table entries), but we want to do in a + // faster manner than an array of arrays. The code below stores sort of a + // linked list within the code table, and then "chases" through it to + // construct the dictionary entries. When a new entry is created, just the + // last byte is stored, and the rest (prefix) of the entry is only + // referenced by its table entry. Then the code chases through the + // prefixes until it reaches a single byte code. We have to chase twice, + // first to compute the length, and then to actually copy the data to the + // output (backwards, since we know the length). The alternative would be + // storing something in an intermediate stack, but that doesn't make any + // more sense. I implemented an approach where it also stored the length + // in the code table, although it's a bit tricky because you run out of + // bits (12 + 12 + 8), but I didn't measure much improvements (the table + // entries are generally not the long). Even when I created benchmarks for + // very long table entries the complexity did not seem worth it. + // The code table stores the prefix entry in 12 bits and then the suffix + // byte in 8 bits, so each entry is 20 bits. + + var chase_code = code < next_code ? code : prev_code; + + // Chase what we will output, either {CODE} or {CODE-1}. + var chase_length = 0; + var chase = chase_code; + while (chase > clear_code) { + chase = code_table[chase] >> 8; + ++chase_length; + } + + var k = chase; + + var op_end = op + chase_length + (chase_code !== code ? 1 : 0); + if (op_end > output_length) { + console.log("Warning, gif stream longer than expected."); + return; + } + + // Already have the first byte from the chase, might as well write it fast. + output[op++] = k; + + op += chase_length; + var b = op; // Track pointer, writing backwards. + + if (chase_code !== code) // The case of emitting {CODE-1} + k. + output[op++] = k; + + chase = chase_code; + while (chase_length--) { + chase = code_table[chase]; + output[--b] = chase & 0xff; // Write backwards. + chase >>= 8; // Pull down to the prefix code. + } + + if (prev_code !== null && next_code < 4096) { + code_table[next_code++] = prev_code << 8 | k; + // TODO(deanm): Figure out this clearing vs code growth logic better. I + // have an feeling that it should just happen somewhere else, for now it + // is awkward between when we grow past the max and then hit a clear code. + // For now just check if we hit the max 12-bits (then a clear code should + // follow, also of course encoded in 12-bits). + if (next_code >= code_mask+1 && cur_code_size < 12) { + ++cur_code_size; + code_mask = code_mask << 1 | 1; + } + } + + prev_code = code; + } + + if (op !== output_length) { + console.log("Warning, gif stream shorter than expected."); + } + + return output; +} + +// CommonJS. +try { exports.GifWriter = GifWriter; exports.GifReader = GifReader } catch(e) {} + +},{}],397:[function(require,module,exports){ +var wrappy = require('wrappy') +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + +},{"wrappy":531}],398:[function(require,module,exports){ +'use strict'; +const mimicFn = require('mimic-fn'); + +const calledFunctions = new WeakMap(); + +const oneTime = (fn, options = {}) => { + if (typeof fn !== 'function') { + throw new TypeError('Expected a function'); + } + + let ret; + let isCalled = false; + let callCount = 0; + const functionName = fn.displayName || fn.name || ''; + + const onetime = function (...args) { + calledFunctions.set(onetime, ++callCount); + + if (isCalled) { + if (options.throw === true) { + throw new Error(`Function \`${functionName}\` can only be called once`); + } + + return ret; + } + + isCalled = true; + ret = fn.apply(this, args); + fn = null; + + return ret; + }; + + mimicFn(onetime, fn); + calledFunctions.set(onetime, callCount); + + return onetime; +}; + +module.exports = oneTime; +// TODO: Remove this for the next major release +module.exports.default = oneTime; + +module.exports.callCount = fn => { + if (!calledFunctions.has(fn)) { + throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`); + } + + return calledFunctions.get(fn); +}; + +},{"mimic-fn":382}],399:[function(require,module,exports){ +(function (process,global){ +module.exports=function(e){var t={};function r(a){if(t[a])return t[a].exports;var n=t[a]={i:a,l:!1,exports:{}};return e[a].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=e,r.c=t,r.d=function(e,t,a){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:a})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var a=Object.create(null);if(r.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)r.d(a,n,function(t){return e[t]}.bind(null,n));return a},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}([function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=r(1),n=r(6),i=r(15),o=r(2);t.validatorSymbol=Symbol("validators");t.Predicate=class{constructor(e,t={}){this.type=e,this.options=t,this.context={validators:[]},this.context={...this.context,...this.options};const r=this.type[0].toLowerCase()+this.type.slice(1);this.addValidator({message:(e,t)=>`Expected ${(null==t?void 0:t.slice(this.type.length+1))||"argument"} to be of type \`${this.type}\` but received type \`${a.default(e)}\``,validator:e=>a.default[r](e)})}[o.testSymbol](e,t,r){for(const{validator:a,message:i}of this.context.validators){if(!0===this.options.optional&&void 0===e)continue;const o=a(e);if(!0===o)continue;let s=r;throw"function"==typeof r&&(s=r()),s=s?`${this.type} \`${s}\``:this.type,new n.ArgumentError(i(e,s,o),t)}}get[t.validatorSymbol](){return this.context.validators}get not(){return i.not(this)}validate(e){return this.addValidator({message:(e,t,r)=>"string"==typeof r?`(${t}) ${r}`:r(t),validator:t=>{const{message:r,validator:a}=e(t);return!!a||r}})}is(e){return this.addValidator({message:(e,t,r)=>r?`(${t}) ${r}`:`Expected ${t} \`${e}\` to pass custom validation function`,validator:e})}addValidator(e){return this.context.validators.push(e),this}}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const{toString:a}=Object.prototype,n=e=>t=>typeof t===e,i=e=>{const t=a.call(e).slice(8,-1);if(t)return t},o=e=>t=>i(t)===e;function s(e){switch(e){case null:return"null";case!0:case!1:return"boolean"}switch(typeof e){case"undefined":return"undefined";case"string":return"string";case"number":return"number";case"bigint":return"bigint";case"symbol":return"symbol"}if(s.function_(e))return"Function";if(s.observable(e))return"Observable";if(s.array(e))return"Array";if(s.buffer(e))return"Buffer";const t=i(e);if(t)return t;if(e instanceof String||e instanceof Boolean||e instanceof Number)throw new TypeError("Please don't use object wrappers for primitive types");return"Object"}s.undefined=n("undefined"),s.string=n("string");const d=n("number");s.number=e=>d(e)&&!s.nan(e),s.bigint=n("bigint"),s.function_=n("function"),s.null_=e=>null===e,s.class_=e=>s.function_(e)&&e.toString().startsWith("class "),s.boolean=e=>!0===e||!1===e,s.symbol=n("symbol"),s.numericString=e=>s.string(e)&&e.length>0&&!Number.isNaN(Number(e)),s.array=Array.isArray,s.buffer=e=>!s.nullOrUndefined(e)&&!s.nullOrUndefined(e.constructor)&&s.function_(e.constructor.isBuffer)&&e.constructor.isBuffer(e),s.nullOrUndefined=e=>s.null_(e)||s.undefined(e),s.object=e=>!s.null_(e)&&("object"==typeof e||s.function_(e)),s.iterable=e=>!s.nullOrUndefined(e)&&s.function_(e[Symbol.iterator]),s.asyncIterable=e=>!s.nullOrUndefined(e)&&s.function_(e[Symbol.asyncIterator]),s.generator=e=>s.iterable(e)&&s.function_(e.next)&&s.function_(e.throw),s.asyncGenerator=e=>s.asyncIterable(e)&&s.function_(e.next)&&s.function_(e.throw),s.nativePromise=e=>o("Promise")(e);s.promise=e=>s.nativePromise(e)||(e=>s.object(e)&&s.function_(e.then)&&s.function_(e.catch))(e),s.generatorFunction=o("GeneratorFunction"),s.asyncGeneratorFunction=e=>"AsyncGeneratorFunction"===i(e),s.asyncFunction=e=>"AsyncFunction"===i(e),s.boundFunction=e=>s.function_(e)&&!e.hasOwnProperty("prototype"),s.regExp=o("RegExp"),s.date=o("Date"),s.error=o("Error"),s.map=e=>o("Map")(e),s.set=e=>o("Set")(e),s.weakMap=e=>o("WeakMap")(e),s.weakSet=e=>o("WeakSet")(e),s.int8Array=o("Int8Array"),s.uint8Array=o("Uint8Array"),s.uint8ClampedArray=o("Uint8ClampedArray"),s.int16Array=o("Int16Array"),s.uint16Array=o("Uint16Array"),s.int32Array=o("Int32Array"),s.uint32Array=o("Uint32Array"),s.float32Array=o("Float32Array"),s.float64Array=o("Float64Array"),s.bigInt64Array=o("BigInt64Array"),s.bigUint64Array=o("BigUint64Array"),s.arrayBuffer=o("ArrayBuffer"),s.sharedArrayBuffer=o("SharedArrayBuffer"),s.dataView=o("DataView"),s.directInstanceOf=(e,t)=>Object.getPrototypeOf(e)===t.prototype,s.urlInstance=e=>o("URL")(e),s.urlString=e=>{if(!s.string(e))return!1;try{return new URL(e),!0}catch(e){return!1}},s.truthy=e=>Boolean(e),s.falsy=e=>!e,s.nan=e=>Number.isNaN(e);const c=new Set(["undefined","string","number","bigint","boolean","symbol"]);s.primitive=e=>s.null_(e)||c.has(typeof e),s.integer=e=>Number.isInteger(e),s.safeInteger=e=>Number.isSafeInteger(e),s.plainObject=e=>{if("Object"!==i(e))return!1;const t=Object.getPrototypeOf(e);return null===t||t===Object.getPrototypeOf({})};const u=new Set(["Int8Array","Uint8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array"]);s.typedArray=e=>{const t=i(e);return void 0!==t&&u.has(t)};s.arrayLike=e=>!s.nullOrUndefined(e)&&!s.function_(e)&&(e=>s.safeInteger(e)&&e>=0)(e.length),s.inRange=(e,t)=>{if(s.number(t))return e>=Math.min(0,t)&&e<=Math.max(t,0);if(s.array(t)&&2===t.length)return e>=Math.min(...t)&&e<=Math.max(...t);throw new TypeError(`Invalid range: ${JSON.stringify(t)}`)};const l=["innerHTML","ownerDocument","style","attributes","nodeValue"];s.domElement=e=>s.object(e)&&1===e.nodeType&&s.string(e.nodeName)&&!s.plainObject(e)&&l.every(t=>t in e),s.observable=e=>!!e&&(!(!e[Symbol.observable]||e!==e[Symbol.observable]())||!(!e["@@observable"]||e!==e["@@observable"]())),s.nodeStream=e=>s.object(e)&&s.function_(e.pipe)&&!s.observable(e),s.infinite=e=>e===1/0||e===-1/0;const g=e=>t=>s.integer(t)&&Math.abs(t%2)===e;s.evenInteger=g(0),s.oddInteger=g(1),s.emptyArray=e=>s.array(e)&&0===e.length,s.nonEmptyArray=e=>s.array(e)&&e.length>0,s.emptyString=e=>s.string(e)&&0===e.length,s.nonEmptyString=e=>s.string(e)&&e.length>0;s.emptyStringOrWhitespace=e=>s.emptyString(e)||(e=>s.string(e)&&!1===/\S/.test(e))(e),s.emptyObject=e=>s.object(e)&&!s.map(e)&&!s.set(e)&&0===Object.keys(e).length,s.nonEmptyObject=e=>s.object(e)&&!s.map(e)&&!s.set(e)&&Object.keys(e).length>0,s.emptySet=e=>s.set(e)&&0===e.size,s.nonEmptySet=e=>s.set(e)&&e.size>0,s.emptyMap=e=>s.map(e)&&0===e.size,s.nonEmptyMap=e=>s.map(e)&&e.size>0;const f=(e,t,r)=>{if(!1===s.function_(t))throw new TypeError(`Invalid predicate: ${JSON.stringify(t)}`);if(0===r.length)throw new TypeError("Invalid number of values");return e.call(r,t)};s.any=(e,...t)=>(s.array(e)?e:[e]).some(e=>f(Array.prototype.some,e,t)),s.all=(e,...t)=>f(Array.prototype.every,e,t);const y=(e,t,r)=>{if(!e)throw new TypeError(`Expected value which is \`${t}\`, received value of type \`${s(r)}\`.`)};t.assert={undefined:e=>y(s.undefined(e),"undefined",e),string:e=>y(s.string(e),"string",e),number:e=>y(s.number(e),"number",e),bigint:e=>y(s.bigint(e),"bigint",e),function_:e=>y(s.function_(e),"Function",e),null_:e=>y(s.null_(e),"null",e),class_:e=>y(s.class_(e),"Class",e),boolean:e=>y(s.boolean(e),"boolean",e),symbol:e=>y(s.symbol(e),"symbol",e),numericString:e=>y(s.numericString(e),"string with a number",e),array:e=>y(s.array(e),"Array",e),buffer:e=>y(s.buffer(e),"Buffer",e),nullOrUndefined:e=>y(s.nullOrUndefined(e),"null or undefined",e),object:e=>y(s.object(e),"Object",e),iterable:e=>y(s.iterable(e),"Iterable",e),asyncIterable:e=>y(s.asyncIterable(e),"AsyncIterable",e),generator:e=>y(s.generator(e),"Generator",e),asyncGenerator:e=>y(s.asyncGenerator(e),"AsyncGenerator",e),nativePromise:e=>y(s.nativePromise(e),"native Promise",e),promise:e=>y(s.promise(e),"Promise",e),generatorFunction:e=>y(s.generatorFunction(e),"GeneratorFunction",e),asyncGeneratorFunction:e=>y(s.asyncGeneratorFunction(e),"AsyncGeneratorFunction",e),asyncFunction:e=>y(s.asyncFunction(e),"AsyncFunction",e),boundFunction:e=>y(s.boundFunction(e),"Function",e),regExp:e=>y(s.regExp(e),"RegExp",e),date:e=>y(s.date(e),"Date",e),error:e=>y(s.error(e),"Error",e),map:e=>y(s.map(e),"Map",e),set:e=>y(s.set(e),"Set",e),weakMap:e=>y(s.weakMap(e),"WeakMap",e),weakSet:e=>y(s.weakSet(e),"WeakSet",e),int8Array:e=>y(s.int8Array(e),"Int8Array",e),uint8Array:e=>y(s.uint8Array(e),"Uint8Array",e),uint8ClampedArray:e=>y(s.uint8ClampedArray(e),"Uint8ClampedArray",e),int16Array:e=>y(s.int16Array(e),"Int16Array",e),uint16Array:e=>y(s.uint16Array(e),"Uint16Array",e),int32Array:e=>y(s.int32Array(e),"Int32Array",e),uint32Array:e=>y(s.uint32Array(e),"Uint32Array",e),float32Array:e=>y(s.float32Array(e),"Float32Array",e),float64Array:e=>y(s.float64Array(e),"Float64Array",e),bigInt64Array:e=>y(s.bigInt64Array(e),"BigInt64Array",e),bigUint64Array:e=>y(s.bigUint64Array(e),"BigUint64Array",e),arrayBuffer:e=>y(s.arrayBuffer(e),"ArrayBuffer",e),sharedArrayBuffer:e=>y(s.sharedArrayBuffer(e),"SharedArrayBuffer",e),dataView:e=>y(s.dataView(e),"DataView",e),urlInstance:e=>y(s.urlInstance(e),"URL",e),urlString:e=>y(s.urlString(e),"string with a URL",e),truthy:e=>y(s.truthy(e),"truthy",e),falsy:e=>y(s.falsy(e),"falsy",e),nan:e=>y(s.nan(e),"NaN",e),primitive:e=>y(s.primitive(e),"primitive",e),integer:e=>y(s.integer(e),"integer",e),safeInteger:e=>y(s.safeInteger(e),"integer",e),plainObject:e=>y(s.plainObject(e),"plain object",e),typedArray:e=>y(s.typedArray(e),"TypedArray",e),arrayLike:e=>y(s.arrayLike(e),"array-like",e),domElement:e=>y(s.domElement(e),"Element",e),observable:e=>y(s.observable(e),"Observable",e),nodeStream:e=>y(s.nodeStream(e),"Node.js Stream",e),infinite:e=>y(s.infinite(e),"infinite number",e),emptyArray:e=>y(s.emptyArray(e),"empty array",e),nonEmptyArray:e=>y(s.nonEmptyArray(e),"non-empty array",e),emptyString:e=>y(s.emptyString(e),"empty string",e),nonEmptyString:e=>y(s.nonEmptyString(e),"non-empty string",e),emptyStringOrWhitespace:e=>y(s.emptyStringOrWhitespace(e),"empty string or whitespace",e),emptyObject:e=>y(s.emptyObject(e),"empty object",e),nonEmptyObject:e=>y(s.nonEmptyObject(e),"non-empty object",e),emptySet:e=>y(s.emptySet(e),"empty set",e),nonEmptySet:e=>y(s.nonEmptySet(e),"non-empty set",e),emptyMap:e=>y(s.emptyMap(e),"empty map",e),nonEmptyMap:e=>y(s.nonEmptyMap(e),"non-empty map",e),evenInteger:e=>y(s.evenInteger(e),"even integer",e),oddInteger:e=>y(s.oddInteger(e),"odd integer",e),directInstanceOf:(e,t)=>y(s.directInstanceOf(e,t),"T",e),inRange:(e,t)=>y(s.inRange(e,t),"in range",e),any:(e,...t)=>y(s.any(e,...t),"predicate returns truthy for any value",t),all:(e,...t)=>y(s.all(e,...t),"predicate returns truthy for all values",t)},Object.defineProperties(s,{class:{value:s.class_},function:{value:s.function_},null:{value:s.null_}}),Object.defineProperties(t.assert,{class:{value:t.assert.class_},function:{value:t.assert.function_},null:{value:t.assert.null_}}),t.default=s,e.exports=s,e.exports.default=s,e.exports.assert=t.assert},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.testSymbol=Symbol("test"),t.isPredicate=e=>Boolean(e[t.testSymbol])},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=(e,t,r=5)=>{const a=[];for(const n of t)if(!e.has(n)&&(a.push(n),a.length===r))return a;return 0===a.length||a}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=r(10),n=r(11),i=r(0);t.Predicate=i.Predicate;const o=r(2),s=r(17),d=r(7),c=r(9),u=(e,t,r)=>{if(!o.isPredicate(t)&&"string"!=typeof t)throw new TypeError(`Expected second argument to be a predicate or a string, got \`${typeof t}\``);if(o.isPredicate(t)){const r=a.default();c.default(e,()=>n.inferLabel(r),t)}else c.default(e,t,r)};Object.defineProperties(u,{isValid:{value:(e,t)=>{try{return u(e,t),!0}catch(e){return!1}}},create:{value:(e,t)=>(r,i)=>{if(o.isPredicate(e)){const t=a.default();c.default(r,null!=i?i:()=>n.inferLabel(t),e)}else c.default(r,null!=i?i:e,t)}}}),t.default=d.default(s.default(u));var l=r(7);t.StringPredicate=l.StringPredicate,t.NumberPredicate=l.NumberPredicate,t.BooleanPredicate=l.BooleanPredicate,t.ArrayPredicate=l.ArrayPredicate,t.ObjectPredicate=l.ObjectPredicate,t.DatePredicate=l.DatePredicate,t.ErrorPredicate=l.ErrorPredicate,t.MapPredicate=l.MapPredicate,t.WeakMapPredicate=l.WeakMapPredicate,t.SetPredicate=l.SetPredicate,t.WeakSetPredicate=l.WeakSetPredicate,t.TypedArrayPredicate=l.TypedArrayPredicate,t.ArrayBufferPredicate=l.ArrayBufferPredicate,t.DataViewPredicate=l.DataViewPredicate,t.AnyPredicate=l.AnyPredicate;var g=r(6);t.ArgumentError=g.ArgumentError},function(e,t,r){(function(e){var r="[object Arguments]",a="[object Map]",n="[object Object]",i="[object Set]",o=/^\[object .+?Constructor\]$/,s=/^(?:0|[1-9]\d*)$/,d={};d["[object Float32Array]"]=d["[object Float64Array]"]=d["[object Int8Array]"]=d["[object Int16Array]"]=d["[object Int32Array]"]=d["[object Uint8Array]"]=d["[object Uint8ClampedArray]"]=d["[object Uint16Array]"]=d["[object Uint32Array]"]=!0,d[r]=d["[object Array]"]=d["[object ArrayBuffer]"]=d["[object Boolean]"]=d["[object DataView]"]=d["[object Date]"]=d["[object Error]"]=d["[object Function]"]=d[a]=d["[object Number]"]=d[n]=d["[object RegExp]"]=d[i]=d["[object String]"]=d["[object WeakMap]"]=!1;var c="object"==typeof global&&global&&global.Object===Object&&global,u="object"==typeof self&&self&&self.Object===Object&&self,l=c||u||Function("return this")(),g=t&&!t.nodeType&&t,f=g&&"object"==typeof e&&e&&!e.nodeType&&e,y=f&&f.exports===g,p=y&&c.process,h=function(){try{return p&&p.binding&&p.binding("util")}catch(e){}}(),m=h&&h.isTypedArray;function b(e,t){for(var r=-1,a=null==e?0:e.length;++rs))return!1;var c=i.get(e);if(c&&i.get(t))return c==t;var u=-1,l=!0,g=2&r?new ne:void 0;for(i.set(e,t),i.set(t,e);++u-1},re.prototype.set=function(e,t){var r=this.__data__,a=se(r,e);return a<0?(++this.size,r.push([e,t])):r[a][1]=t,this},ae.prototype.clear=function(){this.size=0,this.__data__={hash:new te,map:new(D||re),string:new te}},ae.prototype.delete=function(e){var t=pe(this,e).delete(e);return this.size-=t?1:0,t},ae.prototype.get=function(e){return pe(this,e).get(e)},ae.prototype.has=function(e){return pe(this,e).has(e)},ae.prototype.set=function(e,t){var r=pe(this,e),a=r.size;return r.set(e,t),this.size+=r.size==a?0:1,this},ne.prototype.add=ne.prototype.push=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this},ne.prototype.has=function(e){return this.__data__.has(e)},ie.prototype.clear=function(){this.__data__=new re,this.size=0},ie.prototype.delete=function(e){var t=this.__data__,r=t.delete(e);return this.size=t.size,r},ie.prototype.get=function(e){return this.__data__.get(e)},ie.prototype.has=function(e){return this.__data__.has(e)},ie.prototype.set=function(e,t){var r=this.__data__;if(r instanceof re){var a=r.__data__;if(!D||a.length<199)return a.push([e,t]),this.size=++r.size,this;r=this.__data__=new ae(a)}return r.set(e,t),this.size=r.size,this};var me=U?function(e){return null==e?[]:(e=Object(e),function(e,t){for(var r=-1,a=null==e?0:e.length,n=0,i=[];++r-1&&e%1==0&&e-1&&e%1==0&&e<=9007199254740991}function je(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}function Se(e){return null!=e&&"object"==typeof e}var we=m?function(e){return function(t){return e(t)}}(m):function(e){return Se(e)&&Oe(e.length)&&!!d[de(e)]};function Ve(e){return null!=(t=e)&&Oe(t.length)&&!Ae(t)?oe(e):ge(e);var t}e.exports=function(e,t){return ue(e,t)}}).call(this,r(23)(e))},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});class a extends Error{constructor(e,t){super(e),Error.captureStackTrace?Error.captureStackTrace(this,t):this.stack=(new Error).stack,this.name="ArgumentError"}}t.ArgumentError=a},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=r(18);t.StringPredicate=a.StringPredicate;const n=r(20);t.NumberPredicate=n.NumberPredicate;const i=r(21);t.BooleanPredicate=i.BooleanPredicate;const o=r(0),s=r(22);t.ArrayPredicate=s.ArrayPredicate;const d=r(24);t.ObjectPredicate=d.ObjectPredicate;const c=r(29);t.DatePredicate=c.DatePredicate;const u=r(30);t.ErrorPredicate=u.ErrorPredicate;const l=r(31);t.MapPredicate=l.MapPredicate;const g=r(32);t.WeakMapPredicate=g.WeakMapPredicate;const f=r(33);t.SetPredicate=f.SetPredicate;const y=r(34);t.WeakSetPredicate=y.WeakSetPredicate;const p=r(35);t.TypedArrayPredicate=p.TypedArrayPredicate;const h=r(36);t.ArrayBufferPredicate=h.ArrayBufferPredicate;const m=r(37);t.DataViewPredicate=m.DataViewPredicate;const b=r(38);t.AnyPredicate=b.AnyPredicate,t.default=(e,t)=>(Object.defineProperties(e,{string:{get:()=>new a.StringPredicate(t)},number:{get:()=>new n.NumberPredicate(t)},boolean:{get:()=>new i.BooleanPredicate(t)},undefined:{get:()=>new o.Predicate("undefined",t)},null:{get:()=>new o.Predicate("null",t)},nullOrUndefined:{get:()=>new o.Predicate("nullOrUndefined",t)},nan:{get:()=>new o.Predicate("nan",t)},symbol:{get:()=>new o.Predicate("symbol",t)},array:{get:()=>new s.ArrayPredicate(t)},object:{get:()=>new d.ObjectPredicate(t)},date:{get:()=>new c.DatePredicate(t)},error:{get:()=>new u.ErrorPredicate(t)},map:{get:()=>new l.MapPredicate(t)},weakMap:{get:()=>new g.WeakMapPredicate(t)},set:{get:()=>new f.SetPredicate(t)},weakSet:{get:()=>new y.WeakSetPredicate(t)},function:{get:()=>new o.Predicate("Function",t)},buffer:{get:()=>new o.Predicate("Buffer",t)},regExp:{get:()=>new o.Predicate("RegExp",t)},promise:{get:()=>new o.Predicate("Promise",t)},typedArray:{get:()=>new p.TypedArrayPredicate("TypedArray",t)},int8Array:{get:()=>new p.TypedArrayPredicate("Int8Array",t)},uint8Array:{get:()=>new p.TypedArrayPredicate("Uint8Array",t)},uint8ClampedArray:{get:()=>new p.TypedArrayPredicate("Uint8ClampedArray",t)},int16Array:{get:()=>new p.TypedArrayPredicate("Int16Array",t)},uint16Array:{get:()=>new p.TypedArrayPredicate("Uint16Array",t)},int32Array:{get:()=>new p.TypedArrayPredicate("Int32Array",t)},uint32Array:{get:()=>new p.TypedArrayPredicate("Uint32Array",t)},float32Array:{get:()=>new p.TypedArrayPredicate("Float32Array",t)},float64Array:{get:()=>new p.TypedArrayPredicate("Float64Array",t)},arrayBuffer:{get:()=>new h.ArrayBufferPredicate("ArrayBuffer",t)},sharedArrayBuffer:{get:()=>new h.ArrayBufferPredicate("SharedArrayBuffer",t)},dataView:{get:()=>new m.DataViewPredicate(t)},iterable:{get:()=>new o.Predicate("Iterable",t)},any:{value:(...e)=>new b.AnyPredicate(e,t)}}),e)},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=r(4);t.default=(e,t)=>{try{for(const r of e)a.default(r,t);return!0}catch(e){return e.message}}},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=r(2);t.default=function e(t,r,n){n[a.testSymbol](t,e,r)}},function(e,t,r){"use strict";const a=()=>{const e=Error.prepareStackTrace;Error.prepareStackTrace=(e,t)=>t;const t=(new Error).stack.slice(1);return Error.prepareStackTrace=e,t};e.exports=a,e.exports.default=a},function(e,t,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const a=r(12),n=r(13),i=r(14),o=/^.*?\((?