diff --git a/.babelrc b/.babelrc
new file mode 100644
index 00000000..6d32ad5c
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,12 @@
+{
+ "inputSourceMap": true,
+ "presets": [
+ [
+ "@babel/preset-env",
+ {
+ "useBuiltIns": "usage",
+ "corejs": 3,
+ }
+ ]
+ ]
+}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..79621be8
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = space
+indent_size = 2
diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml
new file mode 100644
index 00000000..0e8f5734
--- /dev/null
+++ b/.github/workflows/actions.yml
@@ -0,0 +1,127 @@
+name: "CI"
+
+on:
+ pull_request_target:
+ types: [opened, synchronize, reopened]
+ push:
+ branches:
+ - 'v3'
+ - 'feature/*'
+ - 'fix/*'
+ workflow_dispatch:
+
+permissions:
+ actions: read
+ checks: write
+ contents: read
+ deployments: read
+ issues: read
+ packages: read
+ pull-requests: write
+ repository-projects: read
+ security-events: read
+ statuses: write
+
+env:
+ SAUCE_USERNAME: ${{secrets.SAUCE_USERNAME}}
+ SAUCE_ACCESS_KEY: ${{secrets.SAUCE_ACCESS_KEY}}
+ CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
+ DISPLAY: ':99.0'
+
+jobs:
+ approve:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Approve
+ run: echo For security reasons, all pull requests need to be approved first before running any automated CI.
+
+ prepare:
+ runs-on: ubuntu-latest
+ needs: [approve]
+ environment: open-env
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ ref: ${{ github.event.pull_request.head.sha }}
+ fetch-depth: 2
+ persist-credentials: false
+
+ - name: Is environment ok
+ run: |
+ echo $SAUCE_USERNAME
+ echo ${{ github.event.pull_request.base.sha }} ${{ github.sha }} ${{ github.event.pull_request.head.sha }}
+
+ - name: Get specific changed files
+ id: source-changed
+ uses: tj-actions/changed-files@v1.1.3
+ with:
+ base_sha: ${{ github.sha }}
+ sha: ${{ github.event.pull_request.head.sha }}
+ files: |
+ src
+ test
+ karma.conf.js
+ Gruntfile.js
+ rollup.config.js
+
+ - name: Install node.js
+ if: steps.source-changed.outputs.any_changed == 'true'
+ uses: actions/setup-node@v1
+ with:
+ node-version: 14.x
+
+ - name: Install xvfb
+ if: steps.source-changed.outputs.any_changed == 'true'
+ run: |
+ sudo apt-get install xvfb
+ Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
+
+ - name: Install dependencies
+ if: steps.source-changed.outputs.any_changed == 'true'
+ run: |
+ npm install
+ npm install -g grunt-cli
+ node_modules/.bin/rollup -c
+
+ - name: Install saucectl
+ if: steps.source-changed.outputs.any_changed == 'true'
+ uses: saucelabs/saucectl-run-action@v1
+ with:
+ skip-run: true
+ testing-environment: ""
+ concurrency: 10
+
+ - name: Grunt test
+ if: steps.source-changed.outputs.any_changed == 'true'
+ run: |
+ grunt --version
+ sed -i '/log.info(`Check out job at/a\\ console.log(`::set-output name=urls-${sessionId}::${getSauceEndpoint(browserData.region)}${sessionId}`);' node_modules/karma-sauce-launcher/dist/reporter/reporter.js || true
+
+ - name: Run tests
+ if: steps.source-changed.outputs.any_changed == 'true'
+ run: grunt karma:saucelabs
+ id: test
+
+ - name: Run code coverage
+ if: steps.source-changed.outputs.any_changed == 'true'
+ uses: paambaati/codeclimate-action@v2.7.5
+ with:
+ coverageCommand: grunt karma:coverage
+ debug: true
+ prefix: .
+ coverageLocations: |
+ ${{github.workspace}}/coverage/lcov/result.lcov:lcov
+ id: coverage
+
+ - name: debug
+ run: ls -lhR coverage || true
+
+ - uses: LouisBrunner/checks-action@v1.1.1
+ if: steps.source-changed.outputs.any_changed == 'true'
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ name: Testsuite passed
+ conclusion: ${{ job.status }}
+ output: |
+ {"summary":"${{join(steps.test.outputs.*, ', ')}}"}
diff --git a/.gitignore b/.gitignore
index 2523ef93..69b6ce81 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
*~
# Node
+package-lock.json
/build
/node_modules
/bower_components
@@ -13,4 +14,7 @@
# Tests
sauce_connect.log
-/coverage
\ No newline at end of file
+/coverage
+dist/flow*cov*
+dist/flow*map*
+dist/flow*gz
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c40d3b0b..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-language: node_js
-sudo: false
-services:
- - xvfb
-cache:
- directories:
- - node_modules
-env:
- global:
- - SAUCE_USERNAME=flowjs
- - SAUCE_ACCESS_KEY=53e609a9-cb5d-4eac-a888-aa5419836f19
-matrix:
- fast_finish: true
- include:
- - env: TEST='unit-tests'
- node_js: "4.2"
- - env: TEST='browser-tests'
- node_js: "4.2"
- addons:
- sauce_connect: true
- allow_failures:
- - env: TEST='browser-tests'
-before_install: npm install -g grunt-cli codeclimate-test-reporter
-install: npm install
-script:
- - $TRAVIS_BUILD_DIR/travis.sh
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 60bc6629..b0b1a633 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,37 +1,52 @@
-# 2.0.0
-
-## Features
-
- - All code follows Google javascript style guide
- - Target url can be provided with query string
- - Events **fileAdded** and **filesAdded** can prevent file from being added to $.files list by
- returning false. Custom validators can be ran here.
- - **ResumableFile.getType()** and **ResumableFile.getExtension()** helper methods added. Can be
- used for custom validation.
- - **fileProgress** and **progress** events are always asynchronous.
- - **ResumableFile.pause()** and **ResumableFile.resume()** methods for single file pausing and
- resuming.
- - **filesSubmitted** event added. Can be used to start file upload. Event is thrown then files are
- added to queue.
- - **progressCallbacksInterval** parameter added. Minimum interval between callbacks execution in
- milliseconds.
- - **averageSpeed** and **currentSpeed** parameters added for `ResumableFile`. These params
- accuracy can be adjusted with `speedSmoothingFactor` and `progressCallbacksInterval` parameters.
- - **timeRemaining** method added for `ResumableFile`. Returns remaining time to upload in seconds. Accuracy is based on average speed.
- - **sizeUploaded** method added for `ResumableFile`. Returns size uploaded in bytes.
- - **singleFile** parameter added. Then enabled, uploaded file will replace current one.
-
-## Breaking Changes
- - **Resumable** was renamed to **Flow**
- - **ResumableFile.fileName** parameter renamed to **ResumableFile.name**
- - **Resumable.getOpt** method dropped, use Resumable.opts parameter instead if needed.
- - **Resumable.maxFiles**, **Resumable.minFileSize**, **Resumable.maxFileSize**,
- **Resumable.fileType** validators dropped. Use **fileAdded** and **filesAdded** events for
- custom validation.
- - **fileProgress** and **progress** events are not thrown on ResumableFile.abort() and ResumableFile.cancel() methods execution.
- - **cancel** event was removed. Event was always called after **Resumable.cancel()** function.
- - **fileAdded**, **filesAdded** events are thrown before file is added to upload queue. This means
- that calling **Resumable.upload()** method in these events will not start uploading current
- files. To start upload use **filesSubmitted** event instead.
- - **throttleProgressCallbacks** parameter was replaced with **progressCallbacksInterval** and it
- is now measured in milliseconds.
\ No newline at end of file
+# 3.0.0
+
+## Breaking Changes
+
+### Events
+ - Events are distincts from hooks.
+ - Recognized events and hooks are now lower-snake-case (case-sensitive).
+ - Hooks are "file-added", "files-added", "files-submitted". "filter-file" is a filtering hook.
+ - Events are passed a native CustomEvent. IE:
+ v2: `flow.on('fileRemoved', (file) => { ... });`
+ v3: `flow.on('file-removed', ({detail: [file]}) => { ... });`
+
+### Other
+ - FlowFile does not run bootstrap() upon instanciation. This must be done manually (or rely on *addFile* functions).
+
+# 2.0.0
+
+## Features
+
+ - All code follows Google javascript style guide
+ - Target url can be provided with query string
+ - Events **fileAdded** and **filesAdded** can prevent file from being added to $.files list by
+ returning false. Custom validators can be ran here.
+ - **ResumableFile.getType()** and **ResumableFile.getExtension()** helper methods added. Can be
+ used for custom validation.
+ - **fileProgress** and **progress** events are always asynchronous.
+ - **ResumableFile.pause()** and **ResumableFile.resume()** methods for single file pausing and
+ resuming.
+ - **filesSubmitted** event added. Can be used to start file upload. Event is thrown then files are
+ added to queue.
+ - **progressCallbacksInterval** parameter added. Minimum interval between callbacks execution in
+ milliseconds.
+ - **averageSpeed** and **currentSpeed** parameters added for `ResumableFile`. These params
+ accuracy can be adjusted with `speedSmoothingFactor` and `progressCallbacksInterval` parameters.
+ - **timeRemaining** method added for `ResumableFile`. Returns remaining time to upload in seconds. Accuracy is based on average speed.
+ - **sizeUploaded** method added for `ResumableFile`. Returns size uploaded in bytes.
+ - **singleFile** parameter added. Then enabled, uploaded file will replace current one.
+
+## Breaking Changes
+ - **Resumable** was renamed to **Flow**
+ - **ResumableFile.fileName** parameter renamed to **ResumableFile.name**
+ - **Resumable.getOpt** method dropped, use Resumable.opts parameter instead if needed.
+ - **Resumable.maxFiles**, **Resumable.minFileSize**, **Resumable.maxFileSize**,
+ **Resumable.fileType** validators dropped. Use **fileAdded** and **filesAdded** events for
+ custom validation.
+ - **fileProgress** and **progress** events are not thrown on ResumableFile.abort() and ResumableFile.cancel() methods execution.
+ - **cancel** event was removed. Event was always called after **Resumable.cancel()** function.
+ - **fileAdded**, **filesAdded** events are thrown before file is added to upload queue. This means
+ that calling **Resumable.upload()** method in these events will not start uploading current
+ files. To start upload use **filesSubmitted** event instead.
+ - **throttleProgressCallbacks** parameter was replaced with **progressCallbacksInterval** and it
+ is now measured in milliseconds.
diff --git a/Gruntfile.js b/Gruntfile.js
index 27eb3de8..69e7ef61 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,34 +1,11 @@
module.exports = function(grunt) {
+ grunt.loadNpmTasks('grunt-exec');
+
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
- uglify: {
- options: {
- banner: '/*! <%= pkg.name %> <%= pkg.version %> */\n'
- },
- build: {
- src: 'dist/flow.js',
- dest: 'dist/flow.min.js'
- }
- },
- concat: {
- build: {
- files: {
- 'dist/flow.js': [
- 'src/flow.js'
- ]
- }
- }
- },
- jst: {
- compile: {
- options: {
-
- },
- files: {
- "dist/flow.js": ["dist/flow.js"]
- }
- }
+ exec: {
+ build: 'node_modules/.bin/rollup -c'
},
karma: {
options: {
@@ -45,31 +22,19 @@ module.exports = function(grunt) {
singleRun: true,
browsers: ['Firefox'],
reporters: ['progress', 'coverage'],
- preprocessors: {
- 'src/*.js': 'coverage'
- },
- coverageReporter: {
- type: "lcov",
- dir: "coverage"
- }
},
saucelabs: {
singleRun: true,
reporters: ['progress', 'saucelabs'],
- preprocessors: {
- 'src/*.js': 'coverage'
- },
- coverageReporter: {
- type: "lcov",
- dir: "coverage"
- },
// global config for SauceLabs
+ // SAUCE_USERNAME and SAUCE_ACCESS_KEY environment variable are considered by default
sauceLabs: {
testName: 'flow.js',
- username: grunt.option('sauce-username') || process.env.SAUCE_USERNAME,
- accessKey: grunt.option('sauce-access-key') || process.env.SAUCE_ACCESS_KEY,
+ public: true,
+ // recordVideo: false,
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
- startConnect: false
+ startConnect: true,
+ retryLimit: 1,
}
}
},
@@ -91,18 +56,6 @@ module.exports = function(grunt) {
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d' // options to use with '$ git describe'
}
},
- 'template': {
- 'release': {
- 'options': {
- 'data': {
- 'version': '<%= pkg.version %>'
- }
- },
- 'files': {
- 'dist/flow.js': ['dist/flow.js']
- }
- }
- }
});
// Loading dependencies
@@ -113,7 +66,7 @@ module.exports = function(grunt) {
// Default task.
grunt.registerTask('default', ['test']);
// Release tasks
- grunt.registerTask('build', ['concat', 'template', 'uglify']);
+ grunt.registerTask('build', ['exec:build']);
grunt.registerTask('release', function(type) {
type = type ? type : 'patch';
grunt.task.run('bump-only:' + type);
diff --git a/README.md b/README.md
index d3e9eae5..37a253d9 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Flow.js [](https://travis-ci.org/flowjs/flow.js) [](https://codeclimate.com/github/flowjs/flow.js/coverage) [](https://saucelabs.com/u/flowjs)
+# Flow.js [](https://travis-ci.org/flowjs/flow.js) [](https://codeclimate.com/github/flowjs/flow.js/coverage) [](https://saucelabs.com/u/flowjs) [](http://inch-ci.org/github/flowjs/flow.js)
@@ -126,7 +126,7 @@ function, it will be passed a FlowFile, a FlowChunk and isTest boolean (Default:
* `testChunks` Make a GET request to the server for each chunks to see if it already exists. If implemented on the server-side, this will allow for upload resumes even after a browser crash or even a computer restart. (Default: `true`)
* `preprocess` Optional function to process each chunk before testing & sending. To the function it will be passed the chunk as parameter, and should call the `preprocessFinished` method on the chunk when finished. (Default: `null`)
* `changeRawDataBeforeSend` Optional function to change Raw Data just before the XHR Request can be sent for each chunk. To the function, it will be passed the chunk and the data as a Parameter. Return the data which will be then sent to the XHR request without further modification. (Default: `null`). This is helpful when using FlowJS with [Google Cloud Storage](https://cloud.google.com/storage/docs/json_api/v1/how-tos/multipart-upload). Usage example can be seen [#276](https://github.com/flowjs/flow.js/pull/276). (For more, check issue [#170](https://github.com/flowjs/flow.js/issues/170)).
-* `initFileFn` Optional function to initialize the fileObject. To the function it will be passed a FlowFile and a FlowChunk arguments.
+* `initFileFn` Optional (asynchronous) function to initialize the fileObject. To the function it will be passed a FlowFile and a FlowChunk arguments.
* `readFileFn` Optional function wrapping reading operation from the original file. To the function it will be passed the FlowFile, the startByte and endByte, the fileType and the FlowChunk.
* `generateUniqueIdentifier` Override the function that generates unique identifiers for each file. (Default: `null`)
* `maxChunkRetries` The maximum number of retries for a chunk before the upload is failed. Valid values are any positive integer and `undefined` for no limit. (Default: `0`)
@@ -167,14 +167,18 @@ parameter must be adjusted together with `progressCallbacksInterval` parameter.
* `.off()` All events are removed.
* `.off(event)` Remove all callbacks of specific event.
* `.off(event, callback)` Remove specific callback of event. `callback` should be a `Function`.
-* `.upload()` Start or resume uploading.
-* `.pause()` Pause uploading.
-* `.resume()` Resume uploading.
-* `.cancel()` Cancel upload of all `FlowFile` objects and remove them from the list.
+* `.upload()` [async] Start or resume uploading.
+* `.pause()` [async] Pause uploading.
+* `.resume()` [async] Resume uploading.
+* `.cancel()` [asyc] Cancel upload of all `FlowFile` objects and remove them from the list.
* `.progress()` Returns a float between 0 and 1 indicating the current upload progress of all files.
* `.isUploading()` Returns a boolean indicating whether or not the instance is currently uploading anything.
-* `.addFile(file)` Add a HTML5 File object to the list of files.
-* `.removeFile(file)` Cancel upload of a specific `FlowFile` object on the list from the list.
+* `.addFile(file, event = null, initFileFn = undefined)` [async] Add a HTML5 File object to the list of files.
+ * Accept the same `event` and `initFileFn` parameters thant `addFiles` which is used under the hood.
+* `.addFiles([files], event = null, initFileFn = undefined)` [async] Add multiple File objects to the list of files and returns the promise of the corresponding FlowFiles.
+ * `event` The optional event that trigger the addition (for internal purposes)
+ * `initFileFn` An [async] override of Flow.initFileFn
+* `.removeFile(file)` [asyc] Cancel upload of a specific `FlowFile` object on the list from the list.
* `.getFromUniqueIdentifier(uniqueIdentifier)` Look up a `FlowFile` object by its unique identifier.
* `.getSize()` Returns the total size of the upload in bytes.
* `.sizeUploaded()` Returns the total size uploaded of all files in bytes.
@@ -182,29 +186,35 @@ parameter must be adjusted together with `progressCallbacksInterval` parameter.
#### Events
-* `.fileSuccess(file, message, chunk)` A specific file was completed. First argument `file` is instance of `FlowFile`, second argument `message` contains server response. Response is always a string.
-Third argument `chunk` is instance of `FlowChunk`. You can get response status by accessing xhr
-object `chunk.xhr.status`.
-* `.fileProgress(file, chunk)` Uploading progressed for a specific file.
-* `.fileAdded(file, event)` This event is used for file validation. To reject this file return false.
-This event is also called before file is added to upload queue,
-this means that calling `flow.upload()` function will not start current file upload.
-Optionally, you can use the browser `event` object from when the file was
-added.
-* `.filesAdded(array, event)` Same as fileAdded, but used for multiple file validation.
-* `.filesSubmitted(array, event)` Same as filesAdded, but happens after the file is added to upload queue. Can be used to start upload of currently added files.
-* `.fileRemoved(file)` The specific file was removed from the upload queue. Combined with filesSubmitted, can be used to notify UI to update its state to match the upload queue.
-* `.fileRetry(file, chunk)` Something went wrong during upload of a specific file, uploading is being
-retried.
-* `.fileError(file, message, chunk)` An error occurred during upload of a specific file.
-* `.uploadStart()` Upload has been started on the Flow object.
-* `.complete()` Uploading completed.
-* `.progress()` Uploading progress.
-* `.error(message, file, chunk)` An error, including fileError, occurred.
-* `.catchAll(event, ...)` Listen to all the events listed above with the same callback function.
+Events are native, synchronous and provide information about the internal state of the application without being given a chance to alter it.
+
+* `file-success( file, message, chunk)` A specific file was completed (`message` comes from `xhr.responseText`, `chunk` is instance of `FlowChunk` representing the last chunk for this file. You can get response status by accessing xhr object `chunk.xhr.status`).
+* `file-progress( file, chunk)` Upload progressed for a specific file.
+* `file-removed( file)` The specific file was removed from the upload queue. Combined with the `files-submitted` hook, it can be used to notify UI to update its state to match the upload queue.
+* `file-retry( file, chunk)` Something went wrong during upload of a specific file, uploading is being retried.
+* `file-error( file, message, chunk)` An error occurred during upload of a specific file. `message` comes from `xhr.responseText`.
+* `upload-start()` Upload started on the Flow object.
+* `complete()` Upload completed.
+* `progress()` Upload progress.
+* `error( message, file, chunk)` An error, including fileError, occurred.
+* `catch-all( event-name, ...)` Receive all above events listed above and their corresponding parameters.
+
+#### Processing hooks
+
+Hooks allows for either (possibly asynchronous) operations and allow altering the regular processing of the file(s) from addition to upload completion.
+* `file-added( file, event) : null` This event is also called before file is added to upload queue and after it's been fully initialized. `event` is the browser `event` object from when the file was added.
+* `files-added([ files], event) : null` Same as `file-added`, but used for multiple file validation.
+* `files-submitted([ files], event) : null` Same as `files-added`, but happens after the file is added to upload queue. Can be used to start upload of currently added files.
+* `filter-file( file, event) : boolean` The boolean return value decide whether this particular file must be processed or ignored.
+
+### Hooks and events format
+- Events and hooks name are case-sensitive, snake-cased.
+- In the case of events, a CustomEvent passed straight to callback passed to `Flow.on()`.
+- Sample use `flow.on('file-removed', ({detail: [file]}) => { ... });`
### FlowFile
FlowFile constructor can be accessed in `Flow.FlowFile`.
+
#### Properties
* `.flowObj` A back-reference to the parent `Flow` object.
@@ -223,11 +233,12 @@ FlowFile constructor can be accessed in `Flow.FlowFile`.
* `.progress(relative)` Returns a float between 0 and 1 indicating the current upload progress of the file. If `relative` is `true`, the value is returned relative to all files in the Flow.js instance.
* `.pause()` Pause uploading the file.
-* `.resume()` Resume uploading the file.
-* `.cancel()` Abort uploading the file and delete it from the list of files to upload.
-* `.retry()` Retry uploading the file.
-* `.bootstrap()` Rebuild the state of a `FlowFile` object, including reassigning chunks and XMLHttpRequest instances.
+* `.resume()` [async] Resume uploading the file.
+* `.cancel()` [async] Abort uploading the file and delete it from the list of files to upload.
+* `.retry()` [async] Retry uploading the file.
+* `.bootstrap()` [async / internal use only] Rebuild the state of a `FlowFile` object, including reassigning chunks and XMLHttpRequest instances.
* `.isUploading()` Returns a boolean indicating whether file chunks is uploading.
+* `.isReading()` Returns a boolean indicating whether the file/stream is being read.
* `.isComplete()` Returns a boolean indicating whether the file has completed uploading and received a server response.
* `.sizeUploaded()` Returns size uploaded in bytes.
* `.timeRemaining()` Returns remaining time to finish upload file in seconds. Accuracy is based on average speed. If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
diff --git a/babel.config.json b/babel.config.json
new file mode 100644
index 00000000..a10c9783
--- /dev/null
+++ b/babel.config.json
@@ -0,0 +1,11 @@
+{
+ "presets": [
+ [
+ "@babel/preset-env",
+ {
+ "useBuiltIns": "entry",
+ "corejs": "3.8"
+ }
+ ]
+ ]
+}
diff --git a/dist/flow.js b/dist/flow.js
index e61f0a75..e0ce962e 100644
--- a/dist/flow.js
+++ b/dist/flow.js
@@ -1,1664 +1,8041 @@
-/**
- * @license MIT
- */
-(function(window, document, undefined) {'use strict';
- if (!window || !document) {
- console.warn('Flowjs needs window and document objects to work');
- return;
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Flow = factory());
+}(this, (function () { 'use strict';
+
+ function _typeof(obj) {
+ "@babel/helpers - typeof";
+
+ if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
+ _typeof = function (obj) {
+ return typeof obj;
+ };
+ } else {
+ _typeof = function (obj) {
+ return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
+ };
+ }
+
+ return _typeof(obj);
+ }
+
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
+ try {
+ var info = gen[key](arg);
+ var value = info.value;
+ } catch (error) {
+ reject(error);
+ return;
+ }
+
+ if (info.done) {
+ resolve(value);
+ } else {
+ Promise.resolve(value).then(_next, _throw);
+ }
+ }
+
+ function _asyncToGenerator(fn) {
+ return function () {
+ var self = this,
+ args = arguments;
+ return new Promise(function (resolve, reject) {
+ var gen = fn.apply(self, args);
+
+ function _next(value) {
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
+ }
+
+ function _throw(err) {
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
+ }
+
+ _next(undefined);
+ });
+ };
+ }
+
+ function _classCallCheck(instance, Constructor) {
+ if (!(instance instanceof Constructor)) {
+ throw new TypeError("Cannot call a class as a function");
+ }
+ }
+
+ function _defineProperties(target, props) {
+ for (var i = 0; i < props.length; i++) {
+ var descriptor = props[i];
+ descriptor.enumerable = descriptor.enumerable || false;
+ descriptor.configurable = true;
+ if ("value" in descriptor) descriptor.writable = true;
+ Object.defineProperty(target, descriptor.key, descriptor);
+ }
+ }
+
+ function _createClass(Constructor, protoProps, staticProps) {
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+ if (staticProps) _defineProperties(Constructor, staticProps);
+ return Constructor;
+ }
+
+ function _defineProperty(obj, key, value) {
+ if (key in obj) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ } else {
+ obj[key] = value;
+ }
+
+ return obj;
+ }
+
+ function ownKeys(object, enumerableOnly) {
+ var keys = Object.keys(object);
+
+ if (Object.getOwnPropertySymbols) {
+ var symbols = Object.getOwnPropertySymbols(object);
+ if (enumerableOnly) symbols = symbols.filter(function (sym) {
+ return Object.getOwnPropertyDescriptor(object, sym).enumerable;
+ });
+ keys.push.apply(keys, symbols);
+ }
+
+ return keys;
+ }
+
+ function _objectSpread2(target) {
+ for (var i = 1; i < arguments.length; i++) {
+ var source = arguments[i] != null ? arguments[i] : {};
+
+ if (i % 2) {
+ ownKeys(Object(source), true).forEach(function (key) {
+ _defineProperty(target, key, source[key]);
+ });
+ } else if (Object.getOwnPropertyDescriptors) {
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
+ } else {
+ ownKeys(Object(source)).forEach(function (key) {
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
+ });
+ }
+ }
+
+ return target;
+ }
+
+ function _inherits(subClass, superClass) {
+ if (typeof superClass !== "function" && superClass !== null) {
+ throw new TypeError("Super expression must either be null or a function");
+ }
+
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
+ constructor: {
+ value: subClass,
+ writable: true,
+ configurable: true
+ }
+ });
+ if (superClass) _setPrototypeOf(subClass, superClass);
+ }
+
+ function _getPrototypeOf(o) {
+ _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
+ return o.__proto__ || Object.getPrototypeOf(o);
+ };
+ return _getPrototypeOf(o);
+ }
+
+ function _setPrototypeOf(o, p) {
+ _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
+ o.__proto__ = p;
+ return o;
+ };
+
+ return _setPrototypeOf(o, p);
+ }
+
+ function _isNativeReflectConstruct() {
+ if (typeof Reflect === "undefined" || !Reflect.construct) return false;
+ if (Reflect.construct.sham) return false;
+ if (typeof Proxy === "function") return true;
+
+ try {
+ Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ function _construct(Parent, args, Class) {
+ if (_isNativeReflectConstruct()) {
+ _construct = Reflect.construct;
+ } else {
+ _construct = function _construct(Parent, args, Class) {
+ var a = [null];
+ a.push.apply(a, args);
+ var Constructor = Function.bind.apply(Parent, a);
+ var instance = new Constructor();
+ if (Class) _setPrototypeOf(instance, Class.prototype);
+ return instance;
+ };
+ }
+
+ return _construct.apply(null, arguments);
+ }
+
+ function _isNativeFunction(fn) {
+ return Function.toString.call(fn).indexOf("[native code]") !== -1;
+ }
+
+ function _wrapNativeSuper(Class) {
+ var _cache = typeof Map === "function" ? new Map() : undefined;
+
+ _wrapNativeSuper = function _wrapNativeSuper(Class) {
+ if (Class === null || !_isNativeFunction(Class)) return Class;
+
+ if (typeof Class !== "function") {
+ throw new TypeError("Super expression must either be null or a function");
+ }
+
+ if (typeof _cache !== "undefined") {
+ if (_cache.has(Class)) return _cache.get(Class);
+
+ _cache.set(Class, Wrapper);
+ }
+
+ function Wrapper() {
+ return _construct(Class, arguments, _getPrototypeOf(this).constructor);
+ }
+
+ Wrapper.prototype = Object.create(Class.prototype, {
+ constructor: {
+ value: Wrapper,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ return _setPrototypeOf(Wrapper, Class);
+ };
+
+ return _wrapNativeSuper(Class);
+ }
+
+ function _assertThisInitialized(self) {
+ if (self === void 0) {
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
+ }
+
+ return self;
+ }
+
+ function _possibleConstructorReturn(self, call) {
+ if (call && (typeof call === "object" || typeof call === "function")) {
+ return call;
+ }
+
+ return _assertThisInitialized(self);
+ }
+
+ function _createSuper(Derived) {
+ var hasNativeReflectConstruct = _isNativeReflectConstruct();
+
+ return function _createSuperInternal() {
+ var Super = _getPrototypeOf(Derived),
+ result;
+
+ if (hasNativeReflectConstruct) {
+ var NewTarget = _getPrototypeOf(this).constructor;
+
+ result = Reflect.construct(Super, arguments, NewTarget);
+ } else {
+ result = Super.apply(this, arguments);
+ }
+
+ return _possibleConstructorReturn(this, result);
+ };
+ }
+
+ function _slicedToArray(arr, i) {
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
+ }
+
+ function _arrayWithHoles(arr) {
+ if (Array.isArray(arr)) return arr;
+ }
+
+ function _iterableToArrayLimit(arr, i) {
+ if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
+ var _arr = [];
+ var _n = true;
+ var _d = false;
+ var _e = undefined;
+
+ try {
+ for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
+ _arr.push(_s.value);
+
+ if (i && _arr.length === i) break;
+ }
+ } catch (err) {
+ _d = true;
+ _e = err;
+ } finally {
+ try {
+ if (!_n && _i["return"] != null) _i["return"]();
+ } finally {
+ if (_d) throw _e;
+ }
+ }
+
+ return _arr;
+ }
+
+ function _unsupportedIterableToArray(o, minLen) {
+ if (!o) return;
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+ var n = Object.prototype.toString.call(o).slice(8, -1);
+ if (n === "Object" && o.constructor) n = o.constructor.name;
+ if (n === "Map" || n === "Set") return Array.from(o);
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
+ }
+
+ function _arrayLikeToArray(arr, len) {
+ if (len == null || len > arr.length) len = arr.length;
+
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
+
+ return arr2;
+ }
+
+ function _nonIterableRest() {
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+
+ function _createForOfIteratorHelper(o, allowArrayLike) {
+ var it;
+
+ if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
+ if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
+ if (it) o = it;
+ var i = 0;
+
+ var F = function () {};
+
+ return {
+ s: F,
+ n: function () {
+ if (i >= o.length) return {
+ done: true
+ };
+ return {
+ done: false,
+ value: o[i++]
+ };
+ },
+ e: function (e) {
+ throw e;
+ },
+ f: F
+ };
+ }
+
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
+ }
+
+ var normalCompletion = true,
+ didErr = false,
+ err;
+ return {
+ s: function () {
+ it = o[Symbol.iterator]();
+ },
+ n: function () {
+ var step = it.next();
+ normalCompletion = step.done;
+ return step;
+ },
+ e: function (e) {
+ didErr = true;
+ err = e;
+ },
+ f: function () {
+ try {
+ if (!normalCompletion && it.return != null) it.return();
+ } finally {
+ if (didErr) throw err;
+ }
+ }
+ };
+ }
+
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+
+ function createCommonjsModule(fn) {
+ var module = { exports: {} };
+ return fn(module, module.exports), module.exports;
+ }
+
+ var check = function check(it) {
+ return it && it.Math == Math && it;
+ }; // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
+
+
+ var global$1 = // eslint-disable-next-line no-undef
+ check((typeof globalThis === "undefined" ? "undefined" : _typeof(globalThis)) == 'object' && globalThis) || check((typeof window === "undefined" ? "undefined" : _typeof(window)) == 'object' && window) || check((typeof self === "undefined" ? "undefined" : _typeof(self)) == 'object' && self) || check(_typeof(commonjsGlobal) == 'object' && commonjsGlobal) || // eslint-disable-next-line no-new-func
+ function () {
+ return this;
+ }() || Function('return this')();
+
+ var fails = function fails(exec) {
+ try {
+ return !!exec();
+ } catch (error) {
+ return true;
+ }
+ };
+
+ var descriptors = !fails(function () {
+ return Object.defineProperty({}, 1, {
+ get: function get() {
+ return 7;
+ }
+ })[1] != 7;
+ });
+
+ var nativePropertyIsEnumerable = {}.propertyIsEnumerable;
+ var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; // Nashorn ~ JDK8 bug
+
+ var NASHORN_BUG = getOwnPropertyDescriptor && !nativePropertyIsEnumerable.call({
+ 1: 2
+ }, 1); // `Object.prototype.propertyIsEnumerable` method implementation
+ // https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
+
+ var f = NASHORN_BUG ? function propertyIsEnumerable(V) {
+ var descriptor = getOwnPropertyDescriptor(this, V);
+ return !!descriptor && descriptor.enumerable;
+ } : nativePropertyIsEnumerable;
+ var objectPropertyIsEnumerable = {
+ f: f
+ };
+
+ var createPropertyDescriptor = function createPropertyDescriptor(bitmap, value) {
+ return {
+ enumerable: !(bitmap & 1),
+ configurable: !(bitmap & 2),
+ writable: !(bitmap & 4),
+ value: value
+ };
+ };
+
+ var toString = {}.toString;
+
+ var classofRaw = function classofRaw(it) {
+ return toString.call(it).slice(8, -1);
+ };
+
+ var split = ''.split; // fallback for non-array-like ES3 and non-enumerable old V8 strings
+
+ var indexedObject = fails(function () {
+ // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
+ // eslint-disable-next-line no-prototype-builtins
+ return !Object('z').propertyIsEnumerable(0);
+ }) ? function (it) {
+ return classofRaw(it) == 'String' ? split.call(it, '') : Object(it);
+ } : Object;
+
+ // `RequireObjectCoercible` abstract operation
+ // https://tc39.es/ecma262/#sec-requireobjectcoercible
+ var requireObjectCoercible = function requireObjectCoercible(it) {
+ if (it == undefined) throw TypeError("Can't call method on " + it);
+ return it;
+ };
+
+ var toIndexedObject = function toIndexedObject(it) {
+ return indexedObject(requireObjectCoercible(it));
+ };
+
+ var isObject = function isObject(it) {
+ return _typeof(it) === 'object' ? it !== null : typeof it === 'function';
+ };
+
+ // https://tc39.es/ecma262/#sec-toprimitive
+ // instead of the ES6 spec version, we didn't implement @@toPrimitive case
+ // and the second argument - flag - preferred type is a string
+
+ var toPrimitive = function toPrimitive(input, PREFERRED_STRING) {
+ if (!isObject(input)) return input;
+ var fn, val;
+ if (PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
+ if (typeof (fn = input.valueOf) == 'function' && !isObject(val = fn.call(input))) return val;
+ if (!PREFERRED_STRING && typeof (fn = input.toString) == 'function' && !isObject(val = fn.call(input))) return val;
+ throw TypeError("Can't convert object to primitive value");
+ };
+
+ var hasOwnProperty = {}.hasOwnProperty;
+
+ var has = function has(it, key) {
+ return hasOwnProperty.call(it, key);
+ };
+
+ var document$1 = global$1.document; // typeof document.createElement is 'object' in old IE
+
+ var EXISTS = isObject(document$1) && isObject(document$1.createElement);
+
+ var documentCreateElement = function documentCreateElement(it) {
+ return EXISTS ? document$1.createElement(it) : {};
+ };
+
+ var ie8DomDefine = !descriptors && !fails(function () {
+ return Object.defineProperty(documentCreateElement('div'), 'a', {
+ get: function get() {
+ return 7;
+ }
+ }).a != 7;
+ });
+
+ var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; // `Object.getOwnPropertyDescriptor` method
+ // https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
+
+ var f$1 = descriptors ? nativeGetOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
+ O = toIndexedObject(O);
+ P = toPrimitive(P, true);
+ if (ie8DomDefine) try {
+ return nativeGetOwnPropertyDescriptor(O, P);
+ } catch (error) {
+ /* empty */
+ }
+ if (has(O, P)) return createPropertyDescriptor(!objectPropertyIsEnumerable.f.call(O, P), O[P]);
+ };
+ var objectGetOwnPropertyDescriptor = {
+ f: f$1
+ };
+
+ var anObject = function anObject(it) {
+ if (!isObject(it)) {
+ throw TypeError(String(it) + ' is not an object');
+ }
+
+ return it;
+ };
+
+ var nativeDefineProperty = Object.defineProperty; // `Object.defineProperty` method
+ // https://tc39.es/ecma262/#sec-object.defineproperty
+
+ var f$2 = descriptors ? nativeDefineProperty : function defineProperty(O, P, Attributes) {
+ anObject(O);
+ P = toPrimitive(P, true);
+ anObject(Attributes);
+ if (ie8DomDefine) try {
+ return nativeDefineProperty(O, P, Attributes);
+ } catch (error) {
+ /* empty */
+ }
+ if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported');
+ if ('value' in Attributes) O[P] = Attributes.value;
+ return O;
+ };
+ var objectDefineProperty = {
+ f: f$2
+ };
+
+ var createNonEnumerableProperty = descriptors ? function (object, key, value) {
+ return objectDefineProperty.f(object, key, createPropertyDescriptor(1, value));
+ } : function (object, key, value) {
+ object[key] = value;
+ return object;
+ };
+
+ var setGlobal = function setGlobal(key, value) {
+ try {
+ createNonEnumerableProperty(global$1, key, value);
+ } catch (error) {
+ global$1[key] = value;
+ }
+
+ return value;
+ };
+
+ var SHARED = '__core-js_shared__';
+ var store = global$1[SHARED] || setGlobal(SHARED, {});
+ var sharedStore = store;
+
+ var functionToString = Function.toString; // this helper broken in `3.4.1-3.4.4`, so we can't use `shared` helper
+
+ if (typeof sharedStore.inspectSource != 'function') {
+ sharedStore.inspectSource = function (it) {
+ return functionToString.call(it);
+ };
+ }
+
+ var inspectSource = sharedStore.inspectSource;
+
+ var WeakMap = global$1.WeakMap;
+ var nativeWeakMap = typeof WeakMap === 'function' && /native code/.test(inspectSource(WeakMap));
+
+ var shared = createCommonjsModule(function (module) {
+ (module.exports = function (key, value) {
+ return sharedStore[key] || (sharedStore[key] = value !== undefined ? value : {});
+ })('versions', []).push({
+ version: '3.8.3',
+ mode: 'global',
+ copyright: '© 2021 Denis Pushkarev (zloirock.ru)'
+ });
+ });
+
+ var id = 0;
+ var postfix = Math.random();
+
+ var uid = function uid(key) {
+ return 'Symbol(' + String(key === undefined ? '' : key) + ')_' + (++id + postfix).toString(36);
+ };
+
+ var keys = shared('keys');
+
+ var sharedKey = function sharedKey(key) {
+ return keys[key] || (keys[key] = uid(key));
+ };
+
+ var hiddenKeys = {};
+
+ var WeakMap$1 = global$1.WeakMap;
+ var set, get, has$1;
+
+ var enforce = function enforce(it) {
+ return has$1(it) ? get(it) : set(it, {});
+ };
+
+ var getterFor = function getterFor(TYPE) {
+ return function (it) {
+ var state;
+
+ if (!isObject(it) || (state = get(it)).type !== TYPE) {
+ throw TypeError('Incompatible receiver, ' + TYPE + ' required');
+ }
+
+ return state;
+ };
+ };
+
+ if (nativeWeakMap) {
+ var store$1 = sharedStore.state || (sharedStore.state = new WeakMap$1());
+ var wmget = store$1.get;
+ var wmhas = store$1.has;
+ var wmset = store$1.set;
+
+ set = function set(it, metadata) {
+ metadata.facade = it;
+ wmset.call(store$1, it, metadata);
+ return metadata;
+ };
+
+ get = function get(it) {
+ return wmget.call(store$1, it) || {};
+ };
+
+ has$1 = function has(it) {
+ return wmhas.call(store$1, it);
+ };
+ } else {
+ var STATE = sharedKey('state');
+ hiddenKeys[STATE] = true;
+
+ set = function set(it, metadata) {
+ metadata.facade = it;
+ createNonEnumerableProperty(it, STATE, metadata);
+ return metadata;
+ };
+
+ get = function get(it) {
+ return has(it, STATE) ? it[STATE] : {};
+ };
+
+ has$1 = function has$1(it) {
+ return has(it, STATE);
+ };
+ }
+
+ var internalState = {
+ set: set,
+ get: get,
+ has: has$1,
+ enforce: enforce,
+ getterFor: getterFor
+ };
+
+ var redefine = createCommonjsModule(function (module) {
+ var getInternalState = internalState.get;
+ var enforceInternalState = internalState.enforce;
+ var TEMPLATE = String(String).split('String');
+ (module.exports = function (O, key, value, options) {
+ var unsafe = options ? !!options.unsafe : false;
+ var simple = options ? !!options.enumerable : false;
+ var noTargetGet = options ? !!options.noTargetGet : false;
+ var state;
+
+ if (typeof value == 'function') {
+ if (typeof key == 'string' && !has(value, 'name')) {
+ createNonEnumerableProperty(value, 'name', key);
+ }
+
+ state = enforceInternalState(value);
+
+ if (!state.source) {
+ state.source = TEMPLATE.join(typeof key == 'string' ? key : '');
+ }
+ }
+
+ if (O === global$1) {
+ if (simple) O[key] = value;else setGlobal(key, value);
+ return;
+ } else if (!unsafe) {
+ delete O[key];
+ } else if (!noTargetGet && O[key]) {
+ simple = true;
+ }
+
+ if (simple) O[key] = value;else createNonEnumerableProperty(O, key, value); // add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
+ })(Function.prototype, 'toString', function toString() {
+ return typeof this == 'function' && getInternalState(this).source || inspectSource(this);
+ });
+ });
+
+ var path = global$1;
+
+ var aFunction = function aFunction(variable) {
+ return typeof variable == 'function' ? variable : undefined;
+ };
+
+ var getBuiltIn = function getBuiltIn(namespace, method) {
+ return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global$1[namespace]) : path[namespace] && path[namespace][method] || global$1[namespace] && global$1[namespace][method];
+ };
+
+ var ceil = Math.ceil;
+ var floor = Math.floor; // `ToInteger` abstract operation
+ // https://tc39.es/ecma262/#sec-tointeger
+
+ var toInteger = function toInteger(argument) {
+ return isNaN(argument = +argument) ? 0 : (argument > 0 ? floor : ceil)(argument);
+ };
+
+ var min = Math.min; // `ToLength` abstract operation
+ // https://tc39.es/ecma262/#sec-tolength
+
+ var toLength = function toLength(argument) {
+ return argument > 0 ? min(toInteger(argument), 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
+ };
+
+ var max = Math.max;
+ var min$1 = Math.min; // Helper for a popular repeating case of the spec:
+ // Let integer be ? ToInteger(index).
+ // If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
+
+ var toAbsoluteIndex = function toAbsoluteIndex(index, length) {
+ var integer = toInteger(index);
+ return integer < 0 ? max(integer + length, 0) : min$1(integer, length);
+ };
+
+ var createMethod = function createMethod(IS_INCLUDES) {
+ return function ($this, el, fromIndex) {
+ var O = toIndexedObject($this);
+ var length = toLength(O.length);
+ var index = toAbsoluteIndex(fromIndex, length);
+ var value; // Array#includes uses SameValueZero equality algorithm
+ // eslint-disable-next-line no-self-compare
+
+ if (IS_INCLUDES && el != el) while (length > index) {
+ value = O[index++]; // eslint-disable-next-line no-self-compare
+
+ if (value != value) return true; // Array#indexOf ignores holes, Array#includes - not
+ } else for (; length > index; index++) {
+ if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
+ }
+ return !IS_INCLUDES && -1;
+ };
+ };
+
+ var arrayIncludes = {
+ // `Array.prototype.includes` method
+ // https://tc39.es/ecma262/#sec-array.prototype.includes
+ includes: createMethod(true),
+ // `Array.prototype.indexOf` method
+ // https://tc39.es/ecma262/#sec-array.prototype.indexof
+ indexOf: createMethod(false)
+ };
+
+ var indexOf = arrayIncludes.indexOf;
+
+ var objectKeysInternal = function objectKeysInternal(object, names) {
+ var O = toIndexedObject(object);
+ var i = 0;
+ var result = [];
+ var key;
+
+ for (key in O) {
+ !has(hiddenKeys, key) && has(O, key) && result.push(key);
+ } // Don't enum bug & hidden keys
+
+
+ while (names.length > i) {
+ if (has(O, key = names[i++])) {
+ ~indexOf(result, key) || result.push(key);
+ }
+ }
+
+ return result;
+ };
+
+ // IE8- don't enum bug keys
+ var enumBugKeys = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'];
+
+ var hiddenKeys$1 = enumBugKeys.concat('length', 'prototype'); // `Object.getOwnPropertyNames` method
+ // https://tc39.es/ecma262/#sec-object.getownpropertynames
+
+ var f$3 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
+ return objectKeysInternal(O, hiddenKeys$1);
+ };
+
+ var objectGetOwnPropertyNames = {
+ f: f$3
+ };
+
+ var f$4 = Object.getOwnPropertySymbols;
+ var objectGetOwnPropertySymbols = {
+ f: f$4
+ };
+
+ var ownKeys$1 = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) {
+ var keys = objectGetOwnPropertyNames.f(anObject(it));
+ var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
+ return getOwnPropertySymbols ? keys.concat(getOwnPropertySymbols(it)) : keys;
+ };
+
+ var copyConstructorProperties = function copyConstructorProperties(target, source) {
+ var keys = ownKeys$1(source);
+ var defineProperty = objectDefineProperty.f;
+ var getOwnPropertyDescriptor = objectGetOwnPropertyDescriptor.f;
+
+ for (var i = 0; i < keys.length; i++) {
+ var key = keys[i];
+ if (!has(target, key)) defineProperty(target, key, getOwnPropertyDescriptor(source, key));
+ }
+ };
+
+ var replacement = /#|\.prototype\./;
+
+ var isForced = function isForced(feature, detection) {
+ var value = data[normalize(feature)];
+ return value == POLYFILL ? true : value == NATIVE ? false : typeof detection == 'function' ? fails(detection) : !!detection;
+ };
+
+ var normalize = isForced.normalize = function (string) {
+ return String(string).replace(replacement, '.').toLowerCase();
+ };
+
+ var data = isForced.data = {};
+ var NATIVE = isForced.NATIVE = 'N';
+ var POLYFILL = isForced.POLYFILL = 'P';
+ var isForced_1 = isForced;
+
+ var getOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
+ /*
+ options.target - name of the target object
+ options.global - target is the global object
+ options.stat - export as static methods of target
+ options.proto - export as prototype methods of target
+ options.real - real prototype method for the `pure` version
+ options.forced - export even if the native feature is available
+ options.bind - bind methods to the target, required for the `pure` version
+ options.wrap - wrap constructors to preventing global pollution, required for the `pure` version
+ options.unsafe - use the simple assignment of property instead of delete + defineProperty
+ options.sham - add a flag to not completely full polyfills
+ options.enumerable - export as enumerable property
+ options.noTargetGet - prevent calling a getter on target
+ */
+
+ var _export = function _export(options, source) {
+ var TARGET = options.target;
+ var GLOBAL = options.global;
+ var STATIC = options.stat;
+ var FORCED, target, key, targetProperty, sourceProperty, descriptor;
+
+ if (GLOBAL) {
+ target = global$1;
+ } else if (STATIC) {
+ target = global$1[TARGET] || setGlobal(TARGET, {});
+ } else {
+ target = (global$1[TARGET] || {}).prototype;
+ }
+
+ if (target) for (key in source) {
+ sourceProperty = source[key];
+
+ if (options.noTargetGet) {
+ descriptor = getOwnPropertyDescriptor$1(target, key);
+ targetProperty = descriptor && descriptor.value;
+ } else targetProperty = target[key];
+
+ FORCED = isForced_1(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); // contained in target
+
+ if (!FORCED && targetProperty !== undefined) {
+ if (_typeof(sourceProperty) === _typeof(targetProperty)) continue;
+ copyConstructorProperties(sourceProperty, targetProperty);
+ } // add a flag to not completely full polyfills
+
+
+ if (options.sham || targetProperty && targetProperty.sham) {
+ createNonEnumerableProperty(sourceProperty, 'sham', true);
+ } // extend global
+
+
+ redefine(target, key, sourceProperty, options);
+ }
+ };
+
+ // https://tc39.es/ecma262/#sec-isarray
+
+ var isArray = Array.isArray || function isArray(arg) {
+ return classofRaw(arg) == 'Array';
+ };
+
+ // https://tc39.es/ecma262/#sec-toobject
+
+ var toObject = function toObject(argument) {
+ return Object(requireObjectCoercible(argument));
+ };
+
+ var createProperty = function createProperty(object, key, value) {
+ var propertyKey = toPrimitive(key);
+ if (propertyKey in object) objectDefineProperty.f(object, propertyKey, createPropertyDescriptor(0, value));else object[propertyKey] = value;
+ };
+
+ var nativeSymbol = !!Object.getOwnPropertySymbols && !fails(function () {
+ // Chrome 38 Symbol has incorrect toString conversion
+ // eslint-disable-next-line no-undef
+ return !String(Symbol());
+ });
+
+ var useSymbolAsUid = nativeSymbol // eslint-disable-next-line no-undef
+ && !Symbol.sham // eslint-disable-next-line no-undef
+ && _typeof(Symbol.iterator) == 'symbol';
+
+ var WellKnownSymbolsStore = shared('wks');
+ var _Symbol = global$1.Symbol;
+ var createWellKnownSymbol = useSymbolAsUid ? _Symbol : _Symbol && _Symbol.withoutSetter || uid;
+
+ var wellKnownSymbol = function wellKnownSymbol(name) {
+ if (!has(WellKnownSymbolsStore, name)) {
+ if (nativeSymbol && has(_Symbol, name)) WellKnownSymbolsStore[name] = _Symbol[name];else WellKnownSymbolsStore[name] = createWellKnownSymbol('Symbol.' + name);
+ }
+
+ return WellKnownSymbolsStore[name];
+ };
+
+ var SPECIES = wellKnownSymbol('species'); // `ArraySpeciesCreate` abstract operation
+ // https://tc39.es/ecma262/#sec-arrayspeciescreate
+
+ var arraySpeciesCreate = function arraySpeciesCreate(originalArray, length) {
+ var C;
+
+ if (isArray(originalArray)) {
+ C = originalArray.constructor; // cross-realm fallback
+
+ if (typeof C == 'function' && (C === Array || isArray(C.prototype))) C = undefined;else if (isObject(C)) {
+ C = C[SPECIES];
+ if (C === null) C = undefined;
+ }
+ }
+
+ return new (C === undefined ? Array : C)(length === 0 ? 0 : length);
+ };
+
+ var engineUserAgent = getBuiltIn('navigator', 'userAgent') || '';
+
+ var process = global$1.process;
+ var versions = process && process.versions;
+ var v8 = versions && versions.v8;
+ var match, version;
+
+ if (v8) {
+ match = v8.split('.');
+ version = match[0] + match[1];
+ } else if (engineUserAgent) {
+ match = engineUserAgent.match(/Edge\/(\d+)/);
+
+ if (!match || match[1] >= 74) {
+ match = engineUserAgent.match(/Chrome\/(\d+)/);
+ if (match) version = match[1];
+ }
+ }
+
+ var engineV8Version = version && +version;
+
+ var SPECIES$1 = wellKnownSymbol('species');
+
+ var arrayMethodHasSpeciesSupport = function arrayMethodHasSpeciesSupport(METHOD_NAME) {
+ // We can't use this feature detection in V8 since it causes
+ // deoptimization and serious performance degradation
+ // https://github.com/zloirock/core-js/issues/677
+ return engineV8Version >= 51 || !fails(function () {
+ var array = [];
+ var constructor = array.constructor = {};
+
+ constructor[SPECIES$1] = function () {
+ return {
+ foo: 1
+ };
+ };
+
+ return array[METHOD_NAME](Boolean).foo !== 1;
+ });
+ };
+
+ var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');
+ var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF;
+ var MAXIMUM_ALLOWED_INDEX_EXCEEDED = 'Maximum allowed index exceeded'; // We can't use this feature detection in V8 since it causes
+ // deoptimization and serious performance degradation
+ // https://github.com/zloirock/core-js/issues/679
+
+ var IS_CONCAT_SPREADABLE_SUPPORT = engineV8Version >= 51 || !fails(function () {
+ var array = [];
+ array[IS_CONCAT_SPREADABLE] = false;
+ return array.concat()[0] !== array;
+ });
+ var SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('concat');
+
+ var isConcatSpreadable = function isConcatSpreadable(O) {
+ if (!isObject(O)) return false;
+ var spreadable = O[IS_CONCAT_SPREADABLE];
+ return spreadable !== undefined ? !!spreadable : isArray(O);
+ };
+
+ var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !SPECIES_SUPPORT; // `Array.prototype.concat` method
+ // https://tc39.es/ecma262/#sec-array.prototype.concat
+ // with adding support of @@isConcatSpreadable and @@species
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: FORCED
+ }, {
+ concat: function concat(arg) {
+ // eslint-disable-line no-unused-vars
+ var O = toObject(this);
+ var A = arraySpeciesCreate(O, 0);
+ var n = 0;
+ var i, k, length, len, E;
+
+ for (i = -1, length = arguments.length; i < length; i++) {
+ E = i === -1 ? O : arguments[i];
+
+ if (isConcatSpreadable(E)) {
+ len = toLength(E.length);
+ if (n + len > MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
+
+ for (k = 0; k < len; k++, n++) {
+ if (k in E) createProperty(A, n, E[k]);
+ }
+ } else {
+ if (n >= MAX_SAFE_INTEGER) throw TypeError(MAXIMUM_ALLOWED_INDEX_EXCEEDED);
+ createProperty(A, n++, E);
+ }
+ }
+
+ A.length = n;
+ return A;
+ }
+ });
+
+ var aFunction$1 = function aFunction(it) {
+ if (typeof it != 'function') {
+ throw TypeError(String(it) + ' is not a function');
+ }
+
+ return it;
+ };
+
+ var functionBindContext = function functionBindContext(fn, that, length) {
+ aFunction$1(fn);
+ if (that === undefined) return fn;
+
+ switch (length) {
+ case 0:
+ return function () {
+ return fn.call(that);
+ };
+
+ case 1:
+ return function (a) {
+ return fn.call(that, a);
+ };
+
+ case 2:
+ return function (a, b) {
+ return fn.call(that, a, b);
+ };
+
+ case 3:
+ return function (a, b, c) {
+ return fn.call(that, a, b, c);
+ };
+ }
+
+ return function ()
+ /* ...args */
+ {
+ return fn.apply(that, arguments);
+ };
+ };
+
+ var push = [].push; // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterOut }` methods implementation
+
+ var createMethod$1 = function createMethod(TYPE) {
+ var IS_MAP = TYPE == 1;
+ var IS_FILTER = TYPE == 2;
+ var IS_SOME = TYPE == 3;
+ var IS_EVERY = TYPE == 4;
+ var IS_FIND_INDEX = TYPE == 6;
+ var IS_FILTER_OUT = TYPE == 7;
+ var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
+ return function ($this, callbackfn, that, specificCreate) {
+ var O = toObject($this);
+ var self = indexedObject(O);
+ var boundFunction = functionBindContext(callbackfn, that, 3);
+ var length = toLength(self.length);
+ var index = 0;
+ var create = specificCreate || arraySpeciesCreate;
+ var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_OUT ? create($this, 0) : undefined;
+ var value, result;
+
+ for (; length > index; index++) {
+ if (NO_HOLES || index in self) {
+ value = self[index];
+ result = boundFunction(value, index, O);
+
+ if (TYPE) {
+ if (IS_MAP) target[index] = result; // map
+ else if (result) switch (TYPE) {
+ case 3:
+ return true;
+ // some
+
+ case 5:
+ return value;
+ // find
+
+ case 6:
+ return index;
+ // findIndex
+
+ case 2:
+ push.call(target, value);
+ // filter
+ } else switch (TYPE) {
+ case 4:
+ return false;
+ // every
+
+ case 7:
+ push.call(target, value);
+ // filterOut
+ }
+ }
+ }
+ }
+
+ return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
+ };
+ };
+
+ var arrayIteration = {
+ // `Array.prototype.forEach` method
+ // https://tc39.es/ecma262/#sec-array.prototype.foreach
+ forEach: createMethod$1(0),
+ // `Array.prototype.map` method
+ // https://tc39.es/ecma262/#sec-array.prototype.map
+ map: createMethod$1(1),
+ // `Array.prototype.filter` method
+ // https://tc39.es/ecma262/#sec-array.prototype.filter
+ filter: createMethod$1(2),
+ // `Array.prototype.some` method
+ // https://tc39.es/ecma262/#sec-array.prototype.some
+ some: createMethod$1(3),
+ // `Array.prototype.every` method
+ // https://tc39.es/ecma262/#sec-array.prototype.every
+ every: createMethod$1(4),
+ // `Array.prototype.find` method
+ // https://tc39.es/ecma262/#sec-array.prototype.find
+ find: createMethod$1(5),
+ // `Array.prototype.findIndex` method
+ // https://tc39.es/ecma262/#sec-array.prototype.findIndex
+ findIndex: createMethod$1(6),
+ // `Array.prototype.filterOut` method
+ // https://github.com/tc39/proposal-array-filtering
+ filterOut: createMethod$1(7)
+ };
+
+ var defineProperty = Object.defineProperty;
+ var cache = {};
+
+ var thrower = function thrower(it) {
+ throw it;
+ };
+
+ var arrayMethodUsesToLength = function arrayMethodUsesToLength(METHOD_NAME, options) {
+ if (has(cache, METHOD_NAME)) return cache[METHOD_NAME];
+ if (!options) options = {};
+ var method = [][METHOD_NAME];
+ var ACCESSORS = has(options, 'ACCESSORS') ? options.ACCESSORS : false;
+ var argument0 = has(options, 0) ? options[0] : thrower;
+ var argument1 = has(options, 1) ? options[1] : undefined;
+ return cache[METHOD_NAME] = !!method && !fails(function () {
+ if (ACCESSORS && !descriptors) return true;
+ var O = {
+ length: -1
+ };
+ if (ACCESSORS) defineProperty(O, 1, {
+ enumerable: true,
+ get: thrower
+ });else O[1] = 1;
+ method.call(O, argument0, argument1);
+ });
+ };
+
+ var $filter = arrayIteration.filter;
+ var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('filter'); // Edge 14- issue
+
+ var USES_TO_LENGTH = arrayMethodUsesToLength('filter'); // `Array.prototype.filter` method
+ // https://tc39.es/ecma262/#sec-array.prototype.filter
+ // with adding support of @@species
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: !HAS_SPECIES_SUPPORT || !USES_TO_LENGTH
+ }, {
+ filter: function filter(callbackfn
+ /* , thisArg */
+ ) {
+ return $filter(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
+ }
+ });
+
+ // https://tc39.es/ecma262/#sec-object.keys
+
+ var objectKeys = Object.keys || function keys(O) {
+ return objectKeysInternal(O, enumBugKeys);
+ };
+
+ // https://tc39.es/ecma262/#sec-object.defineproperties
+
+ var objectDefineProperties = descriptors ? Object.defineProperties : function defineProperties(O, Properties) {
+ anObject(O);
+ var keys = objectKeys(Properties);
+ var length = keys.length;
+ var index = 0;
+ var key;
+
+ while (length > index) {
+ objectDefineProperty.f(O, key = keys[index++], Properties[key]);
+ }
+
+ return O;
+ };
+
+ var html = getBuiltIn('document', 'documentElement');
+
+ var GT = '>';
+ var LT = '<';
+ var PROTOTYPE = 'prototype';
+ var SCRIPT = 'script';
+ var IE_PROTO = sharedKey('IE_PROTO');
+
+ var EmptyConstructor = function EmptyConstructor() {
+ /* empty */
+ };
+
+ var scriptTag = function scriptTag(content) {
+ return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
+ }; // Create object with fake `null` prototype: use ActiveX Object with cleared prototype
+
+
+ var NullProtoObjectViaActiveX = function NullProtoObjectViaActiveX(activeXDocument) {
+ activeXDocument.write(scriptTag(''));
+ activeXDocument.close();
+ var temp = activeXDocument.parentWindow.Object;
+ activeXDocument = null; // avoid memory leak
+
+ return temp;
+ }; // Create object with fake `null` prototype: use iframe Object with cleared prototype
+
+
+ var NullProtoObjectViaIFrame = function NullProtoObjectViaIFrame() {
+ // Thrash, waste and sodomy: IE GC bug
+ var iframe = documentCreateElement('iframe');
+ var JS = 'java' + SCRIPT + ':';
+ var iframeDocument;
+ iframe.style.display = 'none';
+ html.appendChild(iframe); // https://github.com/zloirock/core-js/issues/475
+
+ iframe.src = String(JS);
+ iframeDocument = iframe.contentWindow.document;
+ iframeDocument.open();
+ iframeDocument.write(scriptTag('document.F=Object'));
+ iframeDocument.close();
+ return iframeDocument.F;
+ }; // Check for document.domain and active x support
+ // No need to use active x approach when document.domain is not set
+ // see https://github.com/es-shims/es5-shim/issues/150
+ // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
+ // avoid IE GC bug
+
+
+ var activeXDocument;
+
+ var _NullProtoObject = function NullProtoObject() {
+ try {
+ /* global ActiveXObject */
+ activeXDocument = document.domain && new ActiveXObject('htmlfile');
+ } catch (error) {
+ /* ignore */
+ }
+
+ _NullProtoObject = activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame();
+ var length = enumBugKeys.length;
+
+ while (length--) {
+ delete _NullProtoObject[PROTOTYPE][enumBugKeys[length]];
+ }
+
+ return _NullProtoObject();
+ };
+
+ hiddenKeys[IE_PROTO] = true; // `Object.create` method
+ // https://tc39.es/ecma262/#sec-object.create
+
+ var objectCreate = Object.create || function create(O, Properties) {
+ var result;
+
+ if (O !== null) {
+ EmptyConstructor[PROTOTYPE] = anObject(O);
+ result = new EmptyConstructor();
+ EmptyConstructor[PROTOTYPE] = null; // add "__proto__" for Object.getPrototypeOf polyfill
+
+ result[IE_PROTO] = O;
+ } else result = _NullProtoObject();
+
+ return Properties === undefined ? result : objectDefineProperties(result, Properties);
+ };
+
+ var UNSCOPABLES = wellKnownSymbol('unscopables');
+ var ArrayPrototype = Array.prototype; // Array.prototype[@@unscopables]
+ // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
+
+ if (ArrayPrototype[UNSCOPABLES] == undefined) {
+ objectDefineProperty.f(ArrayPrototype, UNSCOPABLES, {
+ configurable: true,
+ value: objectCreate(null)
+ });
+ } // add a key to Array.prototype[@@unscopables]
+
+
+ var addToUnscopables = function addToUnscopables(key) {
+ ArrayPrototype[UNSCOPABLES][key] = true;
+ };
+
+ var iterators = {};
+
+ var correctPrototypeGetter = !fails(function () {
+ function F() {
+ /* empty */
+ }
+
+ F.prototype.constructor = null;
+ return Object.getPrototypeOf(new F()) !== F.prototype;
+ });
+
+ var IE_PROTO$1 = sharedKey('IE_PROTO');
+ var ObjectPrototype = Object.prototype; // `Object.getPrototypeOf` method
+ // https://tc39.es/ecma262/#sec-object.getprototypeof
+
+ var objectGetPrototypeOf = correctPrototypeGetter ? Object.getPrototypeOf : function (O) {
+ O = toObject(O);
+ if (has(O, IE_PROTO$1)) return O[IE_PROTO$1];
+
+ if (typeof O.constructor == 'function' && O instanceof O.constructor) {
+ return O.constructor.prototype;
+ }
+
+ return O instanceof Object ? ObjectPrototype : null;
+ };
+
+ var ITERATOR = wellKnownSymbol('iterator');
+ var BUGGY_SAFARI_ITERATORS = false;
+
+ var returnThis = function returnThis() {
+ return this;
+ }; // `%IteratorPrototype%` object
+ // https://tc39.es/ecma262/#sec-%iteratorprototype%-object
+
+
+ var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;
+
+ if ([].keys) {
+ arrayIterator = [].keys(); // Safari 8 has buggy iterators w/o `next`
+
+ if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;else {
+ PrototypeOfArrayIteratorPrototype = objectGetPrototypeOf(objectGetPrototypeOf(arrayIterator));
+ if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;
+ }
+ }
+
+ var NEW_ITERATOR_PROTOTYPE = IteratorPrototype == undefined || fails(function () {
+ var test = {}; // FF44- legacy iterators case
+
+ return IteratorPrototype[ITERATOR].call(test) !== test;
+ });
+ if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype = {}; // 25.1.2.1.1 %IteratorPrototype%[@@iterator]()
+
+ if ( !has(IteratorPrototype, ITERATOR)) {
+ createNonEnumerableProperty(IteratorPrototype, ITERATOR, returnThis);
+ }
+
+ var iteratorsCore = {
+ IteratorPrototype: IteratorPrototype,
+ BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS
+ };
+
+ var defineProperty$1 = objectDefineProperty.f;
+ var TO_STRING_TAG = wellKnownSymbol('toStringTag');
+
+ var setToStringTag = function setToStringTag(it, TAG, STATIC) {
+ if (it && !has(it = STATIC ? it : it.prototype, TO_STRING_TAG)) {
+ defineProperty$1(it, TO_STRING_TAG, {
+ configurable: true,
+ value: TAG
+ });
+ }
+ };
+
+ var IteratorPrototype$1 = iteratorsCore.IteratorPrototype;
+
+ var returnThis$1 = function returnThis() {
+ return this;
+ };
+
+ var createIteratorConstructor = function createIteratorConstructor(IteratorConstructor, NAME, next) {
+ var TO_STRING_TAG = NAME + ' Iterator';
+ IteratorConstructor.prototype = objectCreate(IteratorPrototype$1, {
+ next: createPropertyDescriptor(1, next)
+ });
+ setToStringTag(IteratorConstructor, TO_STRING_TAG, false);
+ iterators[TO_STRING_TAG] = returnThis$1;
+ return IteratorConstructor;
+ };
+
+ var aPossiblePrototype = function aPossiblePrototype(it) {
+ if (!isObject(it) && it !== null) {
+ throw TypeError("Can't set " + String(it) + ' as a prototype');
+ }
+
+ return it;
+ };
+
+ // https://tc39.es/ecma262/#sec-object.setprototypeof
+ // Works with __proto__ only. Old v8 can't work with null proto objects.
+
+ /* eslint-disable no-proto */
+
+ var objectSetPrototypeOf = Object.setPrototypeOf || ('__proto__' in {} ? function () {
+ var CORRECT_SETTER = false;
+ var test = {};
+ var setter;
+
+ try {
+ setter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
+ setter.call(test, []);
+ CORRECT_SETTER = test instanceof Array;
+ } catch (error) {
+ /* empty */
+ }
+
+ return function setPrototypeOf(O, proto) {
+ anObject(O);
+ aPossiblePrototype(proto);
+ if (CORRECT_SETTER) setter.call(O, proto);else O.__proto__ = proto;
+ return O;
+ };
+ }() : undefined);
+
+ var IteratorPrototype$2 = iteratorsCore.IteratorPrototype;
+ var BUGGY_SAFARI_ITERATORS$1 = iteratorsCore.BUGGY_SAFARI_ITERATORS;
+ var ITERATOR$1 = wellKnownSymbol('iterator');
+ var KEYS = 'keys';
+ var VALUES = 'values';
+ var ENTRIES = 'entries';
+
+ var returnThis$2 = function returnThis() {
+ return this;
+ };
+
+ var defineIterator = function defineIterator(Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
+ createIteratorConstructor(IteratorConstructor, NAME, next);
+
+ var getIterationMethod = function getIterationMethod(KIND) {
+ if (KIND === DEFAULT && defaultIterator) return defaultIterator;
+ if (!BUGGY_SAFARI_ITERATORS$1 && KIND in IterablePrototype) return IterablePrototype[KIND];
+
+ switch (KIND) {
+ case KEYS:
+ return function keys() {
+ return new IteratorConstructor(this, KIND);
+ };
+
+ case VALUES:
+ return function values() {
+ return new IteratorConstructor(this, KIND);
+ };
+
+ case ENTRIES:
+ return function entries() {
+ return new IteratorConstructor(this, KIND);
+ };
+ }
+
+ return function () {
+ return new IteratorConstructor(this);
+ };
+ };
+
+ var TO_STRING_TAG = NAME + ' Iterator';
+ var INCORRECT_VALUES_NAME = false;
+ var IterablePrototype = Iterable.prototype;
+ var nativeIterator = IterablePrototype[ITERATOR$1] || IterablePrototype['@@iterator'] || DEFAULT && IterablePrototype[DEFAULT];
+ var defaultIterator = !BUGGY_SAFARI_ITERATORS$1 && nativeIterator || getIterationMethod(DEFAULT);
+ var anyNativeIterator = NAME == 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
+ var CurrentIteratorPrototype, methods, KEY; // fix native
+
+ if (anyNativeIterator) {
+ CurrentIteratorPrototype = objectGetPrototypeOf(anyNativeIterator.call(new Iterable()));
+
+ if (IteratorPrototype$2 !== Object.prototype && CurrentIteratorPrototype.next) {
+ if ( objectGetPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype$2) {
+ if (objectSetPrototypeOf) {
+ objectSetPrototypeOf(CurrentIteratorPrototype, IteratorPrototype$2);
+ } else if (typeof CurrentIteratorPrototype[ITERATOR$1] != 'function') {
+ createNonEnumerableProperty(CurrentIteratorPrototype, ITERATOR$1, returnThis$2);
+ }
+ } // Set @@toStringTag to native iterators
+
+
+ setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true);
+ }
+ } // fix Array#{values, @@iterator}.name in V8 / FF
+
+
+ if (DEFAULT == VALUES && nativeIterator && nativeIterator.name !== VALUES) {
+ INCORRECT_VALUES_NAME = true;
+
+ defaultIterator = function values() {
+ return nativeIterator.call(this);
+ };
+ } // define iterator
+
+
+ if ( IterablePrototype[ITERATOR$1] !== defaultIterator) {
+ createNonEnumerableProperty(IterablePrototype, ITERATOR$1, defaultIterator);
+ }
+
+ iterators[NAME] = defaultIterator; // export additional methods
+
+ if (DEFAULT) {
+ methods = {
+ values: getIterationMethod(VALUES),
+ keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
+ entries: getIterationMethod(ENTRIES)
+ };
+ if (FORCED) for (KEY in methods) {
+ if (BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
+ redefine(IterablePrototype, KEY, methods[KEY]);
+ }
+ } else _export({
+ target: NAME,
+ proto: true,
+ forced: BUGGY_SAFARI_ITERATORS$1 || INCORRECT_VALUES_NAME
+ }, methods);
+ }
+
+ return methods;
+ };
+
+ var ARRAY_ITERATOR = 'Array Iterator';
+ var setInternalState = internalState.set;
+ var getInternalState = internalState.getterFor(ARRAY_ITERATOR); // `Array.prototype.entries` method
+ // https://tc39.es/ecma262/#sec-array.prototype.entries
+ // `Array.prototype.keys` method
+ // https://tc39.es/ecma262/#sec-array.prototype.keys
+ // `Array.prototype.values` method
+ // https://tc39.es/ecma262/#sec-array.prototype.values
+ // `Array.prototype[@@iterator]` method
+ // https://tc39.es/ecma262/#sec-array.prototype-@@iterator
+ // `CreateArrayIterator` internal method
+ // https://tc39.es/ecma262/#sec-createarrayiterator
+
+ var es_array_iterator = defineIterator(Array, 'Array', function (iterated, kind) {
+ setInternalState(this, {
+ type: ARRAY_ITERATOR,
+ target: toIndexedObject(iterated),
+ // target
+ index: 0,
+ // next index
+ kind: kind // kind
+
+ }); // `%ArrayIteratorPrototype%.next` method
+ // https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next
+ }, function () {
+ var state = getInternalState(this);
+ var target = state.target;
+ var kind = state.kind;
+ var index = state.index++;
+
+ if (!target || index >= target.length) {
+ state.target = undefined;
+ return {
+ value: undefined,
+ done: true
+ };
+ }
+
+ if (kind == 'keys') return {
+ value: index,
+ done: false
+ };
+ if (kind == 'values') return {
+ value: target[index],
+ done: false
+ };
+ return {
+ value: [index, target[index]],
+ done: false
+ };
+ }, 'values'); // argumentsList[@@iterator] is %ArrayProto_values%
+ // https://tc39.es/ecma262/#sec-createunmappedargumentsobject
+ // https://tc39.es/ecma262/#sec-createmappedargumentsobject
+
+ iterators.Arguments = iterators.Array; // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
+
+ addToUnscopables('keys');
+ addToUnscopables('values');
+ addToUnscopables('entries');
+
+ var HAS_SPECIES_SUPPORT$1 = arrayMethodHasSpeciesSupport('splice');
+ var USES_TO_LENGTH$1 = arrayMethodUsesToLength('splice', {
+ ACCESSORS: true,
+ 0: 0,
+ 1: 2
+ });
+ var max$1 = Math.max;
+ var min$2 = Math.min;
+ var MAX_SAFE_INTEGER$1 = 0x1FFFFFFFFFFFFF;
+ var MAXIMUM_ALLOWED_LENGTH_EXCEEDED = 'Maximum allowed length exceeded'; // `Array.prototype.splice` method
+ // https://tc39.es/ecma262/#sec-array.prototype.splice
+ // with adding support of @@species
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: !HAS_SPECIES_SUPPORT$1 || !USES_TO_LENGTH$1
+ }, {
+ splice: function splice(start, deleteCount
+ /* , ...items */
+ ) {
+ var O = toObject(this);
+ var len = toLength(O.length);
+ var actualStart = toAbsoluteIndex(start, len);
+ var argumentsLength = arguments.length;
+ var insertCount, actualDeleteCount, A, k, from, to;
+
+ if (argumentsLength === 0) {
+ insertCount = actualDeleteCount = 0;
+ } else if (argumentsLength === 1) {
+ insertCount = 0;
+ actualDeleteCount = len - actualStart;
+ } else {
+ insertCount = argumentsLength - 2;
+ actualDeleteCount = min$2(max$1(toInteger(deleteCount), 0), len - actualStart);
+ }
+
+ if (len + insertCount - actualDeleteCount > MAX_SAFE_INTEGER$1) {
+ throw TypeError(MAXIMUM_ALLOWED_LENGTH_EXCEEDED);
+ }
+
+ A = arraySpeciesCreate(O, actualDeleteCount);
+
+ for (k = 0; k < actualDeleteCount; k++) {
+ from = actualStart + k;
+ if (from in O) createProperty(A, k, O[from]);
+ }
+
+ A.length = actualDeleteCount;
+
+ if (insertCount < actualDeleteCount) {
+ for (k = actualStart; k < len - actualDeleteCount; k++) {
+ from = k + actualDeleteCount;
+ to = k + insertCount;
+ if (from in O) O[to] = O[from];else delete O[to];
+ }
+
+ for (k = len; k > len - actualDeleteCount + insertCount; k--) {
+ delete O[k - 1];
+ }
+ } else if (insertCount > actualDeleteCount) {
+ for (k = len - actualDeleteCount; k > actualStart; k--) {
+ from = k + actualDeleteCount - 1;
+ to = k + insertCount - 1;
+ if (from in O) O[to] = O[from];else delete O[to];
+ }
+ }
+
+ for (k = 0; k < insertCount; k++) {
+ O[k + actualStart] = arguments[k + 2];
+ }
+
+ O.length = len - actualDeleteCount + insertCount;
+ return A;
+ }
+ });
+
+ var defineProperty$2 = objectDefineProperty.f;
+ var FunctionPrototype = Function.prototype;
+ var FunctionPrototypeToString = FunctionPrototype.toString;
+ var nameRE = /^\s*function ([^ (]*)/;
+ var NAME = 'name'; // Function instances `.name` property
+ // https://tc39.es/ecma262/#sec-function-instances-name
+
+ if (descriptors && !(NAME in FunctionPrototype)) {
+ defineProperty$2(FunctionPrototype, NAME, {
+ configurable: true,
+ get: function get() {
+ try {
+ return FunctionPrototypeToString.call(this).match(nameRE)[1];
+ } catch (error) {
+ return '';
+ }
+ }
+ });
+ }
+
+ var inheritIfRequired = function inheritIfRequired($this, dummy, Wrapper) {
+ var NewTarget, NewTargetPrototype;
+ if ( // it can work only with native `setPrototypeOf`
+ objectSetPrototypeOf && // we haven't completely correct pre-ES6 way for getting `new.target`, so use this
+ typeof (NewTarget = dummy.constructor) == 'function' && NewTarget !== Wrapper && isObject(NewTargetPrototype = NewTarget.prototype) && NewTargetPrototype !== Wrapper.prototype) objectSetPrototypeOf($this, NewTargetPrototype);
+ return $this;
+ };
+
+ // a string of all valid unicode whitespaces
+ // eslint-disable-next-line max-len
+ var whitespaces = "\t\n\x0B\f\r \xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF";
+
+ var whitespace = '[' + whitespaces + ']';
+ var ltrim = RegExp('^' + whitespace + whitespace + '*');
+ var rtrim = RegExp(whitespace + whitespace + '*$'); // `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
+
+ var createMethod$2 = function createMethod(TYPE) {
+ return function ($this) {
+ var string = String(requireObjectCoercible($this));
+ if (TYPE & 1) string = string.replace(ltrim, '');
+ if (TYPE & 2) string = string.replace(rtrim, '');
+ return string;
+ };
+ };
+
+ var stringTrim = {
+ // `String.prototype.{ trimLeft, trimStart }` methods
+ // https://tc39.es/ecma262/#sec-string.prototype.trimstart
+ start: createMethod$2(1),
+ // `String.prototype.{ trimRight, trimEnd }` methods
+ // https://tc39.es/ecma262/#sec-string.prototype.trimend
+ end: createMethod$2(2),
+ // `String.prototype.trim` method
+ // https://tc39.es/ecma262/#sec-string.prototype.trim
+ trim: createMethod$2(3)
+ };
+
+ var getOwnPropertyNames = objectGetOwnPropertyNames.f;
+ var getOwnPropertyDescriptor$2 = objectGetOwnPropertyDescriptor.f;
+ var defineProperty$3 = objectDefineProperty.f;
+ var trim = stringTrim.trim;
+ var NUMBER = 'Number';
+ var NativeNumber = global$1[NUMBER];
+ var NumberPrototype = NativeNumber.prototype; // Opera ~12 has broken Object#toString
+
+ var BROKEN_CLASSOF = classofRaw(objectCreate(NumberPrototype)) == NUMBER; // `ToNumber` abstract operation
+ // https://tc39.es/ecma262/#sec-tonumber
+
+ var toNumber = function toNumber(argument) {
+ var it = toPrimitive(argument, false);
+ var first, third, radix, maxCode, digits, length, index, code;
+
+ if (typeof it == 'string' && it.length > 2) {
+ it = trim(it);
+ first = it.charCodeAt(0);
+
+ if (first === 43 || first === 45) {
+ third = it.charCodeAt(2);
+ if (third === 88 || third === 120) return NaN; // Number('+0x1') should be NaN, old V8 fix
+ } else if (first === 48) {
+ switch (it.charCodeAt(1)) {
+ case 66:
+ case 98:
+ radix = 2;
+ maxCode = 49;
+ break;
+ // fast equal of /^0b[01]+$/i
+
+ case 79:
+ case 111:
+ radix = 8;
+ maxCode = 55;
+ break;
+ // fast equal of /^0o[0-7]+$/i
+
+ default:
+ return +it;
+ }
+
+ digits = it.slice(2);
+ length = digits.length;
+
+ for (index = 0; index < length; index++) {
+ code = digits.charCodeAt(index); // parseInt parses a string to a first unavailable symbol
+ // but ToNumber should return NaN if a string contains unavailable symbols
+
+ if (code < 48 || code > maxCode) return NaN;
+ }
+
+ return parseInt(digits, radix);
+ }
+ }
+
+ return +it;
+ }; // `Number` constructor
+ // https://tc39.es/ecma262/#sec-number-constructor
+
+
+ if (isForced_1(NUMBER, !NativeNumber(' 0o1') || !NativeNumber('0b1') || NativeNumber('+0x1'))) {
+ var NumberWrapper = function Number(value) {
+ var it = arguments.length < 1 ? 0 : value;
+ var dummy = this;
+ return dummy instanceof NumberWrapper // check on 1..constructor(foo) case
+ && (BROKEN_CLASSOF ? fails(function () {
+ NumberPrototype.valueOf.call(dummy);
+ }) : classofRaw(dummy) != NUMBER) ? inheritIfRequired(new NativeNumber(toNumber(it)), dummy, NumberWrapper) : toNumber(it);
+ };
+
+ for (var keys$1 = descriptors ? getOwnPropertyNames(NativeNumber) : ( // ES3:
+ 'MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,' + // ES2015 (in case, if modules with ES2015 Number statics required before):
+ 'EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,' + 'MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger,' + // ESNext
+ 'fromString,range').split(','), j = 0, key; keys$1.length > j; j++) {
+ if (has(NativeNumber, key = keys$1[j]) && !has(NumberWrapper, key)) {
+ defineProperty$3(NumberWrapper, key, getOwnPropertyDescriptor$2(NativeNumber, key));
+ }
+ }
+
+ NumberWrapper.prototype = NumberPrototype;
+ NumberPrototype.constructor = NumberWrapper;
+ redefine(global$1, NUMBER, NumberWrapper);
+ }
+
+ var nativeAssign = Object.assign;
+ var defineProperty$4 = Object.defineProperty; // `Object.assign` method
+ // https://tc39.es/ecma262/#sec-object.assign
+
+ var objectAssign = !nativeAssign || fails(function () {
+ // should have correct order of operations (Edge bug)
+ if (descriptors && nativeAssign({
+ b: 1
+ }, nativeAssign(defineProperty$4({}, 'a', {
+ enumerable: true,
+ get: function get() {
+ defineProperty$4(this, 'b', {
+ value: 3,
+ enumerable: false
+ });
+ }
+ }), {
+ b: 2
+ })).b !== 1) return true; // should work with symbols and should have deterministic property order (V8 bug)
+
+ var A = {};
+ var B = {}; // eslint-disable-next-line no-undef
+
+ var symbol = Symbol();
+ var alphabet = 'abcdefghijklmnopqrst';
+ A[symbol] = 7;
+ alphabet.split('').forEach(function (chr) {
+ B[chr] = chr;
+ });
+ return nativeAssign({}, A)[symbol] != 7 || objectKeys(nativeAssign({}, B)).join('') != alphabet;
+ }) ? function assign(target, source) {
+ // eslint-disable-line no-unused-vars
+ var T = toObject(target);
+ var argumentsLength = arguments.length;
+ var index = 1;
+ var getOwnPropertySymbols = objectGetOwnPropertySymbols.f;
+ var propertyIsEnumerable = objectPropertyIsEnumerable.f;
+
+ while (argumentsLength > index) {
+ var S = indexedObject(arguments[index++]);
+ var keys = getOwnPropertySymbols ? objectKeys(S).concat(getOwnPropertySymbols(S)) : objectKeys(S);
+ var length = keys.length;
+ var j = 0;
+ var key;
+
+ while (length > j) {
+ key = keys[j++];
+ if (!descriptors || propertyIsEnumerable.call(S, key)) T[key] = S[key];
+ }
+ }
+
+ return T;
+ } : nativeAssign;
+
+ // https://tc39.es/ecma262/#sec-object.assign
+
+ _export({
+ target: 'Object',
+ stat: true,
+ forced: Object.assign !== objectAssign
+ }, {
+ assign: objectAssign
+ });
+
+ var TO_STRING_TAG$1 = wellKnownSymbol('toStringTag');
+ var test = {};
+ test[TO_STRING_TAG$1] = 'z';
+ var toStringTagSupport = String(test) === '[object z]';
+
+ var TO_STRING_TAG$2 = wellKnownSymbol('toStringTag'); // ES3 wrong here
+
+ var CORRECT_ARGUMENTS = classofRaw(function () {
+ return arguments;
+ }()) == 'Arguments'; // fallback for IE11 Script Access Denied error
+
+ var tryGet = function tryGet(it, key) {
+ try {
+ return it[key];
+ } catch (error) {
+ /* empty */
+ }
+ }; // getting tag from ES6+ `Object.prototype.toString`
+
+
+ var classof = toStringTagSupport ? classofRaw : function (it) {
+ var O, tag, result;
+ return it === undefined ? 'Undefined' : it === null ? 'Null' // @@toStringTag case
+ : typeof (tag = tryGet(O = Object(it), TO_STRING_TAG$2)) == 'string' ? tag // builtinTag case
+ : CORRECT_ARGUMENTS ? classofRaw(O) // ES3 arguments fallback
+ : (result = classofRaw(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : result;
+ };
+
+ // https://tc39.es/ecma262/#sec-object.prototype.tostring
+
+
+ var objectToString = toStringTagSupport ? {}.toString : function toString() {
+ return '[object ' + classof(this) + ']';
+ };
+
+ // https://tc39.es/ecma262/#sec-object.prototype.tostring
+
+ if (!toStringTagSupport) {
+ redefine(Object.prototype, 'toString', objectToString, {
+ unsafe: true
+ });
+ }
+
+ var nativePromiseConstructor = global$1.Promise;
+
+ var redefineAll = function redefineAll(target, src, options) {
+ for (var key in src) {
+ redefine(target, key, src[key], options);
+ }
+
+ return target;
+ };
+
+ var SPECIES$2 = wellKnownSymbol('species');
+
+ var setSpecies = function setSpecies(CONSTRUCTOR_NAME) {
+ var Constructor = getBuiltIn(CONSTRUCTOR_NAME);
+ var defineProperty = objectDefineProperty.f;
+
+ if (descriptors && Constructor && !Constructor[SPECIES$2]) {
+ defineProperty(Constructor, SPECIES$2, {
+ configurable: true,
+ get: function get() {
+ return this;
+ }
+ });
+ }
+ };
+
+ var anInstance = function anInstance(it, Constructor, name) {
+ if (!(it instanceof Constructor)) {
+ throw TypeError('Incorrect ' + (name ? name + ' ' : '') + 'invocation');
+ }
+
+ return it;
+ };
+
+ var ITERATOR$2 = wellKnownSymbol('iterator');
+ var ArrayPrototype$1 = Array.prototype; // check on default Array iterator
+
+ var isArrayIteratorMethod = function isArrayIteratorMethod(it) {
+ return it !== undefined && (iterators.Array === it || ArrayPrototype$1[ITERATOR$2] === it);
+ };
+
+ var ITERATOR$3 = wellKnownSymbol('iterator');
+
+ var getIteratorMethod = function getIteratorMethod(it) {
+ if (it != undefined) return it[ITERATOR$3] || it['@@iterator'] || iterators[classof(it)];
+ };
+
+ var iteratorClose = function iteratorClose(iterator) {
+ var returnMethod = iterator['return'];
+
+ if (returnMethod !== undefined) {
+ return anObject(returnMethod.call(iterator)).value;
+ }
+ };
+
+ var Result = function Result(stopped, result) {
+ this.stopped = stopped;
+ this.result = result;
+ };
+
+ var iterate = function iterate(iterable, unboundFunction, options) {
+ var that = options && options.that;
+ var AS_ENTRIES = !!(options && options.AS_ENTRIES);
+ var IS_ITERATOR = !!(options && options.IS_ITERATOR);
+ var INTERRUPTED = !!(options && options.INTERRUPTED);
+ var fn = functionBindContext(unboundFunction, that, 1 + AS_ENTRIES + INTERRUPTED);
+ var iterator, iterFn, index, length, result, next, step;
+
+ var stop = function stop(condition) {
+ if (iterator) iteratorClose(iterator);
+ return new Result(true, condition);
+ };
+
+ var callFn = function callFn(value) {
+ if (AS_ENTRIES) {
+ anObject(value);
+ return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]);
+ }
+
+ return INTERRUPTED ? fn(value, stop) : fn(value);
+ };
+
+ if (IS_ITERATOR) {
+ iterator = iterable;
+ } else {
+ iterFn = getIteratorMethod(iterable);
+ if (typeof iterFn != 'function') throw TypeError('Target is not iterable'); // optimisation for array iterators
+
+ if (isArrayIteratorMethod(iterFn)) {
+ for (index = 0, length = toLength(iterable.length); length > index; index++) {
+ result = callFn(iterable[index]);
+ if (result && result instanceof Result) return result;
+ }
+
+ return new Result(false);
+ }
+
+ iterator = iterFn.call(iterable);
+ }
+
+ next = iterator.next;
+
+ while (!(step = next.call(iterator)).done) {
+ try {
+ result = callFn(step.value);
+ } catch (error) {
+ iteratorClose(iterator);
+ throw error;
+ }
+
+ if (_typeof(result) == 'object' && result && result instanceof Result) return result;
+ }
+
+ return new Result(false);
+ };
+
+ var ITERATOR$4 = wellKnownSymbol('iterator');
+ var SAFE_CLOSING = false;
+
+ try {
+ var called = 0;
+ var iteratorWithReturn = {
+ next: function next() {
+ return {
+ done: !!called++
+ };
+ },
+ 'return': function _return() {
+ SAFE_CLOSING = true;
+ }
+ };
+
+ iteratorWithReturn[ITERATOR$4] = function () {
+ return this;
+ }; // eslint-disable-next-line no-throw-literal
+
+
+ Array.from(iteratorWithReturn, function () {
+ throw 2;
+ });
+ } catch (error) {
+ /* empty */
+ }
+
+ var checkCorrectnessOfIteration = function checkCorrectnessOfIteration(exec, SKIP_CLOSING) {
+ if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
+ var ITERATION_SUPPORT = false;
+
+ try {
+ var object = {};
+
+ object[ITERATOR$4] = function () {
+ return {
+ next: function next() {
+ return {
+ done: ITERATION_SUPPORT = true
+ };
+ }
+ };
+ };
+
+ exec(object);
+ } catch (error) {
+ /* empty */
+ }
+
+ return ITERATION_SUPPORT;
+ };
+
+ var SPECIES$3 = wellKnownSymbol('species'); // `SpeciesConstructor` abstract operation
+ // https://tc39.es/ecma262/#sec-speciesconstructor
+
+ var speciesConstructor = function speciesConstructor(O, defaultConstructor) {
+ var C = anObject(O).constructor;
+ var S;
+ return C === undefined || (S = anObject(C)[SPECIES$3]) == undefined ? defaultConstructor : aFunction$1(S);
+ };
+
+ var engineIsIos = /(iphone|ipod|ipad).*applewebkit/i.test(engineUserAgent);
+
+ var engineIsNode = classofRaw(global$1.process) == 'process';
+
+ var location = global$1.location;
+ var set$1 = global$1.setImmediate;
+ var clear = global$1.clearImmediate;
+ var process$1 = global$1.process;
+ var MessageChannel = global$1.MessageChannel;
+ var Dispatch = global$1.Dispatch;
+ var counter = 0;
+ var queue = {};
+ var ONREADYSTATECHANGE = 'onreadystatechange';
+ var defer, channel, port;
+
+ var run = function run(id) {
+ // eslint-disable-next-line no-prototype-builtins
+ if (queue.hasOwnProperty(id)) {
+ var fn = queue[id];
+ delete queue[id];
+ fn();
+ }
+ };
+
+ var runner = function runner(id) {
+ return function () {
+ run(id);
+ };
+ };
+
+ var listener = function listener(event) {
+ run(event.data);
+ };
+
+ var post = function post(id) {
+ // old engines have not location.origin
+ global$1.postMessage(id + '', location.protocol + '//' + location.host);
+ }; // Node.js 0.9+ & IE10+ has setImmediate, otherwise:
+
+
+ if (!set$1 || !clear) {
+ set$1 = function setImmediate(fn) {
+ var args = [];
+ var i = 1;
+
+ while (arguments.length > i) {
+ args.push(arguments[i++]);
+ }
+
+ queue[++counter] = function () {
+ // eslint-disable-next-line no-new-func
+ (typeof fn == 'function' ? fn : Function(fn)).apply(undefined, args);
+ };
+
+ defer(counter);
+ return counter;
+ };
+
+ clear = function clearImmediate(id) {
+ delete queue[id];
+ }; // Node.js 0.8-
+
+
+ if (engineIsNode) {
+ defer = function defer(id) {
+ process$1.nextTick(runner(id));
+ }; // Sphere (JS game engine) Dispatch API
+
+ } else if (Dispatch && Dispatch.now) {
+ defer = function defer(id) {
+ Dispatch.now(runner(id));
+ }; // Browsers with MessageChannel, includes WebWorkers
+ // except iOS - https://github.com/zloirock/core-js/issues/624
+
+ } else if (MessageChannel && !engineIsIos) {
+ channel = new MessageChannel();
+ port = channel.port2;
+ channel.port1.onmessage = listener;
+ defer = functionBindContext(port.postMessage, port, 1); // Browsers with postMessage, skip WebWorkers
+ // IE8 has postMessage, but it's sync & typeof its postMessage is 'object'
+ } else if (global$1.addEventListener && typeof postMessage == 'function' && !global$1.importScripts && location && location.protocol !== 'file:' && !fails(post)) {
+ defer = post;
+ global$1.addEventListener('message', listener, false); // IE8-
+ } else if (ONREADYSTATECHANGE in documentCreateElement('script')) {
+ defer = function defer(id) {
+ html.appendChild(documentCreateElement('script'))[ONREADYSTATECHANGE] = function () {
+ html.removeChild(this);
+ run(id);
+ };
+ }; // Rest old browsers
+
+ } else {
+ defer = function defer(id) {
+ setTimeout(runner(id), 0);
+ };
+ }
+ }
+
+ var task = {
+ set: set$1,
+ clear: clear
+ };
+
+ var engineIsWebosWebkit = /web0s(?!.*chrome)/i.test(engineUserAgent);
+
+ var getOwnPropertyDescriptor$3 = objectGetOwnPropertyDescriptor.f;
+ var macrotask = task.set;
+ var MutationObserver = global$1.MutationObserver || global$1.WebKitMutationObserver;
+ var document$2 = global$1.document;
+ var process$2 = global$1.process;
+ var Promise$1 = global$1.Promise; // Node.js 11 shows ExperimentalWarning on getting `queueMicrotask`
+
+ var queueMicrotaskDescriptor = getOwnPropertyDescriptor$3(global$1, 'queueMicrotask');
+ var queueMicrotask = queueMicrotaskDescriptor && queueMicrotaskDescriptor.value;
+ var flush, head, last, notify, toggle, node, promise, then; // modern engines have queueMicrotask method
+
+ if (!queueMicrotask) {
+ flush = function flush() {
+ var parent, fn;
+ if (engineIsNode && (parent = process$2.domain)) parent.exit();
+
+ while (head) {
+ fn = head.fn;
+ head = head.next;
+
+ try {
+ fn();
+ } catch (error) {
+ if (head) notify();else last = undefined;
+ throw error;
+ }
+ }
+
+ last = undefined;
+ if (parent) parent.enter();
+ }; // browsers with MutationObserver, except iOS - https://github.com/zloirock/core-js/issues/339
+ // also except WebOS Webkit https://github.com/zloirock/core-js/issues/898
+
+
+ if (!engineIsIos && !engineIsNode && !engineIsWebosWebkit && MutationObserver && document$2) {
+ toggle = true;
+ node = document$2.createTextNode('');
+ new MutationObserver(flush).observe(node, {
+ characterData: true
+ });
+
+ notify = function notify() {
+ node.data = toggle = !toggle;
+ }; // environments with maybe non-completely correct, but existent Promise
+
+ } else if (Promise$1 && Promise$1.resolve) {
+ // Promise.resolve without an argument throws an error in LG WebOS 2
+ promise = Promise$1.resolve(undefined);
+ then = promise.then;
+
+ notify = function notify() {
+ then.call(promise, flush);
+ }; // Node.js without promises
+
+ } else if (engineIsNode) {
+ notify = function notify() {
+ process$2.nextTick(flush);
+ }; // for other environments - macrotask based on:
+ // - setImmediate
+ // - MessageChannel
+ // - window.postMessag
+ // - onreadystatechange
+ // - setTimeout
+
+ } else {
+ notify = function notify() {
+ // strange IE + webpack dev server bug - use .call(global)
+ macrotask.call(global$1, flush);
+ };
+ }
+ }
+
+ var microtask = queueMicrotask || function (fn) {
+ var task = {
+ fn: fn,
+ next: undefined
+ };
+ if (last) last.next = task;
+
+ if (!head) {
+ head = task;
+ notify();
+ }
+
+ last = task;
+ };
+
+ var PromiseCapability = function PromiseCapability(C) {
+ var resolve, reject;
+ this.promise = new C(function ($$resolve, $$reject) {
+ if (resolve !== undefined || reject !== undefined) throw TypeError('Bad Promise constructor');
+ resolve = $$resolve;
+ reject = $$reject;
+ });
+ this.resolve = aFunction$1(resolve);
+ this.reject = aFunction$1(reject);
+ }; // 25.4.1.5 NewPromiseCapability(C)
+
+
+ var f$5 = function f(C) {
+ return new PromiseCapability(C);
+ };
+
+ var newPromiseCapability = {
+ f: f$5
+ };
+
+ var promiseResolve = function promiseResolve(C, x) {
+ anObject(C);
+ if (isObject(x) && x.constructor === C) return x;
+ var promiseCapability = newPromiseCapability.f(C);
+ var resolve = promiseCapability.resolve;
+ resolve(x);
+ return promiseCapability.promise;
+ };
+
+ var hostReportErrors = function hostReportErrors(a, b) {
+ var console = global$1.console;
+
+ if (console && console.error) {
+ arguments.length === 1 ? console.error(a) : console.error(a, b);
+ }
+ };
+
+ var perform = function perform(exec) {
+ try {
+ return {
+ error: false,
+ value: exec()
+ };
+ } catch (error) {
+ return {
+ error: true,
+ value: error
+ };
+ }
+ };
+
+ var task$1 = task.set;
+ var SPECIES$4 = wellKnownSymbol('species');
+ var PROMISE = 'Promise';
+ var getInternalState$1 = internalState.get;
+ var setInternalState$1 = internalState.set;
+ var getInternalPromiseState = internalState.getterFor(PROMISE);
+ var PromiseConstructor = nativePromiseConstructor;
+ var TypeError$1 = global$1.TypeError;
+ var document$3 = global$1.document;
+ var process$3 = global$1.process;
+ var $fetch = getBuiltIn('fetch');
+ var newPromiseCapability$1 = newPromiseCapability.f;
+ var newGenericPromiseCapability = newPromiseCapability$1;
+ var DISPATCH_EVENT = !!(document$3 && document$3.createEvent && global$1.dispatchEvent);
+ var NATIVE_REJECTION_EVENT = typeof PromiseRejectionEvent == 'function';
+ var UNHANDLED_REJECTION = 'unhandledrejection';
+ var REJECTION_HANDLED = 'rejectionhandled';
+ var PENDING = 0;
+ var FULFILLED = 1;
+ var REJECTED = 2;
+ var HANDLED = 1;
+ var UNHANDLED = 2;
+ var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen;
+ var FORCED$1 = isForced_1(PROMISE, function () {
+ var GLOBAL_CORE_JS_PROMISE = inspectSource(PromiseConstructor) !== String(PromiseConstructor);
+
+ if (!GLOBAL_CORE_JS_PROMISE) {
+ // V8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=830565
+ // We can't detect it synchronously, so just check versions
+ if (engineV8Version === 66) return true; // Unhandled rejections tracking support, NodeJS Promise without it fails @@species test
+
+ if (!engineIsNode && !NATIVE_REJECTION_EVENT) return true;
+ } // We need Promise#finally in the pure version for preventing prototype pollution
+ // deoptimization and performance degradation
+ // https://github.com/zloirock/core-js/issues/679
+
+ if (engineV8Version >= 51 && /native code/.test(PromiseConstructor)) return false; // Detect correctness of subclassing with @@species support
+
+ var promise = PromiseConstructor.resolve(1);
+
+ var FakePromise = function FakePromise(exec) {
+ exec(function () {
+ /* empty */
+ }, function () {
+ /* empty */
+ });
+ };
+
+ var constructor = promise.constructor = {};
+ constructor[SPECIES$4] = FakePromise;
+ return !(promise.then(function () {
+ /* empty */
+ }) instanceof FakePromise);
+ });
+ var INCORRECT_ITERATION = FORCED$1 || !checkCorrectnessOfIteration(function (iterable) {
+ PromiseConstructor.all(iterable)['catch'](function () {
+ /* empty */
+ });
+ }); // helpers
+
+ var isThenable = function isThenable(it) {
+ var then;
+ return isObject(it) && typeof (then = it.then) == 'function' ? then : false;
+ };
+
+ var notify$1 = function notify(state, isReject) {
+ if (state.notified) return;
+ state.notified = true;
+ var chain = state.reactions;
+ microtask(function () {
+ var value = state.value;
+ var ok = state.state == FULFILLED;
+ var index = 0; // variable length - can't use forEach
+
+ while (chain.length > index) {
+ var reaction = chain[index++];
+ var handler = ok ? reaction.ok : reaction.fail;
+ var resolve = reaction.resolve;
+ var reject = reaction.reject;
+ var domain = reaction.domain;
+ var result, then, exited;
+
+ try {
+ if (handler) {
+ if (!ok) {
+ if (state.rejection === UNHANDLED) onHandleUnhandled(state);
+ state.rejection = HANDLED;
+ }
+
+ if (handler === true) result = value;else {
+ if (domain) domain.enter();
+ result = handler(value); // can throw
+
+ if (domain) {
+ domain.exit();
+ exited = true;
+ }
+ }
+
+ if (result === reaction.promise) {
+ reject(TypeError$1('Promise-chain cycle'));
+ } else if (then = isThenable(result)) {
+ then.call(result, resolve, reject);
+ } else resolve(result);
+ } else reject(value);
+ } catch (error) {
+ if (domain && !exited) domain.exit();
+ reject(error);
+ }
+ }
+
+ state.reactions = [];
+ state.notified = false;
+ if (isReject && !state.rejection) onUnhandled(state);
+ });
+ };
+
+ var dispatchEvent = function dispatchEvent(name, promise, reason) {
+ var event, handler;
+
+ if (DISPATCH_EVENT) {
+ event = document$3.createEvent('Event');
+ event.promise = promise;
+ event.reason = reason;
+ event.initEvent(name, false, true);
+ global$1.dispatchEvent(event);
+ } else event = {
+ promise: promise,
+ reason: reason
+ };
+
+ if (!NATIVE_REJECTION_EVENT && (handler = global$1['on' + name])) handler(event);else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason);
+ };
+
+ var onUnhandled = function onUnhandled(state) {
+ task$1.call(global$1, function () {
+ var promise = state.facade;
+ var value = state.value;
+ var IS_UNHANDLED = isUnhandled(state);
+ var result;
+
+ if (IS_UNHANDLED) {
+ result = perform(function () {
+ if (engineIsNode) {
+ process$3.emit('unhandledRejection', value, promise);
+ } else dispatchEvent(UNHANDLED_REJECTION, promise, value);
+ }); // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should
+
+ state.rejection = engineIsNode || isUnhandled(state) ? UNHANDLED : HANDLED;
+ if (result.error) throw result.value;
+ }
+ });
+ };
+
+ var isUnhandled = function isUnhandled(state) {
+ return state.rejection !== HANDLED && !state.parent;
+ };
+
+ var onHandleUnhandled = function onHandleUnhandled(state) {
+ task$1.call(global$1, function () {
+ var promise = state.facade;
+
+ if (engineIsNode) {
+ process$3.emit('rejectionHandled', promise);
+ } else dispatchEvent(REJECTION_HANDLED, promise, state.value);
+ });
+ };
+
+ var bind = function bind(fn, state, unwrap) {
+ return function (value) {
+ fn(state, value, unwrap);
+ };
+ };
+
+ var internalReject = function internalReject(state, value, unwrap) {
+ if (state.done) return;
+ state.done = true;
+ if (unwrap) state = unwrap;
+ state.value = value;
+ state.state = REJECTED;
+ notify$1(state, true);
+ };
+
+ var internalResolve = function internalResolve(state, value, unwrap) {
+ if (state.done) return;
+ state.done = true;
+ if (unwrap) state = unwrap;
+
+ try {
+ if (state.facade === value) throw TypeError$1("Promise can't be resolved itself");
+ var then = isThenable(value);
+
+ if (then) {
+ microtask(function () {
+ var wrapper = {
+ done: false
+ };
+
+ try {
+ then.call(value, bind(internalResolve, wrapper, state), bind(internalReject, wrapper, state));
+ } catch (error) {
+ internalReject(wrapper, error, state);
+ }
+ });
+ } else {
+ state.value = value;
+ state.state = FULFILLED;
+ notify$1(state, false);
+ }
+ } catch (error) {
+ internalReject({
+ done: false
+ }, error, state);
+ }
+ }; // constructor polyfill
+
+
+ if (FORCED$1) {
+ // 25.4.3.1 Promise(executor)
+ PromiseConstructor = function Promise(executor) {
+ anInstance(this, PromiseConstructor, PROMISE);
+ aFunction$1(executor);
+ Internal.call(this);
+ var state = getInternalState$1(this);
+
+ try {
+ executor(bind(internalResolve, state), bind(internalReject, state));
+ } catch (error) {
+ internalReject(state, error);
+ }
+ }; // eslint-disable-next-line no-unused-vars
+
+
+ Internal = function Promise(executor) {
+ setInternalState$1(this, {
+ type: PROMISE,
+ done: false,
+ notified: false,
+ parent: false,
+ reactions: [],
+ rejection: false,
+ state: PENDING,
+ value: undefined
+ });
+ };
+
+ Internal.prototype = redefineAll(PromiseConstructor.prototype, {
+ // `Promise.prototype.then` method
+ // https://tc39.es/ecma262/#sec-promise.prototype.then
+ then: function then(onFulfilled, onRejected) {
+ var state = getInternalPromiseState(this);
+ var reaction = newPromiseCapability$1(speciesConstructor(this, PromiseConstructor));
+ reaction.ok = typeof onFulfilled == 'function' ? onFulfilled : true;
+ reaction.fail = typeof onRejected == 'function' && onRejected;
+ reaction.domain = engineIsNode ? process$3.domain : undefined;
+ state.parent = true;
+ state.reactions.push(reaction);
+ if (state.state != PENDING) notify$1(state, false);
+ return reaction.promise;
+ },
+ // `Promise.prototype.catch` method
+ // https://tc39.es/ecma262/#sec-promise.prototype.catch
+ 'catch': function _catch(onRejected) {
+ return this.then(undefined, onRejected);
+ }
+ });
+
+ OwnPromiseCapability = function OwnPromiseCapability() {
+ var promise = new Internal();
+ var state = getInternalState$1(promise);
+ this.promise = promise;
+ this.resolve = bind(internalResolve, state);
+ this.reject = bind(internalReject, state);
+ };
+
+ newPromiseCapability.f = newPromiseCapability$1 = function newPromiseCapability(C) {
+ return C === PromiseConstructor || C === PromiseWrapper ? new OwnPromiseCapability(C) : newGenericPromiseCapability(C);
+ };
+
+ if ( typeof nativePromiseConstructor == 'function') {
+ nativeThen = nativePromiseConstructor.prototype.then; // wrap native Promise#then for native async functions
+
+ redefine(nativePromiseConstructor.prototype, 'then', function then(onFulfilled, onRejected) {
+ var that = this;
+ return new PromiseConstructor(function (resolve, reject) {
+ nativeThen.call(that, resolve, reject);
+ }).then(onFulfilled, onRejected); // https://github.com/zloirock/core-js/issues/640
+ }, {
+ unsafe: true
+ }); // wrap fetch result
+
+ if (typeof $fetch == 'function') _export({
+ global: true,
+ enumerable: true,
+ forced: true
+ }, {
+ // eslint-disable-next-line no-unused-vars
+ fetch: function fetch(input
+ /* , init */
+ ) {
+ return promiseResolve(PromiseConstructor, $fetch.apply(global$1, arguments));
+ }
+ });
+ }
+ }
+
+ _export({
+ global: true,
+ wrap: true,
+ forced: FORCED$1
+ }, {
+ Promise: PromiseConstructor
+ });
+ setToStringTag(PromiseConstructor, PROMISE, false);
+ setSpecies(PROMISE);
+ PromiseWrapper = getBuiltIn(PROMISE); // statics
+
+ _export({
+ target: PROMISE,
+ stat: true,
+ forced: FORCED$1
+ }, {
+ // `Promise.reject` method
+ // https://tc39.es/ecma262/#sec-promise.reject
+ reject: function reject(r) {
+ var capability = newPromiseCapability$1(this);
+ capability.reject.call(undefined, r);
+ return capability.promise;
+ }
+ });
+ _export({
+ target: PROMISE,
+ stat: true,
+ forced: FORCED$1
+ }, {
+ // `Promise.resolve` method
+ // https://tc39.es/ecma262/#sec-promise.resolve
+ resolve: function resolve(x) {
+ return promiseResolve( this, x);
+ }
+ });
+ _export({
+ target: PROMISE,
+ stat: true,
+ forced: INCORRECT_ITERATION
+ }, {
+ // `Promise.all` method
+ // https://tc39.es/ecma262/#sec-promise.all
+ all: function all(iterable) {
+ var C = this;
+ var capability = newPromiseCapability$1(C);
+ var resolve = capability.resolve;
+ var reject = capability.reject;
+ var result = perform(function () {
+ var $promiseResolve = aFunction$1(C.resolve);
+ var values = [];
+ var counter = 0;
+ var remaining = 1;
+ iterate(iterable, function (promise) {
+ var index = counter++;
+ var alreadyCalled = false;
+ values.push(undefined);
+ remaining++;
+ $promiseResolve.call(C, promise).then(function (value) {
+ if (alreadyCalled) return;
+ alreadyCalled = true;
+ values[index] = value;
+ --remaining || resolve(values);
+ }, reject);
+ });
+ --remaining || resolve(values);
+ });
+ if (result.error) reject(result.value);
+ return capability.promise;
+ },
+ // `Promise.race` method
+ // https://tc39.es/ecma262/#sec-promise.race
+ race: function race(iterable) {
+ var C = this;
+ var capability = newPromiseCapability$1(C);
+ var reject = capability.reject;
+ var result = perform(function () {
+ var $promiseResolve = aFunction$1(C.resolve);
+ iterate(iterable, function (promise) {
+ $promiseResolve.call(C, promise).then(capability.resolve, reject);
+ });
+ });
+ if (result.error) reject(result.value);
+ return capability.promise;
+ }
+ });
+
+ // https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
+
+
+ var regexpFlags = function regexpFlags() {
+ var that = anObject(this);
+ var result = '';
+ if (that.global) result += 'g';
+ if (that.ignoreCase) result += 'i';
+ if (that.multiline) result += 'm';
+ if (that.dotAll) result += 's';
+ if (that.unicode) result += 'u';
+ if (that.sticky) result += 'y';
+ return result;
+ };
+
+ // so we use an intermediate function.
+
+
+ function RE(s, f) {
+ return RegExp(s, f);
+ }
+
+ var UNSUPPORTED_Y = fails(function () {
+ // babel-minify transpiles RegExp('a', 'y') -> /a/y and it causes SyntaxError
+ var re = RE('a', 'y');
+ re.lastIndex = 2;
+ return re.exec('abcd') != null;
+ });
+ var BROKEN_CARET = fails(function () {
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=773687
+ var re = RE('^r', 'gy');
+ re.lastIndex = 2;
+ return re.exec('str') != null;
+ });
+ var regexpStickyHelpers = {
+ UNSUPPORTED_Y: UNSUPPORTED_Y,
+ BROKEN_CARET: BROKEN_CARET
+ };
+
+ var nativeExec = RegExp.prototype.exec; // This always refers to the native implementation, because the
+ // String#replace polyfill uses ./fix-regexp-well-known-symbol-logic.js,
+ // which loads this file before patching the method.
+
+ var nativeReplace = String.prototype.replace;
+ var patchedExec = nativeExec;
+
+ var UPDATES_LAST_INDEX_WRONG = function () {
+ var re1 = /a/;
+ var re2 = /b*/g;
+ nativeExec.call(re1, 'a');
+ nativeExec.call(re2, 'a');
+ return re1.lastIndex !== 0 || re2.lastIndex !== 0;
+ }();
+
+ var UNSUPPORTED_Y$1 = regexpStickyHelpers.UNSUPPORTED_Y || regexpStickyHelpers.BROKEN_CARET; // nonparticipating capturing group, copied from es5-shim's String#split patch.
+
+ var NPCG_INCLUDED = /()??/.exec('')[1] !== undefined;
+ var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y$1;
+
+ if (PATCH) {
+ patchedExec = function exec(str) {
+ var re = this;
+ var lastIndex, reCopy, match, i;
+ var sticky = UNSUPPORTED_Y$1 && re.sticky;
+ var flags = regexpFlags.call(re);
+ var source = re.source;
+ var charsAdded = 0;
+ var strCopy = str;
+
+ if (sticky) {
+ flags = flags.replace('y', '');
+
+ if (flags.indexOf('g') === -1) {
+ flags += 'g';
+ }
+
+ strCopy = String(str).slice(re.lastIndex); // Support anchored sticky behavior.
+
+ if (re.lastIndex > 0 && (!re.multiline || re.multiline && str[re.lastIndex - 1] !== '\n')) {
+ source = '(?: ' + source + ')';
+ strCopy = ' ' + strCopy;
+ charsAdded++;
+ } // ^(? + rx + ) is needed, in combination with some str slicing, to
+ // simulate the 'y' flag.
+
+
+ reCopy = new RegExp('^(?:' + source + ')', flags);
+ }
+
+ if (NPCG_INCLUDED) {
+ reCopy = new RegExp('^' + source + '$(?!\\s)', flags);
+ }
+
+ if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex;
+ match = nativeExec.call(sticky ? reCopy : re, strCopy);
+
+ if (sticky) {
+ if (match) {
+ match.input = match.input.slice(charsAdded);
+ match[0] = match[0].slice(charsAdded);
+ match.index = re.lastIndex;
+ re.lastIndex += match[0].length;
+ } else re.lastIndex = 0;
+ } else if (UPDATES_LAST_INDEX_WRONG && match) {
+ re.lastIndex = re.global ? match.index + match[0].length : lastIndex;
+ }
+
+ if (NPCG_INCLUDED && match && match.length > 1) {
+ // Fix browsers whose `exec` methods don't consistently return `undefined`
+ // for NPCG, like IE8. NOTE: This doesn' work for /(.?)?/
+ nativeReplace.call(match[0], reCopy, function () {
+ for (i = 1; i < arguments.length - 2; i++) {
+ if (arguments[i] === undefined) match[i] = undefined;
+ }
+ });
+ }
+
+ return match;
+ };
+ }
+
+ var regexpExec = patchedExec;
+
+ // https://tc39.es/ecma262/#sec-regexp.prototype.exec
+
+
+ _export({
+ target: 'RegExp',
+ proto: true,
+ forced: /./.exec !== regexpExec
+ }, {
+ exec: regexpExec
+ });
+
+ var createMethod$3 = function createMethod(CONVERT_TO_STRING) {
+ return function ($this, pos) {
+ var S = String(requireObjectCoercible($this));
+ var position = toInteger(pos);
+ var size = S.length;
+ var first, second;
+ if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
+ first = S.charCodeAt(position);
+ return first < 0xD800 || first > 0xDBFF || position + 1 === size || (second = S.charCodeAt(position + 1)) < 0xDC00 || second > 0xDFFF ? CONVERT_TO_STRING ? S.charAt(position) : first : CONVERT_TO_STRING ? S.slice(position, position + 2) : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
+ };
+ };
+
+ var stringMultibyte = {
+ // `String.prototype.codePointAt` method
+ // https://tc39.es/ecma262/#sec-string.prototype.codepointat
+ codeAt: createMethod$3(false),
+ // `String.prototype.at` method
+ // https://github.com/mathiasbynens/String.prototype.at
+ charAt: createMethod$3(true)
+ };
+
+ var charAt = stringMultibyte.charAt;
+ var STRING_ITERATOR = 'String Iterator';
+ var setInternalState$2 = internalState.set;
+ var getInternalState$2 = internalState.getterFor(STRING_ITERATOR); // `String.prototype[@@iterator]` method
+ // https://tc39.es/ecma262/#sec-string.prototype-@@iterator
+
+ defineIterator(String, 'String', function (iterated) {
+ setInternalState$2(this, {
+ type: STRING_ITERATOR,
+ string: String(iterated),
+ index: 0
+ }); // `%StringIteratorPrototype%.next` method
+ // https://tc39.es/ecma262/#sec-%stringiteratorprototype%.next
+ }, function next() {
+ var state = getInternalState$2(this);
+ var string = state.string;
+ var index = state.index;
+ var point;
+ if (index >= string.length) return {
+ value: undefined,
+ done: true
+ };
+ point = charAt(string, index);
+ state.index += point.length;
+ return {
+ value: point,
+ done: false
+ };
+ });
+
+ var SPECIES$5 = wellKnownSymbol('species');
+ var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function () {
+ // #replace needs built-in support for named groups.
+ // #match works fine because it just return the exec results, even if it has
+ // a "grops" property.
+ var re = /./;
+
+ re.exec = function () {
+ var result = [];
+ result.groups = {
+ a: '7'
+ };
+ return result;
+ };
+
+ return ''.replace(re, '$') !== '7';
+ }); // IE <= 11 replaces $0 with the whole match, as if it was $&
+ // https://stackoverflow.com/questions/6024666/getting-ie-to-replace-a-regex-with-the-literal-string-0
+
+ var REPLACE_KEEPS_$0 = function () {
+ return 'a'.replace(/./, '$0') === '$0';
+ }();
+
+ var REPLACE = wellKnownSymbol('replace'); // Safari <= 13.0.3(?) substitutes nth capture where n>m with an empty string
+
+ var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = function () {
+ if (/./[REPLACE]) {
+ return /./[REPLACE]('a', '$0') === '';
+ }
+
+ return false;
+ }(); // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
+ // Weex JS has frozen built-in prototypes, so use try / catch wrapper
+
+
+ var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails(function () {
+ var re = /(?:)/;
+ var originalExec = re.exec;
+
+ re.exec = function () {
+ return originalExec.apply(this, arguments);
+ };
+
+ var result = 'ab'.split(re);
+ return result.length !== 2 || result[0] !== 'a' || result[1] !== 'b';
+ });
+
+ var fixRegexpWellKnownSymbolLogic = function fixRegexpWellKnownSymbolLogic(KEY, length, exec, sham) {
+ var SYMBOL = wellKnownSymbol(KEY);
+ var DELEGATES_TO_SYMBOL = !fails(function () {
+ // String methods call symbol-named RegEp methods
+ var O = {};
+
+ O[SYMBOL] = function () {
+ return 7;
+ };
+
+ return ''[KEY](O) != 7;
+ });
+ var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails(function () {
+ // Symbol-named RegExp methods call .exec
+ var execCalled = false;
+ var re = /a/;
+
+ if (KEY === 'split') {
+ // We can't use real regex here since it causes deoptimization
+ // and serious performance degradation in V8
+ // https://github.com/zloirock/core-js/issues/306
+ re = {}; // RegExp[@@split] doesn't call the regex's exec method, but first creates
+ // a new one. We need to return the patched regex when creating the new one.
+
+ re.constructor = {};
+
+ re.constructor[SPECIES$5] = function () {
+ return re;
+ };
+
+ re.flags = '';
+ re[SYMBOL] = /./[SYMBOL];
+ }
+
+ re.exec = function () {
+ execCalled = true;
+ return null;
+ };
+
+ re[SYMBOL]('');
+ return !execCalled;
+ });
+
+ if (!DELEGATES_TO_SYMBOL || !DELEGATES_TO_EXEC || KEY === 'replace' && !(REPLACE_SUPPORTS_NAMED_GROUPS && REPLACE_KEEPS_$0 && !REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE) || KEY === 'split' && !SPLIT_WORKS_WITH_OVERWRITTEN_EXEC) {
+ var nativeRegExpMethod = /./[SYMBOL];
+ var methods = exec(SYMBOL, ''[KEY], function (nativeMethod, regexp, str, arg2, forceStringMethod) {
+ if (regexp.exec === regexpExec) {
+ if (DELEGATES_TO_SYMBOL && !forceStringMethod) {
+ // The native String method already delegates to @@method (this
+ // polyfilled function), leasing to infinite recursion.
+ // We avoid it by directly calling the native @@method method.
+ return {
+ done: true,
+ value: nativeRegExpMethod.call(regexp, str, arg2)
+ };
+ }
+
+ return {
+ done: true,
+ value: nativeMethod.call(str, regexp, arg2)
+ };
+ }
+
+ return {
+ done: false
+ };
+ }, {
+ REPLACE_KEEPS_$0: REPLACE_KEEPS_$0,
+ REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE: REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE
+ });
+ var stringMethod = methods[0];
+ var regexMethod = methods[1];
+ redefine(String.prototype, KEY, stringMethod);
+ redefine(RegExp.prototype, SYMBOL, length == 2 // 21.2.5.8 RegExp.prototype[@@replace](string, replaceValue)
+ // 21.2.5.11 RegExp.prototype[@@split](string, limit)
+ ? function (string, arg) {
+ return regexMethod.call(string, this, arg);
+ } // 21.2.5.6 RegExp.prototype[@@match](string)
+ // 21.2.5.9 RegExp.prototype[@@search](string)
+ : function (string) {
+ return regexMethod.call(string, this);
+ });
+ }
+
+ if (sham) createNonEnumerableProperty(RegExp.prototype[SYMBOL], 'sham', true);
+ };
+
+ var charAt$1 = stringMultibyte.charAt; // `AdvanceStringIndex` abstract operation
+ // https://tc39.es/ecma262/#sec-advancestringindex
+
+ var advanceStringIndex = function advanceStringIndex(S, index, unicode) {
+ return index + (unicode ? charAt$1(S, index).length : 1);
+ };
+
+ var floor$1 = Math.floor;
+ var replace = ''.replace;
+ var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d\d?|<[^>]*>)/g;
+ var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d\d?)/g; // https://tc39.es/ecma262/#sec-getsubstitution
+
+ var getSubstitution = function getSubstitution(matched, str, position, captures, namedCaptures, replacement) {
+ var tailPos = position + matched.length;
+ var m = captures.length;
+ var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED;
+
+ if (namedCaptures !== undefined) {
+ namedCaptures = toObject(namedCaptures);
+ symbols = SUBSTITUTION_SYMBOLS;
+ }
+
+ return replace.call(replacement, symbols, function (match, ch) {
+ var capture;
+
+ switch (ch.charAt(0)) {
+ case '$':
+ return '$';
+
+ case '&':
+ return matched;
+
+ case '`':
+ return str.slice(0, position);
+
+ case "'":
+ return str.slice(tailPos);
+
+ case '<':
+ capture = namedCaptures[ch.slice(1, -1)];
+ break;
+
+ default:
+ // \d\d?
+ var n = +ch;
+ if (n === 0) return match;
+
+ if (n > m) {
+ var f = floor$1(n / 10);
+ if (f === 0) return match;
+ if (f <= m) return captures[f - 1] === undefined ? ch.charAt(1) : captures[f - 1] + ch.charAt(1);
+ return match;
+ }
+
+ capture = captures[n - 1];
+ }
+
+ return capture === undefined ? '' : capture;
+ });
+ };
+
+ // https://tc39.es/ecma262/#sec-regexpexec
+
+ var regexpExecAbstract = function regexpExecAbstract(R, S) {
+ var exec = R.exec;
+
+ if (typeof exec === 'function') {
+ var result = exec.call(R, S);
+
+ if (_typeof(result) !== 'object') {
+ throw TypeError('RegExp exec method returned something other than an Object or null');
+ }
+
+ return result;
+ }
+
+ if (classofRaw(R) !== 'RegExp') {
+ throw TypeError('RegExp#exec called on incompatible receiver');
+ }
+
+ return regexpExec.call(R, S);
+ };
+
+ var max$2 = Math.max;
+ var min$3 = Math.min;
+
+ var maybeToString = function maybeToString(it) {
+ return it === undefined ? it : String(it);
+ }; // @@replace logic
+
+
+ fixRegexpWellKnownSymbolLogic('replace', 2, function (REPLACE, nativeReplace, maybeCallNative, reason) {
+ var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = reason.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE;
+ var REPLACE_KEEPS_$0 = reason.REPLACE_KEEPS_$0;
+ var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? '$' : '$0';
+ return [// `String.prototype.replace` method
+ // https://tc39.es/ecma262/#sec-string.prototype.replace
+ function replace(searchValue, replaceValue) {
+ var O = requireObjectCoercible(this);
+ var replacer = searchValue == undefined ? undefined : searchValue[REPLACE];
+ return replacer !== undefined ? replacer.call(searchValue, O, replaceValue) : nativeReplace.call(String(O), searchValue, replaceValue);
+ }, // `RegExp.prototype[@@replace]` method
+ // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace
+ function (regexp, replaceValue) {
+ if (!REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE && REPLACE_KEEPS_$0 || typeof replaceValue === 'string' && replaceValue.indexOf(UNSAFE_SUBSTITUTE) === -1) {
+ var res = maybeCallNative(nativeReplace, regexp, this, replaceValue);
+ if (res.done) return res.value;
+ }
+
+ var rx = anObject(regexp);
+ var S = String(this);
+ var functionalReplace = typeof replaceValue === 'function';
+ if (!functionalReplace) replaceValue = String(replaceValue);
+ var global = rx.global;
+
+ if (global) {
+ var fullUnicode = rx.unicode;
+ rx.lastIndex = 0;
+ }
+
+ var results = [];
+
+ while (true) {
+ var result = regexpExecAbstract(rx, S);
+ if (result === null) break;
+ results.push(result);
+ if (!global) break;
+ var matchStr = String(result[0]);
+ if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength(rx.lastIndex), fullUnicode);
+ }
+
+ var accumulatedResult = '';
+ var nextSourcePosition = 0;
+
+ for (var i = 0; i < results.length; i++) {
+ result = results[i];
+ var matched = String(result[0]);
+ var position = max$2(min$3(toInteger(result.index), S.length), 0);
+ var captures = []; // NOTE: This is equivalent to
+ // captures = result.slice(1).map(maybeToString)
+ // but for some reason `nativeSlice.call(result, 1, result.length)` (called in
+ // the slice polyfill when slicing native arrays) "doesn't work" in safari 9 and
+ // causes a crash (https://pastebin.com/N21QzeQA) when trying to debug it.
+
+ for (var j = 1; j < result.length; j++) {
+ captures.push(maybeToString(result[j]));
+ }
+
+ var namedCaptures = result.groups;
+
+ if (functionalReplace) {
+ var replacerArgs = [matched].concat(captures, position, S);
+ if (namedCaptures !== undefined) replacerArgs.push(namedCaptures);
+ var replacement = String(replaceValue.apply(undefined, replacerArgs));
+ } else {
+ replacement = getSubstitution(matched, S, position, captures, namedCaptures, replaceValue);
+ }
+
+ if (position >= nextSourcePosition) {
+ accumulatedResult += S.slice(nextSourcePosition, position) + replacement;
+ nextSourcePosition = position + matched.length;
+ }
+ }
+
+ return accumulatedResult + S.slice(nextSourcePosition);
+ }];
+ });
+
+ // iterable DOM collections
+ // flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
+ var domIterables = {
+ CSSRuleList: 0,
+ CSSStyleDeclaration: 0,
+ CSSValueList: 0,
+ ClientRectList: 0,
+ DOMRectList: 0,
+ DOMStringList: 0,
+ DOMTokenList: 1,
+ DataTransferItemList: 0,
+ FileList: 0,
+ HTMLAllCollection: 0,
+ HTMLCollection: 0,
+ HTMLFormElement: 0,
+ HTMLSelectElement: 0,
+ MediaList: 0,
+ MimeTypeArray: 0,
+ NamedNodeMap: 0,
+ NodeList: 1,
+ PaintRequestList: 0,
+ Plugin: 0,
+ PluginArray: 0,
+ SVGLengthList: 0,
+ SVGNumberList: 0,
+ SVGPathSegList: 0,
+ SVGPointList: 0,
+ SVGStringList: 0,
+ SVGTransformList: 0,
+ SourceBufferList: 0,
+ StyleSheetList: 0,
+ TextTrackCueList: 0,
+ TextTrackList: 0,
+ TouchList: 0
+ };
+
+ var ITERATOR$5 = wellKnownSymbol('iterator');
+ var TO_STRING_TAG$3 = wellKnownSymbol('toStringTag');
+ var ArrayValues = es_array_iterator.values;
+
+ for (var COLLECTION_NAME in domIterables) {
+ var Collection = global$1[COLLECTION_NAME];
+ var CollectionPrototype = Collection && Collection.prototype;
+
+ if (CollectionPrototype) {
+ // some Chrome versions have non-configurable methods on DOMTokenList
+ if (CollectionPrototype[ITERATOR$5] !== ArrayValues) try {
+ createNonEnumerableProperty(CollectionPrototype, ITERATOR$5, ArrayValues);
+ } catch (error) {
+ CollectionPrototype[ITERATOR$5] = ArrayValues;
+ }
+
+ if (!CollectionPrototype[TO_STRING_TAG$3]) {
+ createNonEnumerableProperty(CollectionPrototype, TO_STRING_TAG$3, COLLECTION_NAME);
+ }
+
+ if (domIterables[COLLECTION_NAME]) for (var METHOD_NAME in es_array_iterator) {
+ // some Chrome versions have non-configurable methods on DOMTokenList
+ if (CollectionPrototype[METHOD_NAME] !== es_array_iterator[METHOD_NAME]) try {
+ createNonEnumerableProperty(CollectionPrototype, METHOD_NAME, es_array_iterator[METHOD_NAME]);
+ } catch (error) {
+ CollectionPrototype[METHOD_NAME] = es_array_iterator[METHOD_NAME];
+ }
+ }
+ }
+ }
+
+ var runtime_1 = createCommonjsModule(function (module) {
+ var runtime = function (exports) {
+
+ var Op = Object.prototype;
+ var hasOwn = Op.hasOwnProperty;
+ var undefined$1; // More compressible than void 0.
+
+ var $Symbol = typeof Symbol === "function" ? Symbol : {};
+ var iteratorSymbol = $Symbol.iterator || "@@iterator";
+ var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
+ var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
+
+ function define(obj, key, value) {
+ Object.defineProperty(obj, key, {
+ value: value,
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
+ return obj[key];
+ }
+
+ try {
+ // IE 8 has a broken Object.defineProperty that only works on DOM objects.
+ define({}, "");
+ } catch (err) {
+ define = function define(obj, key, value) {
+ return obj[key] = value;
+ };
+ }
+
+ function wrap(innerFn, outerFn, self, tryLocsList) {
+ // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
+ var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
+ var generator = Object.create(protoGenerator.prototype);
+ var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next,
+ // .throw, and .return methods.
+
+ generator._invoke = makeInvokeMethod(innerFn, self, context);
+ return generator;
+ }
+
+ exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion
+ // record like context.tryEntries[i].completion. This interface could
+ // have been (and was previously) designed to take a closure to be
+ // invoked without arguments, but in all the cases we care about we
+ // already have an existing method we want to call, so there's no need
+ // to create a new function object. We can even get away with assuming
+ // the method takes exactly one argument, since that happens to be true
+ // in every case, so we don't have to touch the arguments object. The
+ // only additional allocation required is the completion record, which
+ // has a stable shape and so hopefully should be cheap to allocate.
+
+ function tryCatch(fn, obj, arg) {
+ try {
+ return {
+ type: "normal",
+ arg: fn.call(obj, arg)
+ };
+ } catch (err) {
+ return {
+ type: "throw",
+ arg: err
+ };
+ }
+ }
+
+ var GenStateSuspendedStart = "suspendedStart";
+ var GenStateSuspendedYield = "suspendedYield";
+ var GenStateExecuting = "executing";
+ var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as
+ // breaking out of the dispatch switch statement.
+
+ var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and
+ // .constructor.prototype properties for functions that return Generator
+ // objects. For full spec compliance, you may wish to configure your
+ // minifier not to mangle the names of these two functions.
+
+ function Generator() {}
+
+ function GeneratorFunction() {}
+
+ function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that
+ // don't natively support it.
+
+
+ var IteratorPrototype = {};
+
+ IteratorPrototype[iteratorSymbol] = function () {
+ return this;
+ };
+
+ var getProto = Object.getPrototypeOf;
+ var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
+
+ if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
+ // This environment has a native %IteratorPrototype%; use it instead
+ // of the polyfill.
+ IteratorPrototype = NativeIteratorPrototype;
+ }
+
+ var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
+ GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
+ GeneratorFunctionPrototype.constructor = GeneratorFunction;
+ GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"); // Helper for defining the .next, .throw, and .return methods of the
+ // Iterator interface in terms of a single ._invoke method.
+
+ function defineIteratorMethods(prototype) {
+ ["next", "throw", "return"].forEach(function (method) {
+ define(prototype, method, function (arg) {
+ return this._invoke(method, arg);
+ });
+ });
+ }
+
+ exports.isGeneratorFunction = function (genFun) {
+ var ctor = typeof genFun === "function" && genFun.constructor;
+ return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can
+ // do is to check its .name property.
+ (ctor.displayName || ctor.name) === "GeneratorFunction" : false;
+ };
+
+ exports.mark = function (genFun) {
+ if (Object.setPrototypeOf) {
+ Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
+ } else {
+ genFun.__proto__ = GeneratorFunctionPrototype;
+ define(genFun, toStringTagSymbol, "GeneratorFunction");
+ }
+
+ genFun.prototype = Object.create(Gp);
+ return genFun;
+ }; // Within the body of any async function, `await x` is transformed to
+ // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
+ // `hasOwn.call(value, "__await")` to determine if the yielded value is
+ // meant to be awaited.
+
+
+ exports.awrap = function (arg) {
+ return {
+ __await: arg
+ };
+ };
+
+ function AsyncIterator(generator, PromiseImpl) {
+ function invoke(method, arg, resolve, reject) {
+ var record = tryCatch(generator[method], generator, arg);
+
+ if (record.type === "throw") {
+ reject(record.arg);
+ } else {
+ var result = record.arg;
+ var value = result.value;
+
+ if (value && _typeof(value) === "object" && hasOwn.call(value, "__await")) {
+ return PromiseImpl.resolve(value.__await).then(function (value) {
+ invoke("next", value, resolve, reject);
+ }, function (err) {
+ invoke("throw", err, resolve, reject);
+ });
+ }
+
+ return PromiseImpl.resolve(value).then(function (unwrapped) {
+ // When a yielded Promise is resolved, its final value becomes
+ // the .value of the Promise<{value,done}> result for the
+ // current iteration.
+ result.value = unwrapped;
+ resolve(result);
+ }, function (error) {
+ // If a rejected Promise was yielded, throw the rejection back
+ // into the async generator function so it can be handled there.
+ return invoke("throw", error, resolve, reject);
+ });
+ }
+ }
+
+ var previousPromise;
+
+ function enqueue(method, arg) {
+ function callInvokeWithMethodAndArg() {
+ return new PromiseImpl(function (resolve, reject) {
+ invoke(method, arg, resolve, reject);
+ });
+ }
+
+ return previousPromise = // If enqueue has been called before, then we want to wait until
+ // all previous Promises have been resolved before calling invoke,
+ // so that results are always delivered in the correct order. If
+ // enqueue has not been called before, then it is important to
+ // call invoke immediately, without waiting on a callback to fire,
+ // so that the async generator function has the opportunity to do
+ // any necessary setup in a predictable way. This predictability
+ // is why the Promise constructor synchronously invokes its
+ // executor callback, and why async functions synchronously
+ // execute code before the first await. Since we implement simple
+ // async functions in terms of async generators, it is especially
+ // important to get this right, even though it requires care.
+ previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later
+ // invocations of the iterator.
+ callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
+ } // Define the unified helper method that is used to implement .next,
+ // .throw, and .return (see defineIteratorMethods).
+
+
+ this._invoke = enqueue;
+ }
+
+ defineIteratorMethods(AsyncIterator.prototype);
+
+ AsyncIterator.prototype[asyncIteratorSymbol] = function () {
+ return this;
+ };
+
+ exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of
+ // AsyncIterator objects; they just return a Promise for the value of
+ // the final result produced by the iterator.
+
+ exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
+ if (PromiseImpl === void 0) PromiseImpl = Promise;
+ var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
+ return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator.
+ : iter.next().then(function (result) {
+ return result.done ? result.value : iter.next();
+ });
+ };
+
+ function makeInvokeMethod(innerFn, self, context) {
+ var state = GenStateSuspendedStart;
+ return function invoke(method, arg) {
+ if (state === GenStateExecuting) {
+ throw new Error("Generator is already running");
+ }
+
+ if (state === GenStateCompleted) {
+ if (method === "throw") {
+ throw arg;
+ } // Be forgiving, per 25.3.3.3.3 of the spec:
+ // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
+
+
+ return doneResult();
+ }
+
+ context.method = method;
+ context.arg = arg;
+
+ while (true) {
+ var delegate = context.delegate;
+
+ if (delegate) {
+ var delegateResult = maybeInvokeDelegate(delegate, context);
+
+ if (delegateResult) {
+ if (delegateResult === ContinueSentinel) continue;
+ return delegateResult;
+ }
+ }
+
+ if (context.method === "next") {
+ // Setting context._sent for legacy support of Babel's
+ // function.sent implementation.
+ context.sent = context._sent = context.arg;
+ } else if (context.method === "throw") {
+ if (state === GenStateSuspendedStart) {
+ state = GenStateCompleted;
+ throw context.arg;
+ }
+
+ context.dispatchException(context.arg);
+ } else if (context.method === "return") {
+ context.abrupt("return", context.arg);
+ }
+
+ state = GenStateExecuting;
+ var record = tryCatch(innerFn, self, context);
+
+ if (record.type === "normal") {
+ // If an exception is thrown from innerFn, we leave state ===
+ // GenStateExecuting and loop back for another invocation.
+ state = context.done ? GenStateCompleted : GenStateSuspendedYield;
+
+ if (record.arg === ContinueSentinel) {
+ continue;
+ }
+
+ return {
+ value: record.arg,
+ done: context.done
+ };
+ } else if (record.type === "throw") {
+ state = GenStateCompleted; // Dispatch the exception by looping back around to the
+ // context.dispatchException(context.arg) call above.
+
+ context.method = "throw";
+ context.arg = record.arg;
+ }
+ }
+ };
+ } // Call delegate.iterator[context.method](context.arg) and handle the
+ // result, either by returning a { value, done } result from the
+ // delegate iterator, or by modifying context.method and context.arg,
+ // setting context.delegate to null, and returning the ContinueSentinel.
+
+
+ function maybeInvokeDelegate(delegate, context) {
+ var method = delegate.iterator[context.method];
+
+ if (method === undefined$1) {
+ // A .throw or .return when the delegate iterator has no .throw
+ // method always terminates the yield* loop.
+ context.delegate = null;
+
+ if (context.method === "throw") {
+ // Note: ["return"] must be used for ES3 parsing compatibility.
+ if (delegate.iterator["return"]) {
+ // If the delegate iterator has a return method, give it a
+ // chance to clean up.
+ context.method = "return";
+ context.arg = undefined$1;
+ maybeInvokeDelegate(delegate, context);
+
+ if (context.method === "throw") {
+ // If maybeInvokeDelegate(context) changed context.method from
+ // "return" to "throw", let that override the TypeError below.
+ return ContinueSentinel;
+ }
+ }
+
+ context.method = "throw";
+ context.arg = new TypeError("The iterator does not provide a 'throw' method");
+ }
+
+ return ContinueSentinel;
+ }
+
+ var record = tryCatch(method, delegate.iterator, context.arg);
+
+ if (record.type === "throw") {
+ context.method = "throw";
+ context.arg = record.arg;
+ context.delegate = null;
+ return ContinueSentinel;
+ }
+
+ var info = record.arg;
+
+ if (!info) {
+ context.method = "throw";
+ context.arg = new TypeError("iterator result is not an object");
+ context.delegate = null;
+ return ContinueSentinel;
+ }
+
+ if (info.done) {
+ // Assign the result of the finished delegate to the temporary
+ // variable specified by delegate.resultName (see delegateYield).
+ context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield).
+
+ context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the
+ // exception, let the outer generator proceed normally. If
+ // context.method was "next", forget context.arg since it has been
+ // "consumed" by the delegate iterator. If context.method was
+ // "return", allow the original .return call to continue in the
+ // outer generator.
+
+ if (context.method !== "return") {
+ context.method = "next";
+ context.arg = undefined$1;
+ }
+ } else {
+ // Re-yield the result returned by the delegate method.
+ return info;
+ } // The delegate iterator is finished, so forget it and continue with
+ // the outer generator.
+
+
+ context.delegate = null;
+ return ContinueSentinel;
+ } // Define Generator.prototype.{next,throw,return} in terms of the
+ // unified ._invoke helper method.
+
+
+ defineIteratorMethods(Gp);
+ define(Gp, toStringTagSymbol, "Generator"); // A Generator should always return itself as the iterator object when the
+ // @@iterator function is called on it. Some browsers' implementations of the
+ // iterator prototype chain incorrectly implement this, causing the Generator
+ // object to not be returned from this call. This ensures that doesn't happen.
+ // See https://github.com/facebook/regenerator/issues/274 for more details.
+
+ Gp[iteratorSymbol] = function () {
+ return this;
+ };
+
+ Gp.toString = function () {
+ return "[object Generator]";
+ };
+
+ function pushTryEntry(locs) {
+ var entry = {
+ tryLoc: locs[0]
+ };
+
+ if (1 in locs) {
+ entry.catchLoc = locs[1];
+ }
+
+ if (2 in locs) {
+ entry.finallyLoc = locs[2];
+ entry.afterLoc = locs[3];
+ }
+
+ this.tryEntries.push(entry);
+ }
+
+ function resetTryEntry(entry) {
+ var record = entry.completion || {};
+ record.type = "normal";
+ delete record.arg;
+ entry.completion = record;
+ }
+
+ function Context(tryLocsList) {
+ // The root entry object (effectively a try statement without a catch
+ // or a finally block) gives us a place to store values thrown from
+ // locations where there is no enclosing try statement.
+ this.tryEntries = [{
+ tryLoc: "root"
+ }];
+ tryLocsList.forEach(pushTryEntry, this);
+ this.reset(true);
+ }
+
+ exports.keys = function (object) {
+ var keys = [];
+
+ for (var key in object) {
+ keys.push(key);
+ }
+
+ keys.reverse(); // Rather than returning an object with a next method, we keep
+ // things simple and return the next function itself.
+
+ return function next() {
+ while (keys.length) {
+ var key = keys.pop();
+
+ if (key in object) {
+ next.value = key;
+ next.done = false;
+ return next;
+ }
+ } // To avoid creating an additional object, we just hang the .value
+ // and .done properties off the next function object itself. This
+ // also ensures that the minifier will not anonymize the function.
+
+
+ next.done = true;
+ return next;
+ };
+ };
+
+ function values(iterable) {
+ if (iterable) {
+ var iteratorMethod = iterable[iteratorSymbol];
+
+ if (iteratorMethod) {
+ return iteratorMethod.call(iterable);
+ }
+
+ if (typeof iterable.next === "function") {
+ return iterable;
+ }
+
+ if (!isNaN(iterable.length)) {
+ var i = -1,
+ next = function next() {
+ while (++i < iterable.length) {
+ if (hasOwn.call(iterable, i)) {
+ next.value = iterable[i];
+ next.done = false;
+ return next;
+ }
+ }
+
+ next.value = undefined$1;
+ next.done = true;
+ return next;
+ };
+
+ return next.next = next;
+ }
+ } // Return an iterator with no values.
+
+
+ return {
+ next: doneResult
+ };
+ }
+
+ exports.values = values;
+
+ function doneResult() {
+ return {
+ value: undefined$1,
+ done: true
+ };
+ }
+
+ Context.prototype = {
+ constructor: Context,
+ reset: function reset(skipTempReset) {
+ this.prev = 0;
+ this.next = 0; // Resetting context._sent for legacy support of Babel's
+ // function.sent implementation.
+
+ this.sent = this._sent = undefined$1;
+ this.done = false;
+ this.delegate = null;
+ this.method = "next";
+ this.arg = undefined$1;
+ this.tryEntries.forEach(resetTryEntry);
+
+ if (!skipTempReset) {
+ for (var name in this) {
+ // Not sure about the optimal order of these conditions:
+ if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {
+ this[name] = undefined$1;
+ }
+ }
+ }
+ },
+ stop: function stop() {
+ this.done = true;
+ var rootEntry = this.tryEntries[0];
+ var rootRecord = rootEntry.completion;
+
+ if (rootRecord.type === "throw") {
+ throw rootRecord.arg;
+ }
+
+ return this.rval;
+ },
+ dispatchException: function dispatchException(exception) {
+ if (this.done) {
+ throw exception;
+ }
+
+ var context = this;
+
+ function handle(loc, caught) {
+ record.type = "throw";
+ record.arg = exception;
+ context.next = loc;
+
+ if (caught) {
+ // If the dispatched exception was caught by a catch block,
+ // then let that catch block handle the exception normally.
+ context.method = "next";
+ context.arg = undefined$1;
+ }
+
+ return !!caught;
+ }
+
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+ var record = entry.completion;
+
+ if (entry.tryLoc === "root") {
+ // Exception thrown outside of any try block that could handle
+ // it, so set the completion value of the entire function to
+ // throw the exception.
+ return handle("end");
+ }
+
+ if (entry.tryLoc <= this.prev) {
+ var hasCatch = hasOwn.call(entry, "catchLoc");
+ var hasFinally = hasOwn.call(entry, "finallyLoc");
+
+ if (hasCatch && hasFinally) {
+ if (this.prev < entry.catchLoc) {
+ return handle(entry.catchLoc, true);
+ } else if (this.prev < entry.finallyLoc) {
+ return handle(entry.finallyLoc);
+ }
+ } else if (hasCatch) {
+ if (this.prev < entry.catchLoc) {
+ return handle(entry.catchLoc, true);
+ }
+ } else if (hasFinally) {
+ if (this.prev < entry.finallyLoc) {
+ return handle(entry.finallyLoc);
+ }
+ } else {
+ throw new Error("try statement without catch or finally");
+ }
+ }
+ }
+ },
+ abrupt: function abrupt(type, arg) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+
+ if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
+ var finallyEntry = entry;
+ break;
+ }
+ }
+
+ if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
+ // Ignore the finally entry if control is not jumping to a
+ // location outside the try/catch block.
+ finallyEntry = null;
+ }
+
+ var record = finallyEntry ? finallyEntry.completion : {};
+ record.type = type;
+ record.arg = arg;
+
+ if (finallyEntry) {
+ this.method = "next";
+ this.next = finallyEntry.finallyLoc;
+ return ContinueSentinel;
+ }
+
+ return this.complete(record);
+ },
+ complete: function complete(record, afterLoc) {
+ if (record.type === "throw") {
+ throw record.arg;
+ }
+
+ if (record.type === "break" || record.type === "continue") {
+ this.next = record.arg;
+ } else if (record.type === "return") {
+ this.rval = this.arg = record.arg;
+ this.method = "return";
+ this.next = "end";
+ } else if (record.type === "normal" && afterLoc) {
+ this.next = afterLoc;
+ }
+
+ return ContinueSentinel;
+ },
+ finish: function finish(finallyLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+
+ if (entry.finallyLoc === finallyLoc) {
+ this.complete(entry.completion, entry.afterLoc);
+ resetTryEntry(entry);
+ return ContinueSentinel;
+ }
+ }
+ },
+ "catch": function _catch(tryLoc) {
+ for (var i = this.tryEntries.length - 1; i >= 0; --i) {
+ var entry = this.tryEntries[i];
+
+ if (entry.tryLoc === tryLoc) {
+ var record = entry.completion;
+
+ if (record.type === "throw") {
+ var thrown = record.arg;
+ resetTryEntry(entry);
+ }
+
+ return thrown;
+ }
+ } // The context.catch method must only be called with a location
+ // argument that corresponds to a known catch block.
+
+
+ throw new Error("illegal catch attempt");
+ },
+ delegateYield: function delegateYield(iterable, resultName, nextLoc) {
+ this.delegate = {
+ iterator: values(iterable),
+ resultName: resultName,
+ nextLoc: nextLoc
+ };
+
+ if (this.method === "next") {
+ // Deliberately forget the last sent value so that we don't
+ // accidentally pass it on to the delegate.
+ this.arg = undefined$1;
+ }
+
+ return ContinueSentinel;
+ }
+ }; // Regardless of whether this script is executing as a CommonJS module
+ // or not, return the runtime object so that we can declare the variable
+ // regeneratorRuntime in the outer scope, which allows this module to be
+ // injected easily by `bin/regenerator --include-runtime script.js`.
+
+ return exports;
+ }( // If this script is executing as a CommonJS module, use module.exports
+ // as the regeneratorRuntime namespace. Otherwise create a new empty
+ // object. Either way, the resulting object will be used to initialize
+ // the regeneratorRuntime variable at the top of this file.
+ module.exports );
+
+ try {
+ regeneratorRuntime = runtime;
+ } catch (accidentalStrictMode) {
+ // This module should not be running in strict mode, so the above
+ // assignment should always work unless something is misconfigured. Just
+ // in case runtime.js accidentally runs in strict mode, we can escape
+ // strict mode using a global Function call. This could conceivably fail
+ // if a Content Security Policy forbids using Function, but in that case
+ // the proper solution is to fix the accidental strict mode problem. If
+ // you've misconfigured your bundler to force strict mode and applied a
+ // CSP to forbid Function, and you're not willing to fix either of those
+ // problems, please detail your unique predicament in a GitHub issue.
+ Function("r", "regeneratorRuntime = r")(runtime);
+ }
+ });
+
+ var $includes = arrayIncludes.includes;
+ var USES_TO_LENGTH$2 = arrayMethodUsesToLength('indexOf', {
+ ACCESSORS: true,
+ 1: 0
+ }); // `Array.prototype.includes` method
+ // https://tc39.es/ecma262/#sec-array.prototype.includes
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: !USES_TO_LENGTH$2
+ }, {
+ includes: function includes(el
+ /* , fromIndex = 0 */
+ ) {
+ return $includes(this, el, arguments.length > 1 ? arguments[1] : undefined);
+ }
+ }); // https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
+
+ addToUnscopables('includes');
+
+ var arrayMethodIsStrict = function arrayMethodIsStrict(METHOD_NAME, argument) {
+ var method = [][METHOD_NAME];
+ return !!method && fails(function () {
+ // eslint-disable-next-line no-useless-call,no-throw-literal
+ method.call(null, argument || function () {
+ throw 1;
+ }, 1);
+ });
+ };
+
+ var $indexOf = arrayIncludes.indexOf;
+ var nativeIndexOf = [].indexOf;
+ var NEGATIVE_ZERO = !!nativeIndexOf && 1 / [1].indexOf(1, -0) < 0;
+ var STRICT_METHOD = arrayMethodIsStrict('indexOf');
+ var USES_TO_LENGTH$3 = arrayMethodUsesToLength('indexOf', {
+ ACCESSORS: true,
+ 1: 0
+ }); // `Array.prototype.indexOf` method
+ // https://tc39.es/ecma262/#sec-array.prototype.indexof
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: NEGATIVE_ZERO || !STRICT_METHOD || !USES_TO_LENGTH$3
+ }, {
+ indexOf: function indexOf(searchElement
+ /* , fromIndex = 0 */
+ ) {
+ return NEGATIVE_ZERO // convert -0 to +0
+ ? nativeIndexOf.apply(this, arguments) || 0 : $indexOf(this, searchElement, arguments.length > 1 ? arguments[1] : undefined);
+ }
+ });
+
+ var $map = arrayIteration.map;
+ var HAS_SPECIES_SUPPORT$2 = arrayMethodHasSpeciesSupport('map'); // FF49- issue
+
+ var USES_TO_LENGTH$4 = arrayMethodUsesToLength('map'); // `Array.prototype.map` method
+ // https://tc39.es/ecma262/#sec-array.prototype.map
+ // with adding support of @@species
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: !HAS_SPECIES_SUPPORT$2 || !USES_TO_LENGTH$4
+ }, {
+ map: function map(callbackfn
+ /* , thisArg */
+ ) {
+ return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
+ }
+ });
+
+ var propertyIsEnumerable = objectPropertyIsEnumerable.f; // `Object.{ entries, values }` methods implementation
+
+ var createMethod$4 = function createMethod(TO_ENTRIES) {
+ return function (it) {
+ var O = toIndexedObject(it);
+ var keys = objectKeys(O);
+ var length = keys.length;
+ var i = 0;
+ var result = [];
+ var key;
+
+ while (length > i) {
+ key = keys[i++];
+
+ if (!descriptors || propertyIsEnumerable.call(O, key)) {
+ result.push(TO_ENTRIES ? [key, O[key]] : O[key]);
+ }
+ }
+
+ return result;
+ };
+ };
+
+ var objectToArray = {
+ // `Object.entries` method
+ // https://tc39.es/ecma262/#sec-object.entries
+ entries: createMethod$4(true),
+ // `Object.values` method
+ // https://tc39.es/ecma262/#sec-object.values
+ values: createMethod$4(false)
+ };
+
+ var $entries = objectToArray.entries; // `Object.entries` method
+ // https://tc39.es/ecma262/#sec-object.entries
+
+ _export({
+ target: 'Object',
+ stat: true
+ }, {
+ entries: function entries(O) {
+ return $entries(O);
+ }
+ });
+
+ var FAILS_ON_PRIMITIVES = fails(function () {
+ objectKeys(1);
+ }); // `Object.keys` method
+ // https://tc39.es/ecma262/#sec-object.keys
+
+ _export({
+ target: 'Object',
+ stat: true,
+ forced: FAILS_ON_PRIMITIVES
+ }, {
+ keys: function keys(it) {
+ return objectKeys(toObject(it));
+ }
+ });
+
+ var MATCH = wellKnownSymbol('match'); // `IsRegExp` abstract operation
+ // https://tc39.es/ecma262/#sec-isregexp
+
+ var isRegexp = function isRegexp(it) {
+ var isRegExp;
+ return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classofRaw(it) == 'RegExp');
+ };
+
+ var notARegexp = function notARegexp(it) {
+ if (isRegexp(it)) {
+ throw TypeError("The method doesn't accept regular expressions");
+ }
+
+ return it;
+ };
+
+ var MATCH$1 = wellKnownSymbol('match');
+
+ var correctIsRegexpLogic = function correctIsRegexpLogic(METHOD_NAME) {
+ var regexp = /./;
+
+ try {
+ '/./'[METHOD_NAME](regexp);
+ } catch (error1) {
+ try {
+ regexp[MATCH$1] = false;
+ return '/./'[METHOD_NAME](regexp);
+ } catch (error2) {
+ /* empty */
+ }
+ }
+
+ return false;
+ };
+
+ // https://tc39.es/ecma262/#sec-string.prototype.includes
+
+
+ _export({
+ target: 'String',
+ proto: true,
+ forced: !correctIsRegexpLogic('includes')
+ }, {
+ includes: function includes(searchString
+ /* , position = 0 */
+ ) {
+ return !!~String(requireObjectCoercible(this)).indexOf(notARegexp(searchString), arguments.length > 1 ? arguments[1] : undefined);
+ }
+ });
+
+ /**
+ * A base-class (or a mixin) adding support for event-listener and dispatchers.
+ */
+
+ /**
+ * Hooks exist to allow users to alter flow.js file processing. This is intended for users relying on a dropzone and other higher-level components
+ * when the flow between `addFiles()` and `upload()` is hardly configurable.
+ * Users calling `await flow.asyncAddFiles()` have more room for customization before calling `upload();` without having to rely upon hooks.
+ *
+ * Hooks can *alter* the parameters they receive (javascript pass-by-reference rules will apply).
+ * For example, the `file-added` hook receives a `flowfile` parameter. `delete flowfile` or `flowfile = {}` have no effect
+ * because parent function still hold reference. But `delete flowfile.file` would remove the File() and is supported as a way to
+ * dequeue a file from a list after its initialization.
+ */
+ var HOOKS = ['file-added', 'files-added', 'files-submitted'];
+ /**
+ * Additionally, some hooks are said filtering-hooks.
+ * Code will consider the combined (OR-ed) return value of the callbacks to
+ * decide whether or not keep processing this path/item.
+ */
+
+ var FILTERING_HOOKS = ['filter-file'];
+ /**
+ * Events are recognized (case-sensitive) CustomEvent processed using dispatchEvent.
+ * This is a list of those fire by Flow.js, but any name can be attached too.
+ */
+
+ var EVENTS = ['complete', 'error', 'file-error', 'file-progress', 'file-removed', 'file-retry', 'file-success', 'progress', 'upload-start'];
+ /**
+ * This class:
+ * - add EventListener support to an object.
+ * - wrap EventListener attachment in order to ease their removal
+ * - add the concept of processing hooks similar to native events (explained below)
+ *
+ * The file is organized in three parts:
+ * 1. isHook, isFilter, isEvent, on, off
+ * wrap the above concept and offer an unified interface. Whether a callback
+ * apply to a hook or an event is determined by its name (and the "async" nature of
+ * the callback).
+ *
+ * 2. Events: addEventListener, removeEventListener and *emit()*
+ * apply to addition/removal/dispatching of *events*.
+ *
+ * 3. Hooks: addHook, hasHook, removeHook apply to addition/removal of *hooks*.
+ * - *hook()* trigger the hook execution.
+ * - *aHook()* is the async counterpart.
+ */
+
+ EventTarget.prototype._addEventListener = EventTarget.prototype.addEventListener;
+ EventTarget.prototype._removeEventListener = EventTarget.prototype.removeEventListener;
+
+ var _default = /*#__PURE__*/function (_EventTarget) {
+ _inherits(_default, _EventTarget);
+
+ var _super = _createSuper(_default);
+
+ /**
+ * List of hooks or events:
+ * key stands for hook or event name
+ * value array list of callbacks
+ *
+ * Each key is check against an hardcoded to list to defined whether:
+ * - it's a "native" CustomEvent (dispatched asynchronously dirsregarding its value)
+ * - it's a known event (whether a "filter" or an "action", and in this case, whether
+ * each callback is asynchronous or not.
+ * @type {}
+ */
+ function _default() {
+ var _this;
+
+ var hooks_events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ _classCallCheck(this, _default);
+
+ _this = _super.call(this);
+ _this._events = {};
+ _this._hooks = {};
+ _this._asyncHooks = {};
+ /**
+ * Hooks and events are distinguished based on the name.
+ * Anything not being a know hook is assumed an event
+ */
+
+ for (var _i = 0, _Object$entries = Object.entries(hooks_events); _i < _Object$entries.length; _i++) {
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
+ name = _Object$entries$_i[0],
+ callbacks = _Object$entries$_i[1];
+
+ var _iterator = _createForOfIteratorHelper(callbacks),
+ _step;
+
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ var callback = _step.value;
+
+ _this.on(name, callback);
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
+ }
+
+ return _this;
+ }
+
+ _createClass(_default, [{
+ key: "isHook",
+ value: function isHook(name) {
+ return HOOKS.includes(name) || this.isFilter(name);
+ }
+ }, {
+ key: "isFilter",
+ value: function isFilter(name) {
+ return FILTERING_HOOKS.includes(name);
+ }
+ }, {
+ key: "isEvent",
+ value: function isEvent(name) {
+ return !this.isHook(name);
+ }
+ }, {
+ key: "_camelToDashCase",
+ value: function _camelToDashCase(str) {
+ return str.replace(/[A-Z]/g, function (letter) {
+ return "-".concat(letter.toLowerCase());
+ });
+ }
+ /**
+ * A wrapper for addEventListener to alternatively add hooks or events.
+ */
+
+ }, {
+ key: "on",
+ value: function on(event, callback, options) {
+ var revent = this._camelToDashCase(event);
+
+ if (revent != event) {
+ console.warn("Flow.js v3: Do not rely on camel-case (".concat(event, ") event names."));
+
+ if (HOOKS.concat(FILTERING_HOOKS, EVENTS).includes(revent)) {
+ event = revent;
+ console.info("Using \"".concat(revent, "\" instead."));
+ }
+ }
+
+ return this.isEvent(event) ? this.addEventListener(event, callback, options) : this.addHook(event, callback, options);
+ }
+ /**
+ * A wrapper for addEventListener to alternatively add hooks or events.
+ */
+
+ }, {
+ key: "once",
+ value: function once(event, callback, options) {
+ return this.isEvent(event) ? this.addEventListener(event, callback, _objectSpread2(_objectSpread2({}, options), {}, {
+ once: true
+ })) : console.warn('once() is not implemented for hooks.');
+ }
+ /**
+ * A wrapper for removeEventListener to alternatively remove hooks or events.
+ */
+
+ }, {
+ key: "off",
+ value: function off(event, callback, options) {
+ if (this.isEvent(event) || !event) {
+ // console.log(`[event] Remove event listeners...`);
+ this.removeEventListener(event, callback, options);
+ }
+
+ if (!this.isEvent(event) || !event) {
+ // console.log(`[event] Remove hooks...`);
+ this.removeHook(event, callback, options);
+ }
+ }
+ /**
+ * A wrapper around native Target event listeners taken from:
+ * https://github.com/alex2844/js-events
+ *
+ * Return an unbinder() callback, like https://github.com/ai/nanoevents
+ *
+ * @doc: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
+ */
+
+ }, {
+ key: "addEventListener",
+ value: function addEventListener(event, callback) {
+ var _arguments = arguments,
+ _this2 = this;
+
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
+
+ var _callback = callback,
+ runUnbinder = function runUnbinder() {
+ _this2.removeEventListener(event, callback, options);
+
+ _callback.apply(_this2, _arguments);
+ },
+ unbinder = function unbinder() {
+ _this2.removeEventListener(event, callback, options);
+ };
+
+ if (options && options.once) {
+ callback = runUnbinder;
+ }
+
+ this._addEventListener(event, callback, options);
+
+ if (!this._events) {
+ this._events = {};
+ Object.defineProperty(this, '_events', {
+ enumerable: false
+ });
+ }
+
+ if (!this._events[event]) {
+ this._events[event] = [];
+ }
+
+ this._events[event].push({
+ listener: callback,
+ useCapture: options === true || options.capture || false,
+ passive: options && options.passive || false,
+ once: options && options.once || false,
+ type: event
+ });
+
+ return unbinder;
+ }
+ }, {
+ key: "removeEventListener",
+ value: function removeEventListener(event) {
+ var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
+
+ // var callback = e => callback.call(this, ...e.detail);
+ if (callback) {
+ this._removeEventListener(event, callback, options);
+ }
+
+ if (!this._events || event && !this._events[event]) {
+ return;
+ }
+
+ if (!event || event === '*') {
+ for (var _i2 = 0, _Object$keys = Object.keys(this._events); _i2 < _Object$keys.length; _i2++) {
+ var name = _Object$keys[_i2];
+ // console.log('[event] Removing all event listeners');
+ this.removeEventListener(name);
+ }
+
+ return;
+ }
+
+ var _iterator2 = _createForOfIteratorHelper(this._events[event].entries()),
+ _step2;
+
+ try {
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+ var _step2$value = _slicedToArray(_step2.value, 2),
+ i = _step2$value[0],
+ v = _step2$value[1];
+
+ if ((!callback || v.listener == callback) && v.useCapture == options) {
+ // console.log(`[event] Removed one callback from "${event}"`);
+ this._events[event].splice(i, 1);
+
+ if (!callback) {
+ this._removeEventListener(event, v.listener, v);
+ } else {
+ break;
+ }
+ }
+ }
+ } catch (err) {
+ _iterator2.e(err);
+ } finally {
+ _iterator2.f();
+ }
+
+ if (this._events[event].length == 0) {
+ delete this._events[event];
+ }
+ }
+ /**
+ * A wrapper for dispatchEvent handling "catch-all"
+ */
+
+ }, {
+ key: "emit",
+ value: function () {
+ var _emit = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(name) {
+ var _len,
+ args,
+ _key,
+ _args = arguments;
+
+ return regeneratorRuntime.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ for (_len = _args.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = _args[_key];
+ }
+
+ // console.log(`[event] Fire native event "${name}"${args.length ? ' with ' + args.length + ' arguments' : ''}`);
+ this.dispatchEvent(new CustomEvent(name, {
+ detail: args
+ }));
+
+ if (name != 'catch-all') {
+ this.emitCatchAll.apply(this, [name].concat(args));
+ }
+
+ case 3:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ }));
+
+ function emit(_x) {
+ return _emit.apply(this, arguments);
+ }
+
+ return emit;
+ }()
+ }, {
+ key: "emitCatchAll",
+ value: function () {
+ var _emitCatchAll = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(name) {
+ var _len2,
+ args,
+ _key2,
+ _args2 = arguments;
+
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ for (_len2 = _args2.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ args[_key2 - 1] = _args2[_key2];
+ }
+
+ this.dispatchEvent(new CustomEvent('catch-all', {
+ detail: [name].concat(args)
+ }));
+
+ case 2:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ }, _callee2, this);
+ }));
+
+ function emitCatchAll(_x2) {
+ return _emitCatchAll.apply(this, arguments);
+ }
+
+ return emitCatchAll;
+ }()
+ /**
+ * ### HOOKS ###
+ */
+
+ }, {
+ key: "addHook",
+ value: function addHook(event, callback, options) {
+ var isAsync = callback.constructor.name === 'AsyncFunction',
+ target = isAsync ? this._asyncHooks : this._hooks;
+
+ if (!target.hasOwnProperty(event)) {
+ target[event] = [];
+ }
+
+ target[event].push(callback);
+ }
+ }, {
+ key: "hasHook",
+ value: function hasHook(async, events) {
+ events = typeof events === 'string' ? [events] : events || [];
+ var target = async ? this._asyncHooks : this._hooks;
+
+ for (var _i3 = 0, _Object$entries2 = Object.entries(target); _i3 < _Object$entries2.length; _i3++) {
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i3], 2),
+ k = _Object$entries2$_i[0],
+ v = _Object$entries2$_i[1];
+
+ if (events.length > 0 && !events.includes(k)) {
+ continue;
+ }
+
+ if (v.length > 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ /**
+ * Remove one of more hooks' callbacks.
+ */
+
+ }, {
+ key: "removeHook",
+ value: function removeHook(event, callback, options) {
+ var arrayRemove = function arrayRemove(array, value) {
+ var index = array.indexOf(value);
+
+ if (index > -1) {
+ array.splice(index, 1);
+ }
+ };
+
+ if (event && event != '*') {
+ if (callback) {
+ var isAsync = callback.constructor.name === 'AsyncFunction',
+ target = isAsync ? this._asyncHooks : this._hooks;
+
+ if (target.hasOwnProperty(event)) {
+ arrayRemove(target[event], callback);
+ }
+ } else {
+ delete this._hooks[event];
+ delete this._asyncHooks[event];
+ }
+ } else {
+ this._hooks = {};
+ this._asyncHooks = {};
+ }
+ }
+ /**
+ * Run a synchronous hook (action or filter).
+ *
+ * @param {string} event event name
+ * @param {...} args arguments of a callback
+ *
+ * @return {bool} In the case of *filters*, indicates whether processing must continue.
+ * @return null In the case of *actions*.
+ */
+
+ }, {
+ key: "hook",
+ value: function hook(name) {
+ var value,
+ preventDefault = false,
+ isFilter = this.isFilter(name),
+ callbacks = this._hooks[name] || [];
+
+ for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
+ args[_key3 - 1] = arguments[_key3];
+ }
+
+ var _iterator3 = _createForOfIteratorHelper(callbacks),
+ _step3;
+
+ try {
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
+ var callback = _step3.value;
+ // console.log(`[event] Fire hook "${name}"${args.length ? ' with ' + args.length + ' arguments' : ''}`);
+ value = callback.apply(this, args);
+
+ if (name === 'file-added' && value === false) {
+ console.warn('In Flow.js 3.x, file-added event is an action rather than a fitler. return value is ignored but removing the `file` property allows to skip an enqueued file.');
+ }
+
+ if (isFilter) {
+ // console.log(`[filter-event] ${event} returned:`, item.value);
+ preventDefault |= value === false;
+ } else {// Changes happen by reference. We ignore iterator.next().value.
+ }
+ }
+ } catch (err) {
+ _iterator3.e(err);
+ } finally {
+ _iterator3.f();
+ }
+
+ this.emitCatchAll.apply(this, [name].concat(args));
+ return isFilter ? !preventDefault : null;
+ }
+ /**
+ * Run an asynchronous hook (action or filter).
+ *
+ * @param {string} event event name
+ * @param {...} args arguments of a callback
+ *
+ * @return {bool} In the case of *filters*, indicates whether processing must continue.
+ * @return {mixed} In the case of *actions*: The first argument (possibly modified by hooks).
+ */
+
+ }, {
+ key: "aHook",
+ value: function () {
+ var _aHook = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(name) {
+ var _this3 = this;
+
+ var _len4,
+ args,
+ _key4,
+ calls,
+ isFilter,
+ returns,
+ _args3 = arguments;
+
+ return regeneratorRuntime.wrap(function _callee3$(_context3) {
+ while (1) {
+ switch (_context3.prev = _context3.next) {
+ case 0:
+ for (_len4 = _args3.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
+ args[_key4 - 1] = _args3[_key4];
+ }
+
+ calls = this._asyncHooks[name] || [], isFilter = this.isFilter(name);
+
+ if (calls.length) {
+ _context3.next = 4;
+ break;
+ }
+
+ return _context3.abrupt("return", isFilter ? true : args[0]);
+
+ case 4:
+ _context3.next = 6;
+ return Promise.all(calls.map(function (e) {
+ return e.apply(_this3, args);
+ }));
+
+ case 6:
+ returns = _context3.sent;
+ this.emitCatchAll.apply(this, [name].concat(args));
+ return _context3.abrupt("return", isFilter ? returns.include(false) : returns);
+
+ case 9:
+ case "end":
+ return _context3.stop();
+ }
+ }
+ }, _callee3, this);
+ }));
+
+ function aHook(_x3) {
+ return _aHook.apply(this, arguments);
+ }
+
+ return aHook;
+ }()
+ }]);
+
+ return _default;
+ }( /*#__PURE__*/_wrapNativeSuper(EventTarget));
+
+ var min$4 = Math.min;
+ var nativeLastIndexOf = [].lastIndexOf;
+ var NEGATIVE_ZERO$1 = !!nativeLastIndexOf && 1 / [1].lastIndexOf(1, -0) < 0;
+ var STRICT_METHOD$1 = arrayMethodIsStrict('lastIndexOf'); // For preventing possible almost infinite loop in non-standard implementations, test the forward version of the method
+
+ var USES_TO_LENGTH$5 = arrayMethodUsesToLength('indexOf', {
+ ACCESSORS: true,
+ 1: 0
+ });
+ var FORCED$2 = NEGATIVE_ZERO$1 || !STRICT_METHOD$1 || !USES_TO_LENGTH$5; // `Array.prototype.lastIndexOf` method implementation
+ // https://tc39.es/ecma262/#sec-array.prototype.lastindexof
+
+ var arrayLastIndexOf = FORCED$2 ? function lastIndexOf(searchElement
+ /* , fromIndex = @[*-1] */
+ ) {
+ // convert -0 to +0
+ if (NEGATIVE_ZERO$1) return nativeLastIndexOf.apply(this, arguments) || 0;
+ var O = toIndexedObject(this);
+ var length = toLength(O.length);
+ var index = length - 1;
+ if (arguments.length > 1) index = min$4(index, toInteger(arguments[1]));
+ if (index < 0) index = length + index;
+
+ for (; index >= 0; index--) {
+ if (index in O && O[index] === searchElement) return index || 0;
+ }
+
+ return -1;
+ } : nativeLastIndexOf;
+
+ // https://tc39.es/ecma262/#sec-array.prototype.lastindexof
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: arrayLastIndexOf !== [].lastIndexOf
+ }, {
+ lastIndexOf: arrayLastIndexOf
+ });
+
+ var arrayPush = [].push;
+ var min$5 = Math.min;
+ var MAX_UINT32 = 0xFFFFFFFF; // babel-minify transpiles RegExp('x', 'y') -> /x/y and it causes SyntaxError
+
+ var SUPPORTS_Y = !fails(function () {
+ return !RegExp(MAX_UINT32, 'y');
+ }); // @@split logic
+
+ fixRegexpWellKnownSymbolLogic('split', 2, function (SPLIT, nativeSplit, maybeCallNative) {
+ var internalSplit;
+
+ if ('abbc'.split(/(b)*/)[1] == 'c' || 'test'.split(/(?:)/, -1).length != 4 || 'ab'.split(/(?:ab)*/).length != 2 || '.'.split(/(.?)(.?)/).length != 4 || '.'.split(/()()/).length > 1 || ''.split(/.?/).length) {
+ // based on es5-shim implementation, need to rework it
+ internalSplit = function internalSplit(separator, limit) {
+ var string = String(requireObjectCoercible(this));
+ var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
+ if (lim === 0) return [];
+ if (separator === undefined) return [string]; // If `separator` is not a regex, use native split
+
+ if (!isRegexp(separator)) {
+ return nativeSplit.call(string, separator, lim);
+ }
+
+ var output = [];
+ var flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.unicode ? 'u' : '') + (separator.sticky ? 'y' : '');
+ var lastLastIndex = 0; // Make `global` and avoid `lastIndex` issues by working with a copy
+
+ var separatorCopy = new RegExp(separator.source, flags + 'g');
+ var match, lastIndex, lastLength;
+
+ while (match = regexpExec.call(separatorCopy, string)) {
+ lastIndex = separatorCopy.lastIndex;
+
+ if (lastIndex > lastLastIndex) {
+ output.push(string.slice(lastLastIndex, match.index));
+ if (match.length > 1 && match.index < string.length) arrayPush.apply(output, match.slice(1));
+ lastLength = match[0].length;
+ lastLastIndex = lastIndex;
+ if (output.length >= lim) break;
+ }
+
+ if (separatorCopy.lastIndex === match.index) separatorCopy.lastIndex++; // Avoid an infinite loop
+ }
+
+ if (lastLastIndex === string.length) {
+ if (lastLength || !separatorCopy.test('')) output.push('');
+ } else output.push(string.slice(lastLastIndex));
+
+ return output.length > lim ? output.slice(0, lim) : output;
+ }; // Chakra, V8
+
+ } else if ('0'.split(undefined, 0).length) {
+ internalSplit = function internalSplit(separator, limit) {
+ return separator === undefined && limit === 0 ? [] : nativeSplit.call(this, separator, limit);
+ };
+ } else internalSplit = nativeSplit;
+
+ return [// `String.prototype.split` method
+ // https://tc39.es/ecma262/#sec-string.prototype.split
+ function split(separator, limit) {
+ var O = requireObjectCoercible(this);
+ var splitter = separator == undefined ? undefined : separator[SPLIT];
+ return splitter !== undefined ? splitter.call(separator, O, limit) : internalSplit.call(String(O), separator, limit);
+ }, // `RegExp.prototype[@@split]` method
+ // https://tc39.es/ecma262/#sec-regexp.prototype-@@split
+ //
+ // NOTE: This cannot be properly polyfilled in engines that don't support
+ // the 'y' flag.
+ function (regexp, limit) {
+ var res = maybeCallNative(internalSplit, regexp, this, limit, internalSplit !== nativeSplit);
+ if (res.done) return res.value;
+ var rx = anObject(regexp);
+ var S = String(this);
+ var C = speciesConstructor(rx, RegExp);
+ var unicodeMatching = rx.unicode;
+ var flags = (rx.ignoreCase ? 'i' : '') + (rx.multiline ? 'm' : '') + (rx.unicode ? 'u' : '') + (SUPPORTS_Y ? 'y' : 'g'); // ^(? + rx + ) is needed, in combination with some S slicing, to
+ // simulate the 'y' flag.
+
+ var splitter = new C(SUPPORTS_Y ? rx : '^(?:' + rx.source + ')', flags);
+ var lim = limit === undefined ? MAX_UINT32 : limit >>> 0;
+ if (lim === 0) return [];
+ if (S.length === 0) return regexpExecAbstract(splitter, S) === null ? [S] : [];
+ var p = 0;
+ var q = 0;
+ var A = [];
+
+ while (q < S.length) {
+ splitter.lastIndex = SUPPORTS_Y ? q : 0;
+ var z = regexpExecAbstract(splitter, SUPPORTS_Y ? S : S.slice(q));
+ var e;
+
+ if (z === null || (e = min$5(toLength(splitter.lastIndex + (SUPPORTS_Y ? 0 : q)), S.length)) === p) {
+ q = advanceStringIndex(S, q, unicodeMatching);
+ } else {
+ A.push(S.slice(p, q));
+ if (A.length === lim) return A;
+
+ for (var i = 1; i <= z.length - 1; i++) {
+ A.push(z[i]);
+ if (A.length === lim) return A;
+ }
+
+ q = p = e;
+ }
+ }
+
+ A.push(S.slice(p));
+ return A;
+ }];
+ }, !SUPPORTS_Y);
+
+ var nativeJoin = [].join;
+ var ES3_STRINGS = indexedObject != Object;
+ var STRICT_METHOD$2 = arrayMethodIsStrict('join', ','); // `Array.prototype.join` method
+ // https://tc39.es/ecma262/#sec-array.prototype.join
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: ES3_STRINGS || !STRICT_METHOD$2
+ }, {
+ join: function join(separator) {
+ return nativeJoin.call(toIndexedObject(this), separator === undefined ? ',' : separator);
+ }
+ });
+
+ var HAS_SPECIES_SUPPORT$3 = arrayMethodHasSpeciesSupport('slice');
+ var USES_TO_LENGTH$6 = arrayMethodUsesToLength('slice', {
+ ACCESSORS: true,
+ 0: 0,
+ 1: 2
+ });
+ var SPECIES$6 = wellKnownSymbol('species');
+ var nativeSlice = [].slice;
+ var max$3 = Math.max; // `Array.prototype.slice` method
+ // https://tc39.es/ecma262/#sec-array.prototype.slice
+ // fallback for not array-like ES3 strings and DOM objects
+
+ _export({
+ target: 'Array',
+ proto: true,
+ forced: !HAS_SPECIES_SUPPORT$3 || !USES_TO_LENGTH$6
+ }, {
+ slice: function slice(start, end) {
+ var O = toIndexedObject(this);
+ var length = toLength(O.length);
+ var k = toAbsoluteIndex(start, length);
+ var fin = toAbsoluteIndex(end === undefined ? length : end, length); // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
+
+ var Constructor, result, n;
+
+ if (isArray(O)) {
+ Constructor = O.constructor; // cross-realm fallback
+
+ if (typeof Constructor == 'function' && (Constructor === Array || isArray(Constructor.prototype))) {
+ Constructor = undefined;
+ } else if (isObject(Constructor)) {
+ Constructor = Constructor[SPECIES$6];
+ if (Constructor === null) Constructor = undefined;
+ }
+
+ if (Constructor === Array || Constructor === undefined) {
+ return nativeSlice.call(O, k, fin);
+ }
+ }
+
+ result = new (Constructor === undefined ? Array : Constructor)(max$3(fin - k, 0));
+
+ for (n = 0; k < fin; k++, n++) {
+ if (k in O) createProperty(result, n, O[k]);
+ }
+
+ result.length = n;
+ return result;
+ }
+ });
+
+ /**
+ * Default read function using the webAPI
+ *
+ * @function webAPIFileRead(fileObj, startByte, endByte, fileType, chunk)
+ *
+ */
+ function webAPIFileRead(fileObj, startByte, endByte, fileType, chunk) {
+ var function_name = 'slice';
+ if (fileObj.file.slice) function_name = 'slice';else if (fileObj.file.mozSlice) function_name = 'mozSlice';else if (fileObj.file.webkitSlice) function_name = 'webkitSlice';
+ chunk.readFinished(fileObj.file[function_name](startByte, endByte, fileType));
}
- // ie10+
- var ie10plus = window.navigator.msPointerEnabled;
/**
- * Flow.js is a library providing multiple simultaneous, stable and
- * resumable uploads via the HTML5 File API.
- * @param [opts]
- * @param {number|Function} [opts.chunkSize]
- * @param {bool} [opts.forceChunkSize]
- * @param {number} [opts.simultaneousUploads]
- * @param {bool} [opts.singleFile]
- * @param {string} [opts.fileParameterName]
- * @param {number} [opts.progressCallbacksInterval]
- * @param {number} [opts.speedSmoothingFactor]
- * @param {Object|Function} [opts.query]
- * @param {Object|Function} [opts.headers]
- * @param {bool} [opts.withCredentials]
- * @param {Function} [opts.preprocess]
- * @param {string} [opts.method]
- * @param {string|Function} [opts.testMethod]
- * @param {string|Function} [opts.uploadMethod]
- * @param {bool} [opts.prioritizeFirstAndLastChunk]
- * @param {bool} [opts.allowDuplicateUploads]
- * @param {string|Function} [opts.target]
- * @param {number} [opts.maxChunkRetries]
- * @param {number} [opts.chunkRetryInterval]
- * @param {Array.} [opts.permanentErrors]
- * @param {Array.} [opts.successStatuses]
- * @param {Function} [opts.initFileFn]
- * @param {Function} [opts.readFileFn]
- * @param {Function} [opts.generateUniqueIdentifier]
+ * If option is a function, evaluate it with given params
+ * @param {*} data
+ * @param {...} args arguments of a callback
+ * @returns {*}
+ */
+
+
+ function evalOpts(data, args) {
+ if (typeof data === "function") {
+ // `arguments` is an object, not array, in FF, so:
+ args = Array.prototype.slice.call(arguments);
+ data = data.apply(null, args.slice(1));
+ }
+
+ return data;
+ }
+ /**
+ * Iterate each element of an object
+ * @function
+ * @param {Array|Object} obj object or an array to iterate
+ * @param {Function} callback first argument is a value and second is a key.
+ * @param {Object=} context Object to become context (`this`) for the iterator function.
+ */
+
+
+ function each(obj, callback, context) {
+ if (!obj) {
+ return;
+ }
+
+ var key; // Is Array?
+ // Array.isArray won't work, not only arrays can be iterated by index https://github.com/flowjs/ng-flow/issues/236#
+
+ if (typeof obj.length !== 'undefined') {
+ for (key = 0; key < obj.length; key++) {
+ if (callback.call(context, obj[key], key) === false) {
+ return;
+ }
+ }
+ } else {
+ for (key in obj) {
+ if (obj.hasOwnProperty(key) && callback.call(context, obj[key], key) === false) {
+ return;
+ }
+ }
+ }
+ }
+ /**
+ * Exclusively for test purposes
+ * (Until Grunt+Karma+Jasmine can allow test to use (ES) `import` of tools.js)
+ */
+
+
+ var g = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+ g.evalOpts = evalOpts;
+
+ var nativeGetOwnPropertyNames = objectGetOwnPropertyNames.f;
+ var toString$1 = {}.toString;
+ var windowNames = (typeof window === "undefined" ? "undefined" : _typeof(window)) == 'object' && window && Object.getOwnPropertyNames ? Object.getOwnPropertyNames(window) : [];
+
+ var getWindowNames = function getWindowNames(it) {
+ try {
+ return nativeGetOwnPropertyNames(it);
+ } catch (error) {
+ return windowNames.slice();
+ }
+ }; // fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
+
+
+ var f$6 = function getOwnPropertyNames(it) {
+ return windowNames && toString$1.call(it) == '[object Window]' ? getWindowNames(it) : nativeGetOwnPropertyNames(toIndexedObject(it));
+ };
+
+ var objectGetOwnPropertyNamesExternal = {
+ f: f$6
+ };
+
+ var f$7 = wellKnownSymbol;
+ var wellKnownSymbolWrapped = {
+ f: f$7
+ };
+
+ var defineProperty$5 = objectDefineProperty.f;
+
+ var defineWellKnownSymbol = function defineWellKnownSymbol(NAME) {
+ var _Symbol = path.Symbol || (path.Symbol = {});
+
+ if (!has(_Symbol, NAME)) defineProperty$5(_Symbol, NAME, {
+ value: wellKnownSymbolWrapped.f(NAME)
+ });
+ };
+
+ var $forEach = arrayIteration.forEach;
+ var HIDDEN = sharedKey('hidden');
+ var SYMBOL = 'Symbol';
+ var PROTOTYPE$1 = 'prototype';
+ var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');
+ var setInternalState$3 = internalState.set;
+ var getInternalState$3 = internalState.getterFor(SYMBOL);
+ var ObjectPrototype$1 = Object[PROTOTYPE$1];
+ var $Symbol = global$1.Symbol;
+ var $stringify = getBuiltIn('JSON', 'stringify');
+ var nativeGetOwnPropertyDescriptor$1 = objectGetOwnPropertyDescriptor.f;
+ var nativeDefineProperty$1 = objectDefineProperty.f;
+ var nativeGetOwnPropertyNames$1 = objectGetOwnPropertyNamesExternal.f;
+ var nativePropertyIsEnumerable$1 = objectPropertyIsEnumerable.f;
+ var AllSymbols = shared('symbols');
+ var ObjectPrototypeSymbols = shared('op-symbols');
+ var StringToSymbolRegistry = shared('string-to-symbol-registry');
+ var SymbolToStringRegistry = shared('symbol-to-string-registry');
+ var WellKnownSymbolsStore$1 = shared('wks');
+ var QObject = global$1.QObject; // Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
+
+ var USE_SETTER = !QObject || !QObject[PROTOTYPE$1] || !QObject[PROTOTYPE$1].findChild; // fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
+
+ var setSymbolDescriptor = descriptors && fails(function () {
+ return objectCreate(nativeDefineProperty$1({}, 'a', {
+ get: function get() {
+ return nativeDefineProperty$1(this, 'a', {
+ value: 7
+ }).a;
+ }
+ })).a != 7;
+ }) ? function (O, P, Attributes) {
+ var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor$1(ObjectPrototype$1, P);
+ if (ObjectPrototypeDescriptor) delete ObjectPrototype$1[P];
+ nativeDefineProperty$1(O, P, Attributes);
+
+ if (ObjectPrototypeDescriptor && O !== ObjectPrototype$1) {
+ nativeDefineProperty$1(ObjectPrototype$1, P, ObjectPrototypeDescriptor);
+ }
+ } : nativeDefineProperty$1;
+
+ var wrap = function wrap(tag, description) {
+ var symbol = AllSymbols[tag] = objectCreate($Symbol[PROTOTYPE$1]);
+ setInternalState$3(symbol, {
+ type: SYMBOL,
+ tag: tag,
+ description: description
+ });
+ if (!descriptors) symbol.description = description;
+ return symbol;
+ };
+
+ var isSymbol = useSymbolAsUid ? function (it) {
+ return _typeof(it) == 'symbol';
+ } : function (it) {
+ return Object(it) instanceof $Symbol;
+ };
+
+ var $defineProperty = function defineProperty(O, P, Attributes) {
+ if (O === ObjectPrototype$1) $defineProperty(ObjectPrototypeSymbols, P, Attributes);
+ anObject(O);
+ var key = toPrimitive(P, true);
+ anObject(Attributes);
+
+ if (has(AllSymbols, key)) {
+ if (!Attributes.enumerable) {
+ if (!has(O, HIDDEN)) nativeDefineProperty$1(O, HIDDEN, createPropertyDescriptor(1, {}));
+ O[HIDDEN][key] = true;
+ } else {
+ if (has(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;
+ Attributes = objectCreate(Attributes, {
+ enumerable: createPropertyDescriptor(0, false)
+ });
+ }
+
+ return setSymbolDescriptor(O, key, Attributes);
+ }
+
+ return nativeDefineProperty$1(O, key, Attributes);
+ };
+
+ var $defineProperties = function defineProperties(O, Properties) {
+ anObject(O);
+ var properties = toIndexedObject(Properties);
+ var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties));
+ $forEach(keys, function (key) {
+ if (!descriptors || $propertyIsEnumerable.call(properties, key)) $defineProperty(O, key, properties[key]);
+ });
+ return O;
+ };
+
+ var $create = function create(O, Properties) {
+ return Properties === undefined ? objectCreate(O) : $defineProperties(objectCreate(O), Properties);
+ };
+
+ var $propertyIsEnumerable = function propertyIsEnumerable(V) {
+ var P = toPrimitive(V, true);
+ var enumerable = nativePropertyIsEnumerable$1.call(this, P);
+ if (this === ObjectPrototype$1 && has(AllSymbols, P) && !has(ObjectPrototypeSymbols, P)) return false;
+ return enumerable || !has(this, P) || !has(AllSymbols, P) || has(this, HIDDEN) && this[HIDDEN][P] ? enumerable : true;
+ };
+
+ var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {
+ var it = toIndexedObject(O);
+ var key = toPrimitive(P, true);
+ if (it === ObjectPrototype$1 && has(AllSymbols, key) && !has(ObjectPrototypeSymbols, key)) return;
+ var descriptor = nativeGetOwnPropertyDescriptor$1(it, key);
+
+ if (descriptor && has(AllSymbols, key) && !(has(it, HIDDEN) && it[HIDDEN][key])) {
+ descriptor.enumerable = true;
+ }
+
+ return descriptor;
+ };
+
+ var $getOwnPropertyNames = function getOwnPropertyNames(O) {
+ var names = nativeGetOwnPropertyNames$1(toIndexedObject(O));
+ var result = [];
+ $forEach(names, function (key) {
+ if (!has(AllSymbols, key) && !has(hiddenKeys, key)) result.push(key);
+ });
+ return result;
+ };
+
+ var $getOwnPropertySymbols = function getOwnPropertySymbols(O) {
+ var IS_OBJECT_PROTOTYPE = O === ObjectPrototype$1;
+ var names = nativeGetOwnPropertyNames$1(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));
+ var result = [];
+ $forEach(names, function (key) {
+ if (has(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || has(ObjectPrototype$1, key))) {
+ result.push(AllSymbols[key]);
+ }
+ });
+ return result;
+ }; // `Symbol` constructor
+ // https://tc39.es/ecma262/#sec-symbol-constructor
+
+
+ if (!nativeSymbol) {
+ $Symbol = function _Symbol() {
+ if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor');
+ var description = !arguments.length || arguments[0] === undefined ? undefined : String(arguments[0]);
+ var tag = uid(description);
+
+ var setter = function setter(value) {
+ if (this === ObjectPrototype$1) setter.call(ObjectPrototypeSymbols, value);
+ if (has(this, HIDDEN) && has(this[HIDDEN], tag)) this[HIDDEN][tag] = false;
+ setSymbolDescriptor(this, tag, createPropertyDescriptor(1, value));
+ };
+
+ if (descriptors && USE_SETTER) setSymbolDescriptor(ObjectPrototype$1, tag, {
+ configurable: true,
+ set: setter
+ });
+ return wrap(tag, description);
+ };
+
+ redefine($Symbol[PROTOTYPE$1], 'toString', function toString() {
+ return getInternalState$3(this).tag;
+ });
+ redefine($Symbol, 'withoutSetter', function (description) {
+ return wrap(uid(description), description);
+ });
+ objectPropertyIsEnumerable.f = $propertyIsEnumerable;
+ objectDefineProperty.f = $defineProperty;
+ objectGetOwnPropertyDescriptor.f = $getOwnPropertyDescriptor;
+ objectGetOwnPropertyNames.f = objectGetOwnPropertyNamesExternal.f = $getOwnPropertyNames;
+ objectGetOwnPropertySymbols.f = $getOwnPropertySymbols;
+
+ wellKnownSymbolWrapped.f = function (name) {
+ return wrap(wellKnownSymbol(name), name);
+ };
+
+ if (descriptors) {
+ // https://github.com/tc39/proposal-Symbol-description
+ nativeDefineProperty$1($Symbol[PROTOTYPE$1], 'description', {
+ configurable: true,
+ get: function description() {
+ return getInternalState$3(this).description;
+ }
+ });
+
+ {
+ redefine(ObjectPrototype$1, 'propertyIsEnumerable', $propertyIsEnumerable, {
+ unsafe: true
+ });
+ }
+ }
+ }
+
+ _export({
+ global: true,
+ wrap: true,
+ forced: !nativeSymbol,
+ sham: !nativeSymbol
+ }, {
+ Symbol: $Symbol
+ });
+ $forEach(objectKeys(WellKnownSymbolsStore$1), function (name) {
+ defineWellKnownSymbol(name);
+ });
+ _export({
+ target: SYMBOL,
+ stat: true,
+ forced: !nativeSymbol
+ }, {
+ // `Symbol.for` method
+ // https://tc39.es/ecma262/#sec-symbol.for
+ 'for': function _for(key) {
+ var string = String(key);
+ if (has(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];
+ var symbol = $Symbol(string);
+ StringToSymbolRegistry[string] = symbol;
+ SymbolToStringRegistry[symbol] = string;
+ return symbol;
+ },
+ // `Symbol.keyFor` method
+ // https://tc39.es/ecma262/#sec-symbol.keyfor
+ keyFor: function keyFor(sym) {
+ if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol');
+ if (has(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];
+ },
+ useSetter: function useSetter() {
+ USE_SETTER = true;
+ },
+ useSimple: function useSimple() {
+ USE_SETTER = false;
+ }
+ });
+ _export({
+ target: 'Object',
+ stat: true,
+ forced: !nativeSymbol,
+ sham: !descriptors
+ }, {
+ // `Object.create` method
+ // https://tc39.es/ecma262/#sec-object.create
+ create: $create,
+ // `Object.defineProperty` method
+ // https://tc39.es/ecma262/#sec-object.defineproperty
+ defineProperty: $defineProperty,
+ // `Object.defineProperties` method
+ // https://tc39.es/ecma262/#sec-object.defineproperties
+ defineProperties: $defineProperties,
+ // `Object.getOwnPropertyDescriptor` method
+ // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors
+ getOwnPropertyDescriptor: $getOwnPropertyDescriptor
+ });
+ _export({
+ target: 'Object',
+ stat: true,
+ forced: !nativeSymbol
+ }, {
+ // `Object.getOwnPropertyNames` method
+ // https://tc39.es/ecma262/#sec-object.getownpropertynames
+ getOwnPropertyNames: $getOwnPropertyNames,
+ // `Object.getOwnPropertySymbols` method
+ // https://tc39.es/ecma262/#sec-object.getownpropertysymbols
+ getOwnPropertySymbols: $getOwnPropertySymbols
+ }); // Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
+ // https://bugs.chromium.org/p/v8/issues/detail?id=3443
+
+ _export({
+ target: 'Object',
+ stat: true,
+ forced: fails(function () {
+ objectGetOwnPropertySymbols.f(1);
+ })
+ }, {
+ getOwnPropertySymbols: function getOwnPropertySymbols(it) {
+ return objectGetOwnPropertySymbols.f(toObject(it));
+ }
+ }); // `JSON.stringify` method behavior with symbols
+ // https://tc39.es/ecma262/#sec-json.stringify
+
+ if ($stringify) {
+ var FORCED_JSON_STRINGIFY = !nativeSymbol || fails(function () {
+ var symbol = $Symbol(); // MS Edge converts symbol values to JSON as {}
+
+ return $stringify([symbol]) != '[null]' // WebKit converts symbol values to JSON as null
+ || $stringify({
+ a: symbol
+ }) != '{}' // V8 throws on boxed symbols
+ || $stringify(Object(symbol)) != '{}';
+ });
+ _export({
+ target: 'JSON',
+ stat: true,
+ forced: FORCED_JSON_STRINGIFY
+ }, {
+ // eslint-disable-next-line no-unused-vars
+ stringify: function stringify(it, replacer, space) {
+ var args = [it];
+ var index = 1;
+ var $replacer;
+
+ while (arguments.length > index) {
+ args.push(arguments[index++]);
+ }
+
+ $replacer = replacer;
+ if (!isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined
+
+ if (!isArray(replacer)) replacer = function replacer(key, value) {
+ if (typeof $replacer == 'function') value = $replacer.call(this, key, value);
+ if (!isSymbol(value)) return value;
+ };
+ args[1] = replacer;
+ return $stringify.apply(null, args);
+ }
+ });
+ } // `Symbol.prototype[@@toPrimitive]` method
+ // https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive
+
+
+ if (!$Symbol[PROTOTYPE$1][TO_PRIMITIVE]) {
+ createNonEnumerableProperty($Symbol[PROTOTYPE$1], TO_PRIMITIVE, $Symbol[PROTOTYPE$1].valueOf);
+ } // `Symbol.prototype[@@toStringTag]` property
+ // https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag
+
+
+ setToStringTag($Symbol, SYMBOL);
+ hiddenKeys[HIDDEN] = true;
+
+ var defineProperty$6 = objectDefineProperty.f;
+ var NativeSymbol = global$1.Symbol;
+
+ if (descriptors && typeof NativeSymbol == 'function' && (!('description' in NativeSymbol.prototype) || // Safari 12 bug
+ NativeSymbol().description !== undefined)) {
+ var EmptyStringDescriptionStore = {}; // wrap Symbol constructor for correct work with undefined description
+
+ var SymbolWrapper = function _Symbol() {
+ var description = arguments.length < 1 || arguments[0] === undefined ? undefined : String(arguments[0]);
+ var result = this instanceof SymbolWrapper ? new NativeSymbol(description) // in Edge 13, String(Symbol(undefined)) === 'Symbol(undefined)'
+ : description === undefined ? NativeSymbol() : NativeSymbol(description);
+ if (description === '') EmptyStringDescriptionStore[result] = true;
+ return result;
+ };
+
+ copyConstructorProperties(SymbolWrapper, NativeSymbol);
+ var symbolPrototype = SymbolWrapper.prototype = NativeSymbol.prototype;
+ symbolPrototype.constructor = SymbolWrapper;
+ var symbolToString = symbolPrototype.toString;
+ var native = String(NativeSymbol('test')) == 'Symbol(test)';
+ var regexp = /^Symbol\((.*)\)[^)]+$/;
+ defineProperty$6(symbolPrototype, 'description', {
+ configurable: true,
+ get: function description() {
+ var symbol = isObject(this) ? this.valueOf() : this;
+ var string = symbolToString.call(symbol);
+ if (has(EmptyStringDescriptionStore, symbol)) return '';
+ var desc = native ? string.slice(7, -1) : string.replace(regexp, '$1');
+ return desc === '' ? undefined : desc;
+ }
+ });
+ _export({
+ global: true,
+ forced: true
+ }, {
+ Symbol: SymbolWrapper
+ });
+ }
+
+ // https://tc39.es/ecma262/#sec-symbol.tostringtag
+
+ defineWellKnownSymbol('toStringTag');
+
+ // https://tc39.es/ecma262/#sec-json-@@tostringtag
+
+ setToStringTag(global$1.JSON, 'JSON', true);
+
+ // https://tc39.es/ecma262/#sec-math-@@tostringtag
+
+ setToStringTag(Math, 'Math', true);
+
+ var DeferredPromise = // https://stackoverflow.com/a/47112177
+ function DeferredPromise() {
+ var _this = this;
+
+ _classCallCheck(this, DeferredPromise);
+
+ this.resolved = false;
+ this._promise = new Promise(function (resolve, reject) {
+ // assign the resolve and reject functions to `this`
+ // making them usable on the class instance
+ _this.resolve = function () {
+ _this.resolved = true;
+ return resolve();
+ };
+
+ _this.reject = reject;
+ }); // bind `then` and `catch` to implement the same interface as Promise
+
+ this.then = this._promise.then.bind(this._promise);
+ this.catch = this._promise.catch.bind(this._promise);
+ this[Symbol.toStringTag] = 'Promise';
+ };
+
+ /**
+ * Class for storing a single chunk
+ * @name FlowChunk
+ * @param {Flow} flowObj
+ * @param {FlowFile} fileObj
+ * @param {number} offset
* @constructor
*/
- function Flow(opts) {
+
+ var FlowChunk = /*#__PURE__*/function () {
+ function FlowChunk(flowObj, fileObj, offset) {
+ _classCallCheck(this, FlowChunk);
+
+ /**
+ * Reference to parent flow object
+ * @type {Flow}
+ */
+ this.flowObj = flowObj;
+ /**
+ * Reference to parent FlowFile object
+ * @type {FlowFile}
+ */
+
+ this.fileObj = fileObj;
+ /**
+ * File offset
+ * @type {number}
+ */
+
+ this.offset = offset;
+ /**
+ * Indicates if chunk existence was checked on the server
+ * @type {boolean}
+ */
+
+ this.tested = false;
+ /**
+ * Number of retries performed
+ * @type {number}
+ */
+
+ this.retries = 0;
+ /**
+ * Pending retry
+ * @type {boolean}
+ */
+
+ this.pendingRetry = false;
+ /**
+ * Preprocess state
+ * @type {number} 0 = unprocessed, 1 = processing, 2 = finished
+ */
+
+ this.preprocessState = 0;
+ /**
+ * Read state
+ * @type {number} 0 = not read, 1 = reading, 2 = finished
+ */
+
+ this.readState = 0;
+ /**
+ * The payload.
+ * @type {Blob|string}
+ */
+
+ this.payload = null;
+ /**
+ * Mostly for streams: how many bytes were actually read
+ * @type {number} -1 = not read
+ */
+
+ this.readBytes = -1;
+ /**
+ * File-level read state.
+ * When reading from a stream we can't slice a known-size buffer in chunks.
+ * These are constructed sequentially from blocking read. This list stores the
+ * respective Promise status of each chunk.
+ * @type {Promise}
+ */
+
+ this.readStreamState = new DeferredPromise();
+ /**
+ * Bytes transferred from total request size
+ * @type {number}
+ */
+
+ this.loaded = 0;
+ /**
+ * Total request size
+ * @type {number}
+ */
+
+ this.total = 0;
+ /**
+ * Size of a chunk
+ * @type {number}
+ */
+
+ this.chunkSize = this.fileObj.chunkSize;
+ /**
+ * Chunk start byte in a file
+ * @type {number}
+ */
+
+ this.startByte = this.offset * this.chunkSize;
+ /**
+ * A specific filename for this chunk which otherwise default to the main name
+ * @type {string}
+ */
+
+ this.filename = null;
+ /**
+ * Chunk end byte in a file
+ * @type {number}
+ */
+
+ this.endByte = this.computeEndByte();
+ /**
+ * XMLHttpRequest
+ * @type {XMLHttpRequest}
+ */
+
+ this.xhr = null;
+ }
/**
- * Supported by browser?
- * @type {boolean}
+ * Compute the endbyte in a file
+ *
*/
- this.support = (
- typeof File !== 'undefined' &&
- typeof Blob !== 'undefined' &&
- typeof FileList !== 'undefined' &&
- (
- !!Blob.prototype.slice || !!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice ||
- false
- ) // slicing files support
- );
- if (!this.support) {
- return ;
- }
- /**
- * Check if directory upload is supported
- * @type {boolean}
- */
- this.supportDirectory = (
- /Chrome/.test(window.navigator.userAgent) ||
- /Firefox/.test(window.navigator.userAgent) ||
- /Edge/.test(window.navigator.userAgent)
- );
+ _createClass(FlowChunk, [{
+ key: "computeEndByte",
+ value: function computeEndByte() {
+ var endByte = Math.min(this.fileObj.size, (this.offset + 1) * this.chunkSize);
+
+ if (this.fileObj.size - endByte < this.chunkSize && !this.flowObj.opts.forceChunkSize) {
+ // The last chunk will be bigger than the chunk size,
+ // but less than 2 * this.chunkSize
+ endByte = this.fileObj.size;
+ }
+
+ return endByte;
+ }
+ /**
+ * Send chunk event
+ * @param event
+ * @param {...} args arguments of a callback
+ */
+
+ }, {
+ key: "event",
+ value: function event(_event, args) {
+ args = Array.prototype.slice.call(arguments);
+ args.unshift(this);
+ this.fileObj.chunkEvent.apply(this.fileObj, args);
+ }
+ /**
+ * Catch progress event
+ * @param {ProgressEvent} event
+ */
+
+ }, {
+ key: "progressHandler",
+ value: function progressHandler(event) {
+ // console.log(event);
+ if (event.lengthComputable) {
+ this.loaded = event.loaded;
+ this.total = event.total;
+ }
+
+ this.event('progress', event);
+ }
+ /**
+ * Catch test event
+ * @param {Event} event
+ */
+
+ }, {
+ key: "testHandler",
+ value: function testHandler(event) {
+ var status = this.status(true);
+
+ if (status === 'error') {
+ this.event(status, this.message());
+ this.flowObj.uploadNextChunk();
+ } else if (status === 'success') {
+ this.tested = true;
+ this.event(status, this.message());
+ this.flowObj.uploadNextChunk();
+ } else if (!this.fileObj.paused) {
+ // Error might be caused by file pause method
+ // Chunks does not exist on the server side
+ this.tested = true;
+ this.send();
+ }
+ }
+ /**
+ * Upload has stopped
+ * @param {Event} event
+ */
+
+ }, {
+ key: "doneHandler",
+ value: function doneHandler(event) {
+ var _this = this;
+
+ var status = this.status();
+
+ if (status === 'success' || status === 'error') {
+ delete this.data;
+ this.event(status, this.message());
+ this.flowObj.uploadNextChunk();
+ } else if (!this.fileObj.paused) {
+ this.event('retry', this.message());
+ this.pendingRetry = true;
+ this.abort();
+ this.retries++;
+ var retryInterval = this.flowObj.opts.chunkRetryInterval;
+
+ if (retryInterval !== null) {
+ setTimeout(function () {
+ return _this.send();
+ }, retryInterval);
+ } else {
+ this.send();
+ }
+ }
+ }
+ /**
+ * Get params for a request
+ * @function
+ */
+
+ }, {
+ key: "getParams",
+ value: function getParams() {
+ return {
+ flowChunkNumber: this.offset + 1,
+ flowChunkSize: this.chunkSize,
+ flowCurrentChunkSize: this.endByte - this.startByte,
+ flowTotalSize: this.fileObj.size,
+ flowIdentifier: this.fileObj.uniqueIdentifier,
+ flowFilename: this.fileObj.name,
+ flowRelativePath: this.fileObj.relativePath,
+ flowTotalChunks: this.fileObj.chunks.length
+ };
+ }
+ /**
+ * Get target option with query params
+ * @function
+ * @param params
+ * @returns {string}
+ */
+
+ }, {
+ key: "getTarget",
+ value: function getTarget(target, params) {
+ if (params.length == 0) {
+ return target;
+ }
+
+ if (target.indexOf('?') < 0) {
+ target += '?';
+ } else {
+ target += '&';
+ }
+
+ return target + params.join('&');
+ }
+ /**
+ * Makes a GET request without any data to see if the chunk has already
+ * been uploaded in a previous session
+ * @function
+ */
+
+ }, {
+ key: "test",
+ value: function test() {
+ // Set up request and listen for event
+ this.xhr = new XMLHttpRequest();
+ this.xhr.addEventListener("load", this.testHandler.bind(this), false);
+ this.xhr.addEventListener("error", this.testHandler.bind(this), false);
+ var testMethod = evalOpts(this.flowObj.opts.testMethod, this.fileObj, this);
+ var data = this.prepareXhrRequest(testMethod, true);
+ this.xhr.send(data);
+ }
+ /**
+ * Finish preprocess state
+ * @function
+ */
+
+ }, {
+ key: "preprocessFinished",
+ value: function () {
+ var _preprocessFinished = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
+ return regeneratorRuntime.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ // Re-compute the endByte after the preprocess function to allow an
+ // implementer of preprocess to set the fileObj size
+ this.endByte = this.computeEndByte();
+ this.preprocessState = 2;
+ _context.next = 4;
+ return this.send();
+
+ case 4:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ }));
+
+ function preprocessFinished() {
+ return _preprocessFinished.apply(this, arguments);
+ }
+
+ return preprocessFinished;
+ }()
+ /**
+ * Finish read state
+ * @function
+ */
+
+ }, {
+ key: "readFinished",
+ value: function readFinished(payload) {
+ this.readState = 2;
+ this.payload = payload;
+ this.send();
+ }
+ /**
+ * asyncReadFileFn() helper provides the ability of asynchronous read()
+ * Eg: When reading from a ReadableStream.getReader().
+ *
+ * But:
+ * - FlowChunk.send() can be called up to {simultaneousUploads} times.
+ * - Concurrent or misordered read() would result in a corrupted payload.
+ *
+ * This function guards from this: As soon a previous chunk exists and as long as
+ * this previous chunk is not fully read(), we assume corresponding reader is unavailable
+ * and wait for it.
+ * @function
+ */
+
+ }, {
+ key: "readStreamGuard",
+ value: function () {
+ var _readStreamGuard = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
+ var map;
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ map = this.fileObj.chunks.map(function (e) {
+ return e.readStreamState;
+ }).slice(0, this.offset);
+ _context2.prev = 1;
+ _context2.next = 4;
+ return Promise.all(map);
+
+ case 4:
+ _context2.next = 10;
+ break;
+
+ case 6:
+ _context2.prev = 6;
+ _context2.t0 = _context2["catch"](1);
+ console.error("Chunk ".concat(this.offset, ": Error while waiting for ").concat(map.length, " previous chunks being read."));
+ throw _context2.t0;
+
+ case 10:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ }, _callee2, this, [[1, 6]]);
+ }));
+
+ function readStreamGuard() {
+ return _readStreamGuard.apply(this, arguments);
+ }
- /**
- * List of FlowFile objects
- * @type {Array.}
- */
- this.files = [];
+ return readStreamGuard;
+ }()
+ }, {
+ key: "readStreamChunk",
+ value: function () {
+ var _readStreamChunk = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3() {
+ var data, asyncRead;
+ return regeneratorRuntime.wrap(function _callee3$(_context3) {
+ while (1) {
+ switch (_context3.prev = _context3.next) {
+ case 0:
+ if (!this.readStreamState.resolved) {
+ _context3.next = 6;
+ break;
+ }
+
+ if (!(this.payload && this.pendingRetry)) {
+ _context3.next = 4;
+ break;
+ }
+
+ console.info("Retrying chunk ".concat(this.offset, " upload"));
+ return _context3.abrupt("return", this.uploadStreamChunk(this.payload));
+
+ case 4:
+ console.warn("Chunk ".concat(this.offset, " already read. xhr initialized = ").concat(this.xhr ? 1 : 0, ". payload size = ").concat(this.payload ? this.payload.size : null, ". readState = ").concat(this.readState, ". retry = ").concat(this.pendingRetry)); // ... but never try to read that same chunk from the (non-rewindable) stream again or we'd risk
+ // not only misordered chunks but a corrupted file.
+
+ return _context3.abrupt("return", null);
+
+ case 6:
+ this.readState = 1;
+ _context3.next = 9;
+ return this.readStreamGuard();
+
+ case 9:
+ asyncRead = this.flowObj.opts.asyncReadFileFn;
+ _context3.next = 12;
+ return asyncRead(this.fileObj, this.startByte, this.endByte, this.fileObj.file.type, this);
+
+ case 12:
+ data = _context3.sent;
+ this.readStreamState.resolve(); // Equivalent to readFinished()
+
+ this.readState = 2;
+
+ if (data) {
+ this.readBytes = data.size || data.size === 0 ? data.size : -1;
+ }
+
+ return _context3.abrupt("return", this.uploadStreamChunk(data));
+
+ case 17:
+ case "end":
+ return _context3.stop();
+ }
+ }
+ }, _callee3, this);
+ }));
- /**
- * Default options for flow.js
- * @type {Object}
- */
- this.defaults = {
- chunkSize: 1024 * 1024,
- forceChunkSize: false,
- simultaneousUploads: 3,
- singleFile: false,
- fileParameterName: 'file',
- progressCallbacksInterval: 500,
- speedSmoothingFactor: 0.1,
- query: {},
- headers: {},
- withCredentials: false,
- preprocess: null,
- changeRawDataBeforeSend: null,
- method: 'multipart',
- testMethod: 'GET',
- uploadMethod: 'POST',
- prioritizeFirstAndLastChunk: false,
- allowDuplicateUploads: false,
- target: '/',
- testChunks: true,
- generateUniqueIdentifier: null,
- maxChunkRetries: 0,
- chunkRetryInterval: null,
- permanentErrors: [404, 413, 415, 500, 501],
- successStatuses: [200, 201, 202],
- onDropStopPropagation: false,
- initFileFn: null,
- readFileFn: webAPIFileRead
- };
+ function readStreamChunk() {
+ return _readStreamChunk.apply(this, arguments);
+ }
- /**
- * Current options
- * @type {Object}
- */
- this.opts = {};
+ return readStreamChunk;
+ }()
+ }, {
+ key: "uploadStreamChunk",
+ value: function () {
+ var _uploadStreamChunk = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(data) {
+ var lastReadBytes;
+ return regeneratorRuntime.wrap(function _callee4$(_context4) {
+ while (1) {
+ switch (_context4.prev = _context4.next) {
+ case 0:
+ if (!(data && data.size > 0)) {
+ _context4.next = 5;
+ break;
+ }
+
+ if (this.fileObj.chunkSize && data.size > this.fileObj.chunkSize) {
+ // This may imply a miscalculation of the total chunk numbers.
+ console.warn("Chunk ".concat(this.offset, ": returned too much data. Got ").concat(data.size, ". Expected not more than ").concat(this.flowObj.chunkSize, "."));
+ }
+
+ this.payload = data;
+ this.xhrSend(data);
+ return _context4.abrupt("return");
+
+ case 5:
+ if (!(this.offset > 0)) {
+ _context4.next = 13;
+ break;
+ }
+
+ // last size of the buffer read for the previous chunk
+ lastReadBytes = this.fileObj.chunks[this.offset - 1].readBytes;
+
+ if (!(lastReadBytes < parseInt(this.chunkSize))) {
+ _context4.next = 13;
+ break;
+ }
+
+ console.warn("Chunk ".concat(this.offset, " seems superfluous. No byte read() meanwhile previous chunk was only ").concat(lastReadBytes, " bytes instead of ").concat(this.chunkSize)); // The last chunk's buffer wasn't even full. That means the number of chunk may
+ // have been miscomputed and this chunk is superfluous.
+ // We make a fake request so that overall status is "complete" and we can move on
+ // on this FlowFile.
+
+ this.pendingRetry = false;
+ this.xhr = {
+ readyState: 4,
+ status: 200,
+ abort: function abort(e) {
+ return null;
+ }
+ };
+ this.doneHandler(null);
+ return _context4.abrupt("return");
+
+ case 13:
+ console.warn("Chunk ".concat(this.offset, ": no byte to read()"));
+ this.pendingRetry = false;
+
+ case 15:
+ case "end":
+ return _context4.stop();
+ }
+ }
+ }, _callee4, this);
+ }));
- /**
- * List of events:
- * key stands for event name
- * value array list of callbacks
- * @type {}
- */
- this.events = {};
+ function uploadStreamChunk(_x) {
+ return _uploadStreamChunk.apply(this, arguments);
+ }
- var $ = this;
+ return uploadStreamChunk;
+ }()
+ /**
+ * Prepare data (preprocess/read) data then call xhrSend()
+ * @function
+ */
+
+ }, {
+ key: "send",
+ value: function () {
+ var _send = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee5() {
+ var preprocess, read, asyncRead;
+ return regeneratorRuntime.wrap(function _callee5$(_context5) {
+ while (1) {
+ switch (_context5.prev = _context5.next) {
+ case 0:
+ preprocess = this.flowObj.opts.preprocess;
+ read = this.flowObj.opts.readFileFn;
+ asyncRead = this.flowObj.opts.asyncReadFileFn;
+
+ if (!(typeof preprocess === 'function')) {
+ _context5.next = 11;
+ break;
+ }
+
+ _context5.t0 = this.preprocessState;
+ _context5.next = _context5.t0 === 0 ? 7 : _context5.t0 === 1 ? 10 : 11;
+ break;
+
+ case 7:
+ this.preprocessState = 1;
+ preprocess(this);
+ return _context5.abrupt("return");
+
+ case 10:
+ return _context5.abrupt("return");
+
+ case 11:
+ if (!asyncRead) {
+ _context5.next = 15;
+ break;
+ }
+
+ _context5.next = 14;
+ return this.readStreamChunk();
+
+ case 14:
+ return _context5.abrupt("return");
+
+ case 15:
+ _context5.t1 = this.readState;
+ _context5.next = _context5.t1 === 0 ? 18 : _context5.t1 === 1 ? 21 : 22;
+ break;
+
+ case 18:
+ this.readState = 1;
+ read(this.fileObj, this.startByte, this.endByte, this.fileObj.file.type, this);
+ return _context5.abrupt("return");
+
+ case 21:
+ return _context5.abrupt("return");
+
+ case 22:
+ this.xhrSend(this.payload);
+
+ case 23:
+ case "end":
+ return _context5.stop();
+ }
+ }
+ }, _callee5, this);
+ }));
- /**
- * On drop event
- * @function
- * @param {MouseEvent} event
- */
- this.onDrop = function (event) {
- if ($.opts.onDropStopPropagation) {
- event.stopPropagation();
- }
- event.preventDefault();
- var dataTransfer = event.dataTransfer;
- if (dataTransfer.items && dataTransfer.items[0] &&
- dataTransfer.items[0].webkitGetAsEntry) {
- $.webkitReadDataTransfer(event);
- } else {
- $.addFiles(dataTransfer.files, event);
- }
- };
+ function send() {
+ return _send.apply(this, arguments);
+ }
- /**
- * Prevent default
- * @function
- * @param {MouseEvent} event
- */
- this.preventEvent = function (event) {
- event.preventDefault();
- };
+ return send;
+ }()
+ /**
+ * Actually uploads data in a POST call
+ * @function
+ */
+
+ }, {
+ key: "xhrSend",
+ value: function xhrSend(payload) {
+ if (this.flowObj.opts.testChunks && !this.tested) {
+ this.test();
+ return;
+ }
+ this.loaded = 0;
+ this.total = 0;
+ this.pendingRetry = false; // Set up request and listen for event
- /**
- * Current options
- * @type {Object}
- */
- this.opts = Flow.extend({}, this.defaults, opts || {});
+ this.xhr = new XMLHttpRequest();
+ this.xhr.upload.addEventListener('progress', this.progressHandler.bind(this), false);
+ this.xhr.addEventListener('load', this.doneHandler.bind(this), false);
+ this.xhr.addEventListener('error', this.doneHandler.bind(this), false);
+ var uploadMethod = evalOpts(this.flowObj.opts.uploadMethod, this.fileObj, this);
+ var xhrPayload = this.prepareXhrRequest(uploadMethod, false, this.flowObj.opts.method, payload);
+ var changeRawDataBeforeSend = this.flowObj.opts.changeRawDataBeforeSend;
- }
+ if (typeof changeRawDataBeforeSend === 'function') {
+ xhrPayload = changeRawDataBeforeSend(this, xhrPayload);
+ }
- Flow.prototype = {
- /**
- * Set a callback for an event, possible events:
- * fileSuccess(file), fileProgress(file), fileAdded(file, event),
- * fileRemoved(file), fileRetry(file), fileError(file, message),
- * complete(), progress(), error(message, file), pause()
- * @function
- * @param {string} event
- * @param {Function} callback
- */
- on: function (event, callback) {
- event = event.toLowerCase();
- if (!this.events.hasOwnProperty(event)) {
- this.events[event] = [];
+ this.xhr.send(xhrPayload);
}
- this.events[event].push(callback);
- },
+ /**
+ * Abort current xhr request
+ * @function
+ */
+
+ }, {
+ key: "abort",
+ value: function abort() {
+ if (this.xhr) {
+ this.xhr.abort();
+ }
- /**
- * Remove event callback
- * @function
- * @param {string} [event] removes all events if not specified
- * @param {Function} [fn] removes all callbacks of event if not specified
- */
- off: function (event, fn) {
- if (event !== undefined) {
- event = event.toLowerCase();
- if (fn !== undefined) {
- if (this.events.hasOwnProperty(event)) {
- arrayRemove(this.events[event], fn);
+ this.xhr = null;
+ }
+ /**
+ * Retrieve current chunk upload status
+ * @function
+ * @returns {string} 'pending', 'uploading', 'success', 'error'
+ */
+
+ }, {
+ key: "status",
+ value: function status(isTest) {
+ if (this.readState === 1) {
+ return 'reading';
+ } else if (this.preprocessState === 1) {
+ // if pending retry then that's effectively the same as actively uploading,
+ // there might just be a slight delay before the retry starts
+ return 'uploading';
+ } else if (!this.xhr || this.pendingRetry) {
+ return 'pending';
+ } else if (this.xhr.readyState < 4) {
+ // Status is really 'OPENED', 'HEADERS_RECEIVED'
+ // or 'LOADING' - meaning that stuff is happening
+ return 'uploading';
+ } else {
+ if (this.flowObj.opts.successStatuses.indexOf(this.xhr.status) > -1) {
+ // HTTP 200, perfect
+ // HTTP 202 Accepted - The request has been accepted for processing, but the processing has not been completed.
+ return 'success';
+ } else if (this.flowObj.opts.permanentErrors.indexOf(this.xhr.status) > -1 || !isTest && this.retries >= this.flowObj.opts.maxChunkRetries) {
+ // HTTP 413/415/500/501, permanent error
+ return 'error';
+ } else {
+ // this should never happen, but we'll reset and queue a retry
+ // a likely case for this would be 503 service unavailable
+ this.abort();
+ return 'pending';
}
+ }
+ }
+ /**
+ * Get response from xhr request
+ * @function
+ * @returns {String}
+ */
+
+ }, {
+ key: "message",
+ value: function message() {
+ return this.xhr ? this.xhr.responseText : '';
+ }
+ /**
+ * Get upload progress
+ * @function
+ * @returns {number}
+ */
+
+ }, {
+ key: "progress",
+ value: function progress() {
+ if (this.pendingRetry) {
+ return 0;
+ }
+
+ var s = this.status();
+
+ if (s === 'success' || s === 'error') {
+ return 1;
+ } else if (s === 'pending') {
+ return 0;
} else {
- delete this.events[event];
+ return this.total > 0 ? this.loaded / this.total : 0;
}
- } else {
- this.events = {};
}
- },
+ /**
+ * Count total size uploaded
+ * @function
+ * @returns {number}
+ */
+
+ }, {
+ key: "sizeUploaded",
+ value: function sizeUploaded() {
+ var size = this.endByte - this.startByte; // can't return only chunk.loaded value, because it is bigger than chunk size
+
+ if (this.status() !== 'success') {
+ size = this.progress() * size;
+ }
- /**
- * Fire an event
- * @function
- * @param {string} event event name
- * @param {...} args arguments of a callback
- * @return {bool} value is false if at least one of the event handlers which handled this event
- * returned false. Otherwise it returns true.
- */
- fire: function (event, args) {
- // `arguments` is an object, not array, in FF, so:
- args = Array.prototype.slice.call(arguments);
- event = event.toLowerCase();
- var preventDefault = false;
- if (this.events.hasOwnProperty(event)) {
- each(this.events[event], function (callback) {
- preventDefault = callback.apply(this, args.slice(1)) === false || preventDefault;
- }, this);
+ return size;
}
- if (event != 'catchall') {
- args.unshift('catchAll');
- preventDefault = this.fire.apply(this, args) === false || preventDefault;
+ /**
+ * Prepare Xhr request. Set query, headers and data
+ * @param {string} method GET or POST
+ * @param {bool} isTest is this a test request
+ * @param {string} [paramsMethod] octet or form
+ * @param {Blob} [blob] to send
+ * @returns {FormData|Blob|Null} data to send
+ */
+
+ }, {
+ key: "prepareXhrRequest",
+ value: function prepareXhrRequest(method, isTest, paramsMethod, blob) {
+ // Add data from the query options
+ var query = evalOpts(this.flowObj.opts.query, this.fileObj, this, isTest);
+ query = Object.assign({}, query || {}, this.getParams());
+ var target = evalOpts(this.flowObj.opts.target, this.fileObj, this, isTest);
+ var data = null;
+
+ if (method === 'GET' || paramsMethod === 'octet') {
+ // Add data from the query options
+ var params = [];
+ each(query, function (v, k) {
+ params.push([encodeURIComponent(k), encodeURIComponent(v)].join('='));
+ });
+ target = this.getTarget(target, params);
+ data = blob || null;
+ } else {
+ // Add data from the query options
+ data = new FormData();
+ each(query, function (v, k) {
+ data.append(k, v);
+ });
+
+ if (typeof blob !== "undefined") {
+ data.append(this.flowObj.opts.fileParameterName, blob, this.filename || this.fileObj.file.name);
+ }
+ }
+
+ this.xhr.open(method, target, true);
+ this.xhr.withCredentials = this.flowObj.opts.withCredentials; // Add data from header options
+
+ each(evalOpts(this.flowObj.opts.headers, this.fileObj, this, isTest), function (v, k) {
+ this.xhr.setRequestHeader(k, v);
+ }, this);
+ return data;
}
- return !preventDefault;
- },
+ }]);
+
+ return FlowChunk;
+ }();
+
+ /**
+ * FlowFile class
+ * @name FlowFile
+ * @param {Flow} flowObj
+ * @param {File} file
+ * @param {string} uniqueIdentifier
+ * @constructor
+ */
+ var FlowFile = /*#__PURE__*/function () {
+ function FlowFile(flowObj, file, uniqueIdentifier) {
+ _classCallCheck(this, FlowFile);
+
+ /**
+ * Reference to parent Flow instance
+ * @type {Flow}
+ */
+ this.flowObj = flowObj;
+ /**
+ * Reference to file
+ * @type {File}
+ */
+
+ this.file = file;
+ /**
+ * File name. Some confusion in different versions of Firefox
+ * @type {string}
+ */
+
+ this.name = file.fileName || file.name;
+ /**
+ * File size
+ * @type {number}
+ */
+
+ this.size = file.size;
+ /**
+ * Relative file path
+ * @type {string}
+ */
+
+ this.relativePath = file.relativePath || file.webkitRelativePath || this.name;
+ /**
+ * File unique identifier
+ * @type {string}
+ */
+
+ this.uniqueIdentifier = uniqueIdentifier === undefined ? flowObj.generateUniqueIdentifier(file) : uniqueIdentifier;
+ /**
+ * Size of Each Chunk
+ * @type {number}
+ */
+
+ this.chunkSize = 0;
+ /**
+ * List of chunks
+ * @type {Array.}
+ */
+
+ this.chunks = [];
+ /**
+ * Indicated if file is paused
+ * @type {boolean}
+ */
+
+ this.paused = false;
+ /**
+ * Indicated if file has encountered an error
+ * @type {boolean}
+ */
+
+ this.error = false;
+ /**
+ * Average upload speed
+ * @type {number}
+ */
+
+ this.averageSpeed = 0;
+ /**
+ * Current upload speed
+ * @type {number}
+ */
+
+ this.currentSpeed = 0;
+ /**
+ * Date then progress was called last time
+ * @type {number}
+ * @private
+ */
+
+ this._lastProgressCallback = Date.now();
+ /**
+ * Previously uploaded file size
+ * @type {number}
+ * @private
+ */
+
+ this._prevUploadedSize = 0;
+ /**
+ * Holds previous progress
+ * @type {number}
+ * @private
+ */
+
+ this._prevProgress = 0;
+ }
/**
- * Read webkit dataTransfer object
- * @param event
+ * Update speed parameters
+ * @link http://stackoverflow.com/questions/2779600/how-to-estimate-download-time-remaining-accurately
+ * @function
*/
- webkitReadDataTransfer: function (event) {
- var $ = this;
- var queue = event.dataTransfer.items.length;
- var files = [];
- each(event.dataTransfer.items, function (item) {
- var entry = item.webkitGetAsEntry();
- if (!entry) {
- decrement();
- return ;
+
+
+ _createClass(FlowFile, [{
+ key: "measureSpeed",
+ value: function measureSpeed() {
+ var timeSpan = Date.now() - this._lastProgressCallback;
+
+ if (!timeSpan) {
+ return;
}
- if (entry.isFile) {
- // due to a bug in Chrome's File System API impl - #149735
- fileReadSuccess(item.getAsFile(), entry.fullPath);
- } else {
- readDirectory(entry.createReader());
+
+ var smoothingFactor = this.flowObj.opts.speedSmoothingFactor;
+ var uploaded = this.sizeUploaded(); // Prevent negative upload speed after file upload resume
+
+ this.currentSpeed = Math.max((uploaded - this._prevUploadedSize) / timeSpan * 1000, 0);
+ this.averageSpeed = smoothingFactor * this.currentSpeed + (1 - smoothingFactor) * this.averageSpeed;
+ this._prevUploadedSize = uploaded;
+ }
+ /**
+ * For internal usage only.
+ * Callback when something happens within the chunk.
+ * @function
+ * @param {FlowChunk} chunk
+ * @param {string} event can be 'progress', 'success', 'error' or 'retry'
+ * @param {string} [message]
+ */
+
+ }, {
+ key: "chunkEvent",
+ value: function chunkEvent(chunk, event, message) {
+ switch (event) {
+ case 'progress':
+ if (Date.now() - this._lastProgressCallback < this.flowObj.opts.progressCallbacksInterval) {
+ break;
+ }
+
+ this.measureSpeed();
+ this.flowObj.emit('file-progress', this, chunk);
+ this.flowObj.emit('progress');
+ this._lastProgressCallback = Date.now();
+ break;
+
+ case 'error':
+ this.error = true;
+ this.abort(true);
+ this.flowObj.emit('file-error', this, message, chunk);
+ this.flowObj.emit('error', message, this, chunk);
+ break;
+
+ case 'success':
+ if (this.error) {
+ return;
+ }
+
+ this.measureSpeed();
+ this.flowObj.emit('file-progress', this, chunk);
+ this.flowObj.emit('progress');
+ this._lastProgressCallback = Date.now();
+
+ if (this.isComplete()) {
+ this.currentSpeed = 0;
+ this.averageSpeed = 0;
+ this.flowObj.emit('file-success', this, message, chunk);
+ }
+
+ break;
+
+ case 'retry':
+ this.flowObj.emit('file-retry', this, chunk);
+ break;
}
- });
- function readDirectory(reader) {
- reader.readEntries(function (entries) {
- if (entries.length) {
- queue += entries.length;
- each(entries, function(entry) {
- if (entry.isFile) {
- var fullPath = entry.fullPath;
- entry.file(function (file) {
- fileReadSuccess(file, fullPath);
- }, readError);
- } else if (entry.isDirectory) {
- readDirectory(entry.createReader());
- }
- });
- readDirectory(reader);
- } else {
- decrement();
+ }
+ /**
+ * Pause file upload
+ * @function
+ */
+
+ }, {
+ key: "pause",
+ value: function pause() {
+ this.paused = true;
+ this.abort();
+ }
+ /**
+ * Resume file upload
+ * @function
+ */
+
+ }, {
+ key: "resume",
+ value: function resume() {
+ this.paused = false;
+ this.flowObj.upload();
+ }
+ /**
+ * Abort current upload
+ * @function
+ */
+
+ }, {
+ key: "abort",
+ value: function abort(reset) {
+ this.currentSpeed = 0;
+ this.averageSpeed = 0;
+
+ if (reset) {
+ this.chunks = [];
+ }
+
+ var _iterator = _createForOfIteratorHelper(this.chunks),
+ _step;
+
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ var c = _step.value;
+
+ if (c.status() === 'uploading') {
+ c.abort();
+ c.pendingRetry = true;
+ this.flowObj.uploadNextChunk();
+ }
}
- }, readError);
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
}
- function fileReadSuccess(file, fullPath) {
- // relative path should not start with "/"
- file.relativePath = fullPath.substring(1);
- files.push(file);
- decrement();
+ /**
+ * Cancel current upload and remove from a list
+ * @function
+ */
+
+ }, {
+ key: "cancel",
+ value: function cancel() {
+ this.flowObj.removeFile(this);
}
- function readError(fileError) {
- decrement();
- throw fileError;
+ /**
+ * Retry aborted file upload
+ * @function
+ */
+
+ }, {
+ key: "retry",
+ value: function retry() {
+ this.bootstrap('retry');
+ this.flowObj.upload();
}
- function decrement() {
- if (--queue == 0) {
- $.addFiles(files, event);
+ /**
+ * Clear current chunks and slice file again
+ * @function
+ */
+
+ }, {
+ key: "bootstrap",
+ value: function bootstrap() {
+ var initFileFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.flowObj.opts.initFileFn;
+
+ if (typeof initFileFn === "function") {
+ initFileFn(this);
}
+
+ this._bootstrap();
}
- },
+ }, {
+ key: "_bootstrap",
+ value: function _bootstrap() {
+ this.abort(true);
+ this.error = false; // Rebuild stack of chunks from file
+
+ this._prevProgress = 0;
+ var round = this.flowObj.opts.forceChunkSize ? Math.ceil : Math.floor;
+ this.chunkSize = evalOpts(this.flowObj.opts.chunkSize, this);
+ var chunks = Math.max(round(this.size / this.chunkSize), 1);
+
+ for (var offset = 0; offset < chunks; offset++) {
+ this.chunks.push(new FlowChunk(this.flowObj, this, offset));
+ }
+ }
+ /**
+ * Get current upload progress status
+ * @function
+ * @returns {number} from 0 to 1
+ */
+
+ }, {
+ key: "progress",
+ value: function progress() {
+ if (this.error) {
+ return 1;
+ }
- /**
- * Generate unique identifier for a file
- * @function
- * @param {FlowFile} file
- * @returns {string}
- */
- generateUniqueIdentifier: function (file) {
- var custom = this.opts.generateUniqueIdentifier;
- if (typeof custom === 'function') {
- return custom(file);
- }
- // Some confusion in different versions of Firefox
- var relativePath = file.relativePath || file.webkitRelativePath || file.fileName || file.name;
- return file.size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, '');
- },
+ if (this.chunks.length === 1) {
+ this._prevProgress = Math.max(this._prevProgress, this.chunks[0].progress());
+ return this._prevProgress;
+ } // Sum up progress across everything
- /**
- * Upload next chunk from the queue
- * @function
- * @returns {boolean}
- * @private
- */
- uploadNextChunk: function (preventEvents) {
- // In some cases (such as videos) it's really handy to upload the first
- // and last chunk of a file quickly; this let's the server check the file's
- // metadata and determine if there's even a point in continuing.
- var found = false;
- if (this.opts.prioritizeFirstAndLastChunk) {
- each(this.files, function (file) {
- if (!file.paused && file.chunks.length &&
- file.chunks[0].status() === 'pending') {
- file.chunks[0].send();
- found = true;
+
+ var bytesLoaded = 0;
+ each(this.chunks, function (c) {
+ // get chunk progress relative to entire file
+ bytesLoaded += c.progress() * (c.endByte - c.startByte);
+ });
+ var percent = bytesLoaded / this.size; // We don't want to lose percentages when an upload is paused
+
+ this._prevProgress = Math.max(this._prevProgress, percent > 0.9999 ? 1 : percent);
+ return this._prevProgress;
+ }
+ /**
+ * Indicates if file is being uploaded at the moment
+ * @function
+ * @returns {boolean}
+ */
+
+ }, {
+ key: "isUploading",
+ value: function isUploading() {
+ var uploading = false;
+ each(this.chunks, function (chunk) {
+ if (chunk.status() === 'uploading') {
+ uploading = true;
return false;
}
- if (!file.paused && file.chunks.length > 1 &&
- file.chunks[file.chunks.length - 1].status() === 'pending') {
- file.chunks[file.chunks.length - 1].send();
- found = true;
+ });
+ return uploading;
+ }
+ /**
+ * Indicates if file is has finished uploading and received a response
+ * @function
+ * @returns {boolean}
+ */
+
+ }, {
+ key: "isComplete",
+ value: function isComplete() {
+ var outstanding = false;
+ each(this.chunks, function (chunk) {
+ var status = chunk.status();
+
+ if (status === 'pending' || status === 'uploading' || status === 'reading' || chunk.preprocessState === 1 || chunk.readState === 1) {
+ outstanding = true;
return false;
}
});
- if (found) {
- return found;
- }
+ return !outstanding;
}
-
- // Now, simply look for the next, best thing to upload
- each(this.files, function (file) {
- if (!file.paused) {
- each(file.chunks, function (chunk) {
- if (chunk.status() === 'pending') {
- chunk.send();
- found = true;
- return false;
- }
- });
+ /**
+ * Count total size uploaded
+ * @function
+ * @returns {number}
+ */
+
+ }, {
+ key: "sizeUploaded",
+ value: function sizeUploaded() {
+ var size = 0;
+ each(this.chunks, function (chunk) {
+ size += chunk.sizeUploaded();
+ });
+ return size;
+ }
+ /**
+ * Returns remaining time to finish upload file in seconds. Accuracy is based on average speed.
+ * If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
+ * @function
+ * @returns {number}
+ */
+
+ }, {
+ key: "timeRemaining",
+ value: function timeRemaining() {
+ if (this.paused || this.error) {
+ return 0;
}
- if (found) {
- return false;
+
+ var delta = this.size - this.sizeUploaded();
+
+ if (delta && !this.averageSpeed) {
+ return Number.POSITIVE_INFINITY;
}
- });
- if (found) {
- return true;
- }
- // The are no more outstanding chunks to upload, check is everything is done
- var outstanding = false;
- each(this.files, function (file) {
- if (!file.isComplete()) {
- outstanding = true;
- return false;
+ if (!delta && !this.averageSpeed) {
+ return 0;
}
- });
- if (!outstanding && !preventEvents) {
- // All chunks have been uploaded, complete
- async(function () {
- this.fire('complete');
- }, this);
+
+ return Math.floor(delta / this.averageSpeed);
}
- return false;
- },
+ /**
+ * Get file type
+ * @function
+ * @returns {string}
+ */
+
+ }, {
+ key: "getType",
+ value: function getType() {
+ return this.file.type && this.file.type.split('/')[1];
+ }
+ /**
+ * Get file extension
+ * @function
+ * @returns {string}
+ */
+
+ }, {
+ key: "getExtension",
+ value: function getExtension() {
+ return this.name.substr((~-this.name.lastIndexOf(".") >>> 0) + 2).toLowerCase();
+ }
+ }]);
+ return FlowFile;
+ }();
+ var g$1 = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+ g$1.FlowFile = FlowFile;
- /**
- * Assign a browse action to one or more DOM nodes.
- * @function
- * @param {Element|Array.} domNodes
- * @param {boolean} isDirectory Pass in true to allow directories to
- * @param {boolean} singleFile prevent multi file upload
- * @param {Object} attributes set custom attributes:
- * http://www.w3.org/TR/html-markup/input.file.html#input.file-attributes
- * eg: accept: 'image/*'
- * be selected (Chrome only).
- */
- assignBrowse: function (domNodes, isDirectory, singleFile, attributes) {
- if (domNodes instanceof Element) {
- domNodes = [domNodes];
- }
+ /**
+ * AsyncFlowFile class
+ * @name AsyncFlowFile
+ */
- each(domNodes, function (domNode) {
- var input;
- if (domNode.tagName === 'INPUT' && domNode.type === 'file') {
- input = domNode;
- } else {
- input = document.createElement('input');
- input.setAttribute('type', 'file');
- // display:none - not working in opera 12
- extend(input.style, {
- visibility: 'hidden',
- position: 'absolute',
- width: '1px',
- height: '1px'
- });
- // for opera 12 browser, input must be assigned to a document
- domNode.appendChild(input);
- // https://developer.mozilla.org/en/using_files_from_web_applications)
- // event listener is executed two times
- // first one - original mouse click event
- // second - input.click(), input is inside domNode
- domNode.addEventListener('click', function() {
- input.click();
- }, false);
- }
- if (!this.opts.singleFile && !singleFile) {
- input.setAttribute('multiple', 'multiple');
- }
- if (isDirectory) {
- input.setAttribute('webkitdirectory', 'webkitdirectory');
- }
- each(attributes, function (value, key) {
- input.setAttribute(key, value);
- });
- // When new files are added, simply append them to the overall list
- var $ = this;
- input.addEventListener('change', function (e) {
- if (e.target.value) {
- $.addFiles(e.target.files, e);
- e.target.value = '';
- }
- }, false);
- }, this);
- },
+ var AsyncFlowFile = /*#__PURE__*/function (_FlowFile) {
+ _inherits(AsyncFlowFile, _FlowFile);
- /**
- * Assign one or more DOM nodes as a drop target.
- * @function
- * @param {Element|Array.} domNodes
- */
- assignDrop: function (domNodes) {
- if (typeof domNodes.length === 'undefined') {
- domNodes = [domNodes];
- }
- each(domNodes, function (domNode) {
- domNode.addEventListener('dragover', this.preventEvent, false);
- domNode.addEventListener('dragenter', this.preventEvent, false);
- domNode.addEventListener('drop', this.onDrop, false);
- }, this);
- },
+ var _super = _createSuper(AsyncFlowFile);
- /**
- * Un-assign drop event from DOM nodes
- * @function
- * @param domNodes
- */
- unAssignDrop: function (domNodes) {
- if (typeof domNodes.length === 'undefined') {
- domNodes = [domNodes];
- }
- each(domNodes, function (domNode) {
- domNode.removeEventListener('dragover', this.preventEvent);
- domNode.removeEventListener('dragenter', this.preventEvent);
- domNode.removeEventListener('drop', this.onDrop);
- }, this);
- },
+ function AsyncFlowFile() {
+ _classCallCheck(this, AsyncFlowFile);
- /**
- * Returns a boolean indicating whether or not the instance is currently
- * uploading anything.
- * @function
- * @returns {boolean}
- */
- isUploading: function () {
- var uploading = false;
- each(this.files, function (file) {
- if (file.isUploading()) {
- uploading = true;
- return false;
+ return _super.apply(this, arguments);
+ }
+
+ _createClass(AsyncFlowFile, [{
+ key: "retry",
+
+ /**
+ * Retry aborted file upload
+ * @function
+ */
+ value: function () {
+ var _retry = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
+ return regeneratorRuntime.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ _context.next = 2;
+ return this.bootstrap('retry');
+
+ case 2:
+ return _context.abrupt("return", this.flowObj.upload());
+
+ case 3:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ }));
+
+ function retry() {
+ return _retry.apply(this, arguments);
}
- });
- return uploading;
- },
- /**
- * should upload next chunk
- * @function
- * @returns {boolean|number}
- */
- _shouldUploadNext: function () {
- var num = 0;
- var should = true;
- var simultaneousUploads = this.opts.simultaneousUploads;
- each(this.files, function (file) {
- each(file.chunks, function(chunk) {
- if (chunk.status() === 'uploading') {
- num++;
- if (num >= simultaneousUploads) {
- should = false;
- return false;
+ return retry;
+ }()
+ }, {
+ key: "bootstrap",
+ value: function () {
+ var _bootstrap = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2() {
+ var event,
+ initFileFn,
+ _args2 = arguments;
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ event = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : null;
+ initFileFn = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : this.flowObj.opts.initFileFn;
+
+ if (!(typeof initFileFn === 'function')) {
+ _context2.next = 5;
+ break;
+ }
+
+ _context2.next = 5;
+ return initFileFn(this, event);
+
+ case 5:
+ this._bootstrap();
+
+ if (event !== 'retry') {
+ this.flowObj.hook('file-added', this, event);
+ } // console.log("Flowfile returns [async]", this._bootstrapped);
+
+
+ return _context2.abrupt("return", this);
+
+ case 8:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ }, _callee2, this);
+ }));
+
+ function bootstrap() {
+ return _bootstrap.apply(this, arguments);
+ }
+
+ return bootstrap;
+ }()
+ /**
+ * Indicates if string is being read at the moment
+ * @function
+ * @returns {boolean}
+ */
+
+ }, {
+ key: "isReading",
+ value: function isReading() {
+ var _iterator = _createForOfIteratorHelper(this.chunks),
+ _step;
+
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ var chunk = _step.value;
+
+ if (chunk.status() === 'reading') {
+ return true;
}
}
- });
- });
- // if should is true then return uploading chunks's length
- return should && num;
- },
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
- /**
- * Start or resume uploading.
- * @function
- */
- upload: function () {
- // Make sure we don't start too many uploads at once
- var ret = this._shouldUploadNext();
- if (ret === false) {
- return;
+ return false;
}
- // Kick off the queue
- this.fire('uploadStart');
- var started = false;
- for (var num = 1; num <= this.opts.simultaneousUploads - ret; num++) {
- started = this.uploadNextChunk(true) || started;
- }
- if (!started) {
- async(function () {
- this.fire('complete');
- }, this);
- }
- },
+ }]);
+
+ return AsyncFlowFile;
+ }(FlowFile);
+
+ /**
+ * Flow.js is a library providing multiple simultaneous, stable and
+ * resumable uploads via the HTML5 File API.
+ * @param [opts]
+ * @param {number|Function} [opts.chunkSize]
+ * @param {bool} [opts.forceChunkSize]
+ * @param {number} [opts.simultaneousUploads]
+ * @param {bool} [opts.singleFile]
+ * @param {string} [opts.fileParameterName]
+ * @param {number} [opts.progressCallbacksInterval]
+ * @param {number} [opts.speedSmoothingFactor]
+ * @param {Object|Function} [opts.query]
+ * @param {Object|Function} [opts.headers]
+ * @param {bool} [opts.withCredentials]
+ * @param {Function} [opts.preprocess]
+ * @param {string} [opts.method]
+ * @param {string|Function} [opts.testMethod]
+ * @param {string|Function} [opts.uploadMethod]
+ * @param {bool} [opts.prioritizeFirstAndLastChunk]
+ * @param {bool} [opts.allowDuplicateUploads]
+ * @param {string|Function} [opts.target]
+ * @param {number} [opts.maxChunkRetries]
+ * @param {number} [opts.chunkRetryInterval]
+ * @param {Array.} [opts.permanentErrors]
+ * @param {Array.} [opts.successStatuses]
+ * @param {Function} [opts.initFileFn]
+ * @param {Function} [opts.readFileFn]
+ * @param {Function} [opts.asyncReadFileFn]
+ * @param {Function} [opts.generateUniqueIdentifier]
+ * @constructor
+ */
- /**
- * Resume uploading.
- * @function
- */
- resume: function () {
- each(this.files, function (file) {
- if (!file.isComplete()) {
- file.resume();
- }
- });
- },
+ var Flow = /*#__PURE__*/function (_Eventizer) {
+ _inherits(Flow, _Eventizer);
- /**
- * Pause uploading.
- * @function
- */
- pause: function () {
- each(this.files, function (file) {
- file.pause();
- });
- },
+ var _super = _createSuper(Flow);
/**
- * Cancel upload of all FlowFile objects and remove them from the list.
- * @function
+ * For the events object:
+ * - keys: stands for event name
+ * - values: array list of callbacks
+ * All keys are lowercased as on() would do.
*/
- cancel: function () {
- for (var i = this.files.length - 1; i >= 0; i--) {
- this.files[i].cancel();
- }
- },
-
+ function Flow(opts, events) {
+ var _this;
+
+ _classCallCheck(this, Flow);
+
+ _this = _super.call(this, events);
+ /**
+ * Library version
+ * @type {string}
+ */
+
+ Flow.version = '3.0.0-alpha.0';
+ /**
+ * Check if directory upload is supported
+ * @type {boolean}
+ */
+
+ _this.supportDirectory = /Chrome/.test(window.navigator.userAgent) || /Firefox/.test(window.navigator.userAgent) || /Edge/.test(window.navigator.userAgent);
+ /**
+ * List of FlowFile objects
+ * @type {Array.}
+ */
+
+ _this.files = [];
+ /**
+ * Default options for flow.js
+ * @type {Object}
+ */
+
+ _this.defaults = {
+ chunkSize: 1024 * 1024,
+ forceChunkSize: false,
+ simultaneousUploads: 3,
+ singleFile: false,
+ fileParameterName: 'file',
+ progressCallbacksInterval: 500,
+ speedSmoothingFactor: 0.1,
+ query: {},
+ headers: {},
+ withCredentials: false,
+ preprocess: null,
+ changeRawDataBeforeSend: null,
+ method: 'multipart',
+ testMethod: 'GET',
+ uploadMethod: 'POST',
+ prioritizeFirstAndLastChunk: false,
+ allowDuplicateUploads: false,
+ target: '/',
+ testChunks: true,
+ generateUniqueIdentifier: null,
+ maxChunkRetries: 0,
+ chunkRetryInterval: null,
+ permanentErrors: [404, 413, 415, 500, 501],
+ successStatuses: [200, 201, 202],
+ onDropStopPropagation: false,
+ initFileFn: null,
+ readFileFn: webAPIFileRead,
+ asyncReadFileFn: null
+ };
+ /**
+ * Current options
+ * @type {Object}
+ */
+
+ _this.opts = {};
+ /**
+ * Current options
+ * @type {Object}
+ */
+
+ _this.opts = Object.assign({}, _this.defaults, opts || {}); // A workaround for using this.method.bind(this) as a (removable) event handler.
+ // https://stackoverflow.com/questions/11565471
+
+ _this._onDropBound = null;
+ return _this;
+ }
/**
- * Returns a number between 0 and 1 indicating the current upload progress
- * of all files.
+ * On drop event
* @function
- * @returns {number}
+ * @param {MouseEvent} event
*/
- progress: function () {
- var totalDone = 0;
- var totalSize = 0;
- // Resume all chunks currently being uploaded
- each(this.files, function (file) {
- totalDone += file.progress() * file.size;
- totalSize += file.size;
- });
- return totalSize > 0 ? totalDone / totalSize : 0;
- },
- /**
- * Add a HTML5 File object to the list of files.
- * @function
- * @param {File} file
- * @param {Event} [event] event is optional
- */
- addFile: function (file, event) {
- this.addFiles([file], event);
- },
- /**
- * Add a HTML5 File object to the list of files.
- * @function
- * @param {FileList|Array} fileList
- * @param {Event} [event] event is optional
- */
- addFiles: function (fileList, event) {
- var files = [];
- each(fileList, function (file) {
- // https://github.com/flowjs/flow.js/issues/55
- if ((!ie10plus || ie10plus && file.size > 0) && !(file.size % 4096 === 0 && (file.name === '.' || file.fileName === '.'))) {
- var uniqueIdentifier = this.generateUniqueIdentifier(file);
- if (this.opts.allowDuplicateUploads || !this.getFromUniqueIdentifier(uniqueIdentifier)) {
- var f = new FlowFile(this, file, uniqueIdentifier);
- if (this.fire('fileAdded', f, event)) {
- files.push(f);
- }
- }
+ _createClass(Flow, [{
+ key: "onDrop",
+ value: function onDrop(event) {
+ if (this.opts.onDropStopPropagation) {
+ event.stopPropagation();
}
- }, this);
- if (this.fire('filesAdded', files, event)) {
- each(files, function (file) {
- if (this.opts.singleFile && this.files.length > 0) {
- this.removeFile(this.files[0]);
- }
- this.files.push(file);
- }, this);
- this.fire('filesSubmitted', files, event);
- }
- },
+ event.preventDefault();
+ var dataTransfer = event.dataTransfer;
- /**
- * Cancel upload of a specific FlowFile object from the list.
- * @function
- * @param {FlowFile} file
- */
- removeFile: function (file) {
- for (var i = this.files.length - 1; i >= 0; i--) {
- if (this.files[i] === file) {
- this.files.splice(i, 1);
- file.abort();
- this.fire('fileRemoved', file);
+ if (dataTransfer.items && dataTransfer.items[0] && dataTransfer.items[0].webkitGetAsEntry) {
+ this.webkitReadDataTransfer(event);
+ } else {
+ this.addFiles(dataTransfer.files, event);
}
}
- },
+ /**
+ * On drop event when file/stream initialization is asynchronous
+ * @function
+ * @param {MouseEvent} event
+ */
+
+ }, {
+ key: "asyncOnDrop",
+ value: function () {
+ var _asyncOnDrop = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(event) {
+ var dataTransfer;
+ return regeneratorRuntime.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ if (this.opts.onDropStopPropagation) {
+ event.stopPropagation();
+ }
+
+ event.preventDefault();
+ dataTransfer = event.dataTransfer;
+
+ if (!(dataTransfer.items && dataTransfer.items[0] && dataTransfer.items[0].webkitGetAsEntry)) {
+ _context.next = 7;
+ break;
+ }
+
+ this.webkitReadDataTransfer(event);
+ _context.next = 9;
+ break;
+
+ case 7:
+ _context.next = 9;
+ return this.asyncAddFiles(dataTransfer.files, event);
+
+ case 9:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee, this);
+ }));
- /**
- * Look up a FlowFile object by its unique identifier.
- * @function
- * @param {string} uniqueIdentifier
- * @returns {boolean|FlowFile} false if file was not found
- */
- getFromUniqueIdentifier: function (uniqueIdentifier) {
- var ret = false;
- each(this.files, function (file) {
- if (file.uniqueIdentifier === uniqueIdentifier) {
- ret = file;
+ function asyncOnDrop(_x) {
+ return _asyncOnDrop.apply(this, arguments);
}
- });
- return ret;
- },
-
- /**
- * Returns the total size of all files in bytes.
- * @function
- * @returns {number}
- */
- getSize: function () {
- var totalSize = 0;
- each(this.files, function (file) {
- totalSize += file.size;
- });
- return totalSize;
- },
- /**
- * Returns the total size uploaded of all files in bytes.
- * @function
- * @returns {number}
- */
- sizeUploaded: function () {
- var size = 0;
- each(this.files, function (file) {
- size += file.sizeUploaded();
- });
- return size;
- },
-
- /**
- * Returns remaining time to upload all files in seconds. Accuracy is based on average speed.
- * If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
- * @function
- * @returns {number}
- */
- timeRemaining: function () {
- var sizeDelta = 0;
- var averageSpeed = 0;
- each(this.files, function (file) {
- if (!file.paused && !file.error) {
- sizeDelta += file.size - file.sizeUploaded();
- averageSpeed += file.averageSpeed;
- }
- });
- if (sizeDelta && !averageSpeed) {
- return Number.POSITIVE_INFINITY;
- }
- if (!sizeDelta && !averageSpeed) {
- return 0;
+ return asyncOnDrop;
+ }()
+ /**
+ * Prevent default
+ * @function
+ * @param {MouseEvent} event
+ */
+
+ }, {
+ key: "preventEvent",
+ value: function preventEvent(event) {
+ event.preventDefault();
}
- return Math.floor(sizeDelta / averageSpeed);
- }
- };
+ /**
+ * Read webkit dataTransfer object
+ * @param event
+ */
+ }, {
+ key: "webkitReadDataTransfer",
+ value: function webkitReadDataTransfer(event) {
+ var _this2 = this;
+ var queue = event.dataTransfer.items.length;
+ var decrement = function decrement() {
+ if (--queue == 0) {
+ _this2.addFiles(files, event);
+ }
+ };
+ var files = [];
+ var _iterator = _createForOfIteratorHelper(event.dataTransfer.items),
+ _step;
- /**
- * FlowFile class
- * @name FlowFile
- * @param {Flow} flowObj
- * @param {File} file
- * @param {string} uniqueIdentifier
- * @constructor
- */
- function FlowFile(flowObj, file, uniqueIdentifier) {
+ try {
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
+ var item = _step.value;
+ var entry = item.webkitGetAsEntry();
- /**
- * Reference to parent Flow instance
- * @type {Flow}
- */
- this.flowObj = flowObj;
+ if (!entry) {
+ decrement();
+ return;
+ }
- /**
- * Used to store the bytes read
- * @type {Blob|string}
- */
- this.bytes = null;
+ if (entry.isFile) {
+ // due to a bug in Chrome's File System API impl - #149735
+ fileReadSuccess(item.getAsFile(), entry.fullPath);
+ } else {
+ readDirectory(entry.createReader());
+ }
+ }
+ } catch (err) {
+ _iterator.e(err);
+ } finally {
+ _iterator.f();
+ }
- /**
- * Reference to file
- * @type {File}
- */
- this.file = file;
+ function readDirectory(reader) {
+ reader.readEntries(function (entries) {
+ if (entries.length) {
+ queue += entries.length;
+ var fullPaths = {};
+
+ var _iterator2 = _createForOfIteratorHelper(entries),
+ _step2;
+
+ try {
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
+ var _entry = _step2.value;
+
+ if (_entry.isFile) {
+ fullPaths[_entry.name] = _entry.fullPath;
+
+ _entry.file(function (file) {
+ return fileReadSuccess(file, fullPaths[file.name]);
+ }, readError);
+ } else if (_entry.isDirectory) {
+ readDirectory(_entry.createReader());
+ }
+ }
+ } catch (err) {
+ _iterator2.e(err);
+ } finally {
+ _iterator2.f();
+ }
- /**
- * File name. Some confusion in different versions of Firefox
- * @type {string}
- */
- this.name = file.fileName || file.name;
+ readDirectory(reader);
+ } else {
+ decrement();
+ }
+ }, readError);
+ }
- /**
- * File size
- * @type {number}
- */
- this.size = file.size;
+ function fileReadSuccess(file, fullPath) {
+ // relative path should not start with "/"
+ file.relativePath = fullPath.substring(1);
+ files.push(file);
+ decrement();
+ }
- /**
- * Relative file path
- * @type {string}
- */
- this.relativePath = file.relativePath || file.webkitRelativePath || this.name;
+ function readError(fileError) {
+ decrement();
+ throw fileError;
+ }
+ }
+ /**
+ * Generate unique identifier for a file
+ * @function
+ * @param {FlowFile} file
+ * @returns {string}
+ */
- /**
- * File unique identifier
- * @type {string}
- */
- this.uniqueIdentifier = (uniqueIdentifier === undefined ? flowObj.generateUniqueIdentifier(file) : uniqueIdentifier);
+ }, {
+ key: "generateUniqueIdentifier",
+ value: function generateUniqueIdentifier(file) {
+ var custom = this.opts.generateUniqueIdentifier;
- /**
- * Size of Each Chunk
- * @type {number}
- */
- this.chunkSize = 0;
+ if (typeof custom === 'function') {
+ return custom(file);
+ } // Some confusion in different versions of Firefox
- /**
- * List of chunks
- * @type {Array.}
- */
- this.chunks = [];
- /**
- * Indicated if file is paused
- * @type {boolean}
- */
- this.paused = false;
+ var relativePath = file.relativePath || file.webkitRelativePath || file.fileName || file.name;
+ return file.size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, '');
+ }
+ /**
+ * Upload next chunk from the queue
+ * @function
+ * @returns {boolean}
+ * @private
+ */
+
+ }, {
+ key: "uploadNextChunk",
+ value: function uploadNextChunk(preventEvents) {
+ // In some cases (such as videos) it's really handy to upload the first
+ // and last chunk of a file quickly; this let's the server check the file's
+ // metadata and determine if there's even a point in continuing.
+ var found = false;
+
+ if (this.opts.prioritizeFirstAndLastChunk) {
+ var _iterator3 = _createForOfIteratorHelper(this.files),
+ _step3;
+
+ try {
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
+ var file = _step3.value;
+
+ if (!file.paused && file.chunks.length && file.chunks[0].status() === 'pending') {
+ file.chunks[0].send();
+ found = true;
+ break;
+ }
- /**
- * Indicated if file has encountered an error
- * @type {boolean}
- */
- this.error = false;
+ if (!file.paused && file.chunks.length > 1 && file.chunks[file.chunks.length - 1].status() === 'pending') {
+ file.chunks[file.chunks.length - 1].send();
+ found = true;
+ break;
+ }
+ }
+ } catch (err) {
+ _iterator3.e(err);
+ } finally {
+ _iterator3.f();
+ }
- /**
- * Average upload speed
- * @type {number}
- */
- this.averageSpeed = 0;
+ if (found) {
+ return found;
+ }
+ } // Now, simply look for the next, best thing to upload
- /**
- * Current upload speed
- * @type {number}
- */
- this.currentSpeed = 0;
- /**
- * Date then progress was called last time
- * @type {number}
- * @private
- */
- this._lastProgressCallback = Date.now();
+ var _iterator4 = _createForOfIteratorHelper(this.files),
+ _step4;
- /**
- * Previously uploaded file size
- * @type {number}
- * @private
- */
- this._prevUploadedSize = 0;
+ try {
+ outer_loop: for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
+ var _file = _step4.value;
- /**
- * Holds previous progress
- * @type {number}
- * @private
- */
- this._prevProgress = 0;
+ if (_file.paused) {
+ continue;
+ }
- this.bootstrap();
- }
+ var _iterator6 = _createForOfIteratorHelper(_file.chunks),
+ _step6;
- FlowFile.prototype = {
- /**
- * Update speed parameters
- * @link http://stackoverflow.com/questions/2779600/how-to-estimate-download-time-remaining-accurately
- * @function
- */
- measureSpeed: function () {
- var timeSpan = Date.now() - this._lastProgressCallback;
- if (!timeSpan) {
- return ;
- }
- var smoothingFactor = this.flowObj.opts.speedSmoothingFactor;
- var uploaded = this.sizeUploaded();
- // Prevent negative upload speed after file upload resume
- this.currentSpeed = Math.max((uploaded - this._prevUploadedSize) / timeSpan * 1000, 0);
- this.averageSpeed = smoothingFactor * this.currentSpeed + (1 - smoothingFactor) * this.averageSpeed;
- this._prevUploadedSize = uploaded;
- },
+ try {
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
+ var chunk = _step6.value;
- /**
- * For internal usage only.
- * Callback when something happens within the chunk.
- * @function
- * @param {FlowChunk} chunk
- * @param {string} event can be 'progress', 'success', 'error' or 'retry'
- * @param {string} [message]
- */
- chunkEvent: function (chunk, event, message) {
- switch (event) {
- case 'progress':
- if (Date.now() - this._lastProgressCallback <
- this.flowObj.opts.progressCallbacksInterval) {
- break;
- }
- this.measureSpeed();
- this.flowObj.fire('fileProgress', this, chunk);
- this.flowObj.fire('progress');
- this._lastProgressCallback = Date.now();
- break;
- case 'error':
- this.error = true;
- this.abort(true);
- this.flowObj.fire('fileError', this, message, chunk);
- this.flowObj.fire('error', message, this, chunk);
- break;
- case 'success':
- if (this.error) {
- return;
- }
- this.measureSpeed();
- this.flowObj.fire('fileProgress', this, chunk);
- this.flowObj.fire('progress');
- this._lastProgressCallback = Date.now();
- if (this.isComplete()) {
- this.currentSpeed = 0;
- this.averageSpeed = 0;
- this.flowObj.fire('fileSuccess', this, message, chunk);
+ if (chunk.status() === 'pending') {
+ chunk.send();
+ found = true;
+ break outer_loop;
+ }
+ }
+ } catch (err) {
+ _iterator6.e(err);
+ } finally {
+ _iterator6.f();
+ }
}
- break;
- case 'retry':
- this.flowObj.fire('fileRetry', this, chunk);
- break;
- }
- },
+ } catch (err) {
+ _iterator4.e(err);
+ } finally {
+ _iterator4.f();
+ }
- /**
- * Pause file upload
- * @function
- */
- pause: function() {
- this.paused = true;
- this.abort();
- },
+ if (found) {
+ return true;
+ } // The are no more outstanding chunks to upload, check if everything is done
- /**
- * Resume file upload
- * @function
- */
- resume: function() {
- this.paused = false;
- this.flowObj.upload();
- },
- /**
- * Abort current upload
- * @function
- */
- abort: function (reset) {
- this.currentSpeed = 0;
- this.averageSpeed = 0;
- var chunks = this.chunks;
- if (reset) {
- this.chunks = [];
+ var outstanding = false;
+
+ var _iterator5 = _createForOfIteratorHelper(this.files),
+ _step5;
+
+ try {
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
+ var _file2 = _step5.value;
+
+ if (!_file2.isComplete()) {
+ outstanding = true;
+ break;
+ }
+ }
+ } catch (err) {
+ _iterator5.e(err);
+ } finally {
+ _iterator5.f();
+ }
+
+ if (!outstanding && !preventEvents) {
+ // All chunks have been uploaded, complete
+ this.emit('complete');
+ }
+
+ return false;
}
- each(chunks, function (c) {
- if (c.status() === 'uploading') {
- c.abort();
- this.flowObj.uploadNextChunk();
+ /**
+ * Assign a browse action to one or more DOM nodes.
+ * @function
+ * @param {Element|Array.} domNodes
+ * @param {boolean} isDirectory Pass in true to allow directories to
+ * @param {boolean} singleFile prevent multi file upload
+ * @param {Object} attributes set custom attributes:
+ * http://www.w3.org/TR/html-markup/input.file.html#input.file-attributes
+ * eg: accept: 'image/*'
+ * be selected (Chrome only).
+ */
+
+ }, {
+ key: "assignBrowse",
+ value: function assignBrowse(domNodes, isDirectory, singleFile, attributes) {
+ if (domNodes instanceof Element) {
+ domNodes = [domNodes];
}
- }, this);
- },
- /**
- * Cancel current upload and remove from a list
- * @function
- */
- cancel: function () {
- this.flowObj.removeFile(this);
- },
+ each(domNodes, function (domNode) {
+ var _this3 = this;
- /**
- * Retry aborted file upload
- * @function
- */
- retry: function () {
- this.bootstrap();
- this.flowObj.upload();
- },
+ var input;
- /**
- * Clear current chunks and slice file again
- * @function
- */
- bootstrap: function () {
- if (typeof this.flowObj.opts.initFileFn === "function") {
- this.flowObj.opts.initFileFn(this);
- }
+ if (domNode.tagName === 'INPUT' && domNode.type === 'file') {
+ input = domNode;
+ } else {
+ input = document.createElement('input');
+ input.setAttribute('type', 'file'); // display:none - not working in opera 12
+
+ Object.assign(input.style, {
+ visibility: 'hidden',
+ position: 'absolute',
+ width: '1px',
+ height: '1px'
+ }); // for opera 12 browser, input must be assigned to a document
+
+ domNode.appendChild(input); // https://developer.mozilla.org/en/using_files_from_web_applications)
+ // event listener is executed two times
+ // first one - original mouse click event
+ // second - input.click(), input is inside domNode
+
+ domNode.addEventListener('click', function () {
+ input.click();
+ }, false);
+ }
- this.abort(true);
- this.error = false;
- // Rebuild stack of chunks from file
- this._prevProgress = 0;
- var round = this.flowObj.opts.forceChunkSize ? Math.ceil : Math.floor;
- this.chunkSize = evalOpts(this.flowObj.opts.chunkSize, this);
- var chunks = Math.max(
- round(this.size / this.chunkSize), 1
- );
- for (var offset = 0; offset < chunks; offset++) {
- this.chunks.push(
- new FlowChunk(this.flowObj, this, offset)
- );
- }
- },
+ if (!this.opts.singleFile && !singleFile) {
+ input.setAttribute('multiple', 'multiple');
+ }
- /**
- * Get current upload progress status
- * @function
- * @returns {number} from 0 to 1
- */
- progress: function () {
- if (this.error) {
- return 1;
- }
- if (this.chunks.length === 1) {
- this._prevProgress = Math.max(this._prevProgress, this.chunks[0].progress());
- return this._prevProgress;
- }
- // Sum up progress across everything
- var bytesLoaded = 0;
- each(this.chunks, function (c) {
- // get chunk progress relative to entire file
- bytesLoaded += c.progress() * (c.endByte - c.startByte);
- });
- var percent = bytesLoaded / this.size;
- // We don't want to lose percentages when an upload is paused
- this._prevProgress = Math.max(this._prevProgress, percent > 0.9999 ? 1 : percent);
- return this._prevProgress;
- },
+ if (isDirectory) {
+ input.setAttribute('webkitdirectory', 'webkitdirectory');
+ }
- /**
- * Indicates if file is being uploaded at the moment
- * @function
- * @returns {boolean}
- */
- isUploading: function () {
- var uploading = false;
- each(this.chunks, function (chunk) {
- if (chunk.status() === 'uploading') {
- uploading = true;
- return false;
+ each(attributes, function (value, key) {
+ input.setAttribute(key, value);
+ }); // When new files are added, simply append them to the overall list
+ // but adapt to the case where initFileFn is async.
+
+ var callback = this.opts.initFileFn && typeof this.opts.initFileFn === 'function' && this.opts.initFileFn.constructor.name === 'AsyncFunction' ? /*#__PURE__*/function () {
+ var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(e) {
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ if (!e.target.value) {
+ _context2.next = 6;
+ break;
+ }
+
+ input.setAttribute('readonly', 'readonly');
+ _context2.next = 4;
+ return _this3.asyncAddFiles(e.target.files, e);
+
+ case 4:
+ e.target.value = '';
+ input.removeAttribute('readonly');
+
+ case 6:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ }, _callee2);
+ }));
+
+ return function (_x2) {
+ return _ref.apply(this, arguments);
+ };
+ }() : function (e) {
+ if (e.target.value) {
+ _this3.addFiles(e.target.files, e);
+
+ e.target.value = '';
+ }
+ };
+ input.addEventListener('change', callback, false);
+ }, this);
+ }
+ /**
+ * Assign one or more DOM nodes as a drop target.
+ * @function
+ * @param {Element|Array.} domNodes
+ */
+
+ }, {
+ key: "assignDrop",
+ value: function assignDrop(domNodes) {
+ if (typeof domNodes.length === 'undefined') {
+ domNodes = [domNodes];
}
- });
- return uploading;
- },
- /**
- * Indicates if file is has finished uploading and received a response
- * @function
- * @returns {boolean}
- */
- isComplete: function () {
- var outstanding = false;
- each(this.chunks, function (chunk) {
- var status = chunk.status();
- if (status === 'pending' || status === 'uploading' || status === 'reading' || chunk.preprocessState === 1 || chunk.readState === 1) {
- outstanding = true;
- return false;
- }
- });
- return !outstanding;
- },
+ this._onDropBound = this.opts.initFileFn && typeof this.opts.initFileFn === 'function' && this.opts.initFileFn.constructor.name === 'AsyncFunction' ? this.asyncOnDrop.bind(this) : this.onDrop.bind(this);
- /**
- * Count total size uploaded
- * @function
- * @returns {number}
- */
- sizeUploaded: function () {
- var size = 0;
- each(this.chunks, function (chunk) {
- size += chunk.sizeUploaded();
- });
- return size;
- },
+ var _iterator7 = _createForOfIteratorHelper(domNodes),
+ _step7;
- /**
- * Returns remaining time to finish upload file in seconds. Accuracy is based on average speed.
- * If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
- * @function
- * @returns {number}
- */
- timeRemaining: function () {
- if (this.paused || this.error) {
- return 0;
+ try {
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
+ var domNode = _step7.value;
+ domNode.addEventListener('dragover', this.preventEvent, false);
+ domNode.addEventListener('dragenter', this.preventEvent, false);
+ domNode.addEventListener('drop', this._onDropBound, false);
+ }
+ } catch (err) {
+ _iterator7.e(err);
+ } finally {
+ _iterator7.f();
+ }
}
- var delta = this.size - this.sizeUploaded();
- if (delta && !this.averageSpeed) {
- return Number.POSITIVE_INFINITY;
+ /**
+ * Un-assign drop event from DOM nodes
+ * @function
+ * @param domNodes
+ */
+
+ }, {
+ key: "unAssignDrop",
+ value: function unAssignDrop(domNodes) {
+ if (typeof domNodes.length === 'undefined') {
+ domNodes = [domNodes];
+ }
+
+ var _iterator8 = _createForOfIteratorHelper(domNodes),
+ _step8;
+
+ try {
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
+ var domNode = _step8.value;
+ domNode.removeEventListener('dragover', this.preventEvent, false);
+ domNode.removeEventListener('dragenter', this.preventEvent, false);
+ domNode.removeEventListener('drop', this._onDropBound, false);
+ }
+ } catch (err) {
+ _iterator8.e(err);
+ } finally {
+ _iterator8.f();
+ }
}
- if (!delta && !this.averageSpeed) {
- return 0;
+ /**
+ * Returns a boolean indicating whether or not the instance is currently
+ * uploading anything.
+ * @function
+ * @returns {boolean}
+ */
+
+ }, {
+ key: "isUploading",
+ value: function isUploading() {
+ var uploading = false;
+ each(this.files, function (file) {
+ if (file.isUploading()) {
+ uploading = true;
+ return false;
+ }
+ });
+ return uploading;
}
- return Math.floor(delta / this.averageSpeed);
- },
+ /**
+ * should upload next chunk
+ * @function
+ * @returns {boolean|number}
+ */
+
+ }, {
+ key: "_shouldUploadNext",
+ value: function _shouldUploadNext() {
+ var num = 0;
+ var should = true;
+ var simultaneousUploads = this.opts.simultaneousUploads;
+ each(this.files, function (file) {
+ each(file.chunks, function (chunk) {
+ if (chunk.status() === 'uploading') {
+ num++;
- /**
- * Get file type
- * @function
- * @returns {string}
- */
- getType: function () {
- return this.file.type && this.file.type.split('/')[1];
- },
+ if (num >= simultaneousUploads) {
+ should = false;
+ return false;
+ }
+ }
+ });
+ }); // if should is true then return uploading chunks's length
- /**
- * Get file extension
- * @function
- * @returns {string}
- */
- getExtension: function () {
- return this.name.substr((~-this.name.lastIndexOf(".") >>> 0) + 2).toLowerCase();
- }
- };
+ return should && num;
+ }
+ /**
+ * Start or resume uploading.
+ * @function
+ */
+
+ }, {
+ key: "upload",
+ value: function upload() {
+ // Make sure we don't start too many uploads at once
+ var ret = this._shouldUploadNext();
+
+ if (ret === false) {
+ return;
+ } // Kick off the queue
- /**
- * Default read function using the webAPI
- *
- * @function webAPIFileRead(fileObj, startByte, endByte, fileType, chunk)
- *
- */
- function webAPIFileRead(fileObj, startByte, endByte, fileType, chunk) {
- var function_name = 'slice';
- if (fileObj.file.slice)
- function_name = 'slice';
- else if (fileObj.file.mozSlice)
- function_name = 'mozSlice';
- else if (fileObj.file.webkitSlice)
- function_name = 'webkitSlice';
+ this.emit('upload-start');
+ var started = false;
- chunk.readFinished(fileObj.file[function_name](startByte, endByte, fileType));
- }
+ for (var num = 1; num <= this.opts.simultaneousUploads - ret; num++) {
+ started = this.uploadNextChunk(true) || started;
+ }
+ if (!started) {
+ this.emit('complete');
+ }
+ }
+ /**
+ * Resume uploading.
+ * @function
+ */
+
+ }, {
+ key: "resume",
+ value: function resume() {
+ each(this.files, function (file) {
+ if (!file.isComplete()) {
+ file.resume();
+ }
+ });
+ }
+ /**
+ * Pause uploading.
+ * @function
+ */
+
+ }, {
+ key: "pause",
+ value: function pause() {
+ each(this.files, function (file) {
+ file.pause();
+ });
+ }
+ /**
+ * Cancel upload of all FlowFile objects and remove them from the list.
+ * @function
+ */
+
+ }, {
+ key: "cancel",
+ value: function cancel() {
+ for (var i = this.files.length - 1; i >= 0; i--) {
+ this.files[i].cancel();
+ }
+ }
+ /**
+ * Returns a number between 0 and 1 indicating the current upload progress
+ * of all files.
+ * @function
+ * @returns {number}
+ */
+
+ }, {
+ key: "progress",
+ value: function progress() {
+ var totalDone = 0;
+ var totalSize = 0; // Resume all chunks currently being uploaded
- /**
- * Class for storing a single chunk
- * @name FlowChunk
- * @param {Flow} flowObj
- * @param {FlowFile} fileObj
- * @param {number} offset
- * @constructor
- */
- function FlowChunk(flowObj, fileObj, offset) {
+ each(this.files, function (file) {
+ totalDone += file.progress() * file.size;
+ totalSize += file.size;
+ });
+ return totalSize > 0 ? totalDone / totalSize : 0;
+ }
+ /**
+ * A generator to yield files and factor the sync part of the filtering logic used by both
+ * addFiles & asyncAddFiles
+ */
- /**
- * Reference to parent flow object
- * @type {Flow}
- */
- this.flowObj = flowObj;
+ }, {
+ key: "filterFileList",
+ value: /*#__PURE__*/regeneratorRuntime.mark(function filterFileList(fileList, event) {
+ var ie10plus, _iterator9, _step9, file, uniqueIdentifier;
- /**
- * Reference to parent FlowFile object
- * @type {FlowFile}
- */
- this.fileObj = fileObj;
+ return regeneratorRuntime.wrap(function filterFileList$(_context3) {
+ while (1) {
+ switch (_context3.prev = _context3.next) {
+ case 0:
+ // ie10+
+ ie10plus = window.navigator.msPointerEnabled;
+ _iterator9 = _createForOfIteratorHelper(fileList);
+ _context3.prev = 2;
- /**
- * File offset
- * @type {number}
- */
- this.offset = offset;
+ _iterator9.s();
- /**
- * Indicates if chunk existence was checked on the server
- * @type {boolean}
- */
- this.tested = false;
+ case 4:
+ if ((_step9 = _iterator9.n()).done) {
+ _context3.next = 17;
+ break;
+ }
- /**
- * Number of retries performed
- * @type {number}
- */
- this.retries = 0;
+ file = _step9.value;
- /**
- * Pending retry
- * @type {boolean}
- */
- this.pendingRetry = false;
+ if (!(ie10plus && file.size === 0 || file.size % 4096 === 0 && (file.name === '.' || file.fileName === '.'))) {
+ _context3.next = 8;
+ break;
+ }
- /**
- * Preprocess state
- * @type {number} 0 = unprocessed, 1 = processing, 2 = finished
- */
- this.preprocessState = 0;
+ return _context3.abrupt("continue", 15);
- /**
- * Read state
- * @type {number} 0 = not read, 1 = reading, 2 = finished
- */
- this.readState = 0;
+ case 8:
+ uniqueIdentifier = this.generateUniqueIdentifier(file);
+ if (!(!this.opts.allowDuplicateUploads && this.getFromUniqueIdentifier(uniqueIdentifier))) {
+ _context3.next = 11;
+ break;
+ }
- /**
- * Bytes transferred from total request size
- * @type {number}
- */
- this.loaded = 0;
+ return _context3.abrupt("continue", 15);
- /**
- * Total request size
- * @type {number}
- */
- this.total = 0;
+ case 11:
+ if (this.hook('filter-file', file, event)) {
+ _context3.next = 13;
+ break;
+ }
- /**
- * Size of a chunk
- * @type {number}
- */
- this.chunkSize = this.fileObj.chunkSize;
+ return _context3.abrupt("continue", 15);
- /**
- * Chunk start byte in a file
- * @type {number}
- */
- this.startByte = this.offset * this.chunkSize;
+ case 13:
+ _context3.next = 15;
+ return [file, uniqueIdentifier];
- /**
- * A specific filename for this chunk which otherwise default to the main name
- * @type {string}
- */
- this.filename = null;
+ case 15:
+ _context3.next = 4;
+ break;
- /**
- * Compute the endbyte in a file
- *
- */
- this.computeEndByte = function() {
- var endByte = Math.min(this.fileObj.size, (this.offset + 1) * this.chunkSize);
- if (this.fileObj.size - endByte < this.chunkSize && !this.flowObj.opts.forceChunkSize) {
- // The last chunk will be bigger than the chunk size,
- // but less than 2 * this.chunkSize
- endByte = this.fileObj.size;
- }
- return endByte;
- }
+ case 17:
+ _context3.next = 22;
+ break;
- /**
- * Chunk end byte in a file
- * @type {number}
- */
- this.endByte = this.computeEndByte();
+ case 19:
+ _context3.prev = 19;
+ _context3.t0 = _context3["catch"](2);
- /**
- * XMLHttpRequest
- * @type {XMLHttpRequest}
- */
- this.xhr = null;
+ _iterator9.e(_context3.t0);
- var $ = this;
+ case 22:
+ _context3.prev = 22;
- /**
- * Send chunk event
- * @param event
- * @param {...} args arguments of a callback
- */
- this.event = function (event, args) {
- args = Array.prototype.slice.call(arguments);
- args.unshift($);
- $.fileObj.chunkEvent.apply($.fileObj, args);
- };
- /**
- * Catch progress event
- * @param {ProgressEvent} event
- */
- this.progressHandler = function(event) {
- if (event.lengthComputable) {
- $.loaded = event.loaded ;
- $.total = event.total;
- }
- $.event('progress', event);
- };
+ _iterator9.f();
- /**
- * Catch test event
- * @param {Event} event
- */
- this.testHandler = function(event) {
- var status = $.status(true);
- if (status === 'error') {
- $.event(status, $.message());
- $.flowObj.uploadNextChunk();
- } else if (status === 'success') {
- $.tested = true;
- $.event(status, $.message());
- $.flowObj.uploadNextChunk();
- } else if (!$.fileObj.paused) {
- // Error might be caused by file pause method
- // Chunks does not exist on the server side
- $.tested = true;
- $.send();
- }
- };
+ return _context3.finish(22);
- /**
- * Upload has stopped
- * @param {Event} event
- */
- this.doneHandler = function(event) {
- var status = $.status();
- if (status === 'success' || status === 'error') {
- delete this.data;
- $.event(status, $.message());
- $.flowObj.uploadNextChunk();
- } else if (!$.fileObj.paused) {
- $.event('retry', $.message());
- $.pendingRetry = true;
- $.abort();
- $.retries++;
- var retryInterval = $.flowObj.opts.chunkRetryInterval;
- if (retryInterval !== null) {
- setTimeout(function () {
- $.send();
- }, retryInterval);
- } else {
- $.send();
+ case 25:
+ case "end":
+ return _context3.stop();
+ }
+ }
+ }, filterFileList, this, [[2, 19, 22, 25]]);
+ })
+ /**
+ * Add a HTML5 File object to the list of files.
+ * @function
+ * @param {File} file
+ * @param Any other parameters supported by addFiles
+ */
+
+ }, {
+ key: "addFile",
+ value: function addFile(file) {
+ for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
}
- }
- };
- }
-
- FlowChunk.prototype = {
- /**
- * Get params for a request
- * @function
- */
- getParams: function () {
- return {
- flowChunkNumber: this.offset + 1,
- flowChunkSize: this.chunkSize,
- flowCurrentChunkSize: this.endByte - this.startByte,
- flowTotalSize: this.fileObj.size,
- flowIdentifier: this.fileObj.uniqueIdentifier,
- flowFilename: this.fileObj.name,
- flowRelativePath: this.fileObj.relativePath,
- flowTotalChunks: this.fileObj.chunks.length
- };
- },
- /**
- * Get target option with query params
- * @function
- * @param params
- * @returns {string}
- */
- getTarget: function(target, params){
- if (params.length == 0) {
- return target;
+ this.addFiles.apply(this, [[file]].concat(args));
}
+ /**
+ * Add a HTML5 File object to the list of files.
+ * @function
+ * @param {FileList|Array} fileList
+ * @param {Event} [event] event is optional
+ */
+
+ }, {
+ key: "addFiles",
+ value: function addFiles(fileList) {
+ var event = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
+ var initFileFn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.opts.initFileFn;
+
+ if (this.hasHook(true)) {
+ console.warn('Using addFiles() while settings asynchronous events can lead to unpredictable results. Use asyncAddFiles() instead.');
+ }
- if(target.indexOf('?') < 0) {
- target += '?';
- } else {
- target += '&';
- }
- return target + params.join('&');
- },
+ var item,
+ file,
+ uniqueIdentifier,
+ files = [];
+ var iterator = this.filterFileList(fileList, event);
- /**
- * Makes a GET request without any data to see if the chunk has already
- * been uploaded in a previous session
- * @function
- */
- test: function () {
- // Set up request and listen for event
- this.xhr = new XMLHttpRequest();
- this.xhr.addEventListener("load", this.testHandler, false);
- this.xhr.addEventListener("error", this.testHandler, false);
- var testMethod = evalOpts(this.flowObj.opts.testMethod, this.fileObj, this);
- var data = this.prepareXhrRequest(testMethod, true);
- this.xhr.send(data);
- },
+ while ((item = iterator.next()) && !item.done) {
+ var _item$value = _slicedToArray(item.value, 2);
- /**
- * Finish preprocess state
- * @function
- */
- preprocessFinished: function () {
- // Re-compute the endByte after the preprocess function to allow an
- // implementer of preprocess to set the fileObj size
- this.endByte = this.computeEndByte();
+ file = _item$value[0];
+ uniqueIdentifier = _item$value[1];
+ var f = new FlowFile(this, file, uniqueIdentifier);
+ f.bootstrap(event, initFileFn);
+ this.hook('file-added', f, event);
+ this.aHook('file-added', f, event);
- this.preprocessState = 2;
- this.send();
- },
+ if (!f.file) {
+ continue;
+ }
- /**
- * Finish read state
- * @function
- */
- readFinished: function (bytes) {
- this.readState = 2;
- this.bytes = bytes;
- this.send();
- },
+ files.push(f);
+ }
+ this.hook('files-added', files, event);
+ this.aHook('files-added', files, event);
+ files = files.filter(function (e) {
+ return e;
+ });
- /**
- * Uploads the actual data in a POST call
- * @function
- */
- send: function () {
- var preprocess = this.flowObj.opts.preprocess;
- var read = this.flowObj.opts.readFileFn;
- if (typeof preprocess === 'function') {
- switch (this.preprocessState) {
- case 0:
- this.preprocessState = 1;
- preprocess(this);
- return;
- case 1:
- return;
- }
- }
- switch (this.readState) {
- case 0:
- this.readState = 1;
- read(this.fileObj, this.startByte, this.endByte, this.fileObj.file.type, this);
- return;
- case 1:
- return;
- }
- if (this.flowObj.opts.testChunks && !this.tested) {
- this.test();
- return;
- }
+ var _iterator10 = _createForOfIteratorHelper(files),
+ _step10;
- this.loaded = 0;
- this.total = 0;
- this.pendingRetry = false;
+ try {
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
+ file = _step10.value;
- // Set up request and listen for event
- this.xhr = new XMLHttpRequest();
- this.xhr.upload.addEventListener('progress', this.progressHandler, false);
- this.xhr.addEventListener("load", this.doneHandler, false);
- this.xhr.addEventListener("error", this.doneHandler, false);
+ if (this.opts.singleFile && this.files.length > 0) {
+ this.removeFile(this.files[0]);
+ }
- var uploadMethod = evalOpts(this.flowObj.opts.uploadMethod, this.fileObj, this);
- var data = this.prepareXhrRequest(uploadMethod, false, this.flowObj.opts.method, this.bytes);
- var changeRawDataBeforeSend = this.flowObj.opts.changeRawDataBeforeSend;
- if (typeof changeRawDataBeforeSend === 'function') {
- data = changeRawDataBeforeSend(this, data);
- }
- this.xhr.send(data);
- },
+ this.files.push(file); // console.log(`enqueue file ${file.name} of ${file.chunks.length} chunks`);
+ }
+ } catch (err) {
+ _iterator10.e(err);
+ } finally {
+ _iterator10.f();
+ }
- /**
- * Abort current xhr request
- * @function
- */
- abort: function () {
- // Abort and reset
- var xhr = this.xhr;
- this.xhr = null;
- if (xhr) {
- xhr.abort();
+ this.hook('files-submitted', this.files, event);
+ this.aHook('files-submitted', this.files, event);
}
- },
+ /**
+ * Add a HTML5 File object to the list of files.
+ * @function
+ * @param {File} file
+ * @param Any other parameters supported by asyncAddFiles.
+ *
+ * @return (async) An initialized .
+ */
+
+ }, {
+ key: "asyncAddFile",
+ value: function () {
+ var _asyncAddFile = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(file) {
+ var _len2,
+ args,
+ _key2,
+ _args4 = arguments;
+
+ return regeneratorRuntime.wrap(function _callee3$(_context4) {
+ while (1) {
+ switch (_context4.prev = _context4.next) {
+ case 0:
+ for (_len2 = _args4.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ args[_key2 - 1] = _args4[_key2];
+ }
+
+ _context4.next = 3;
+ return this.asyncAddFiles.apply(this, [[file]].concat(args));
+
+ case 3:
+ return _context4.abrupt("return", _context4.sent[0]);
+
+ case 4:
+ case "end":
+ return _context4.stop();
+ }
+ }
+ }, _callee3, this);
+ }));
- /**
- * Retrieve current chunk upload status
- * @function
- * @returns {string} 'pending', 'uploading', 'success', 'error'
- */
- status: function (isTest) {
- if (this.readState === 1) {
- return 'reading';
- } else if (this.pendingRetry || this.preprocessState === 1) {
- // if pending retry then that's effectively the same as actively uploading,
- // there might just be a slight delay before the retry starts
- return 'uploading';
- } else if (!this.xhr) {
- return 'pending';
- } else if (this.xhr.readyState < 4) {
- // Status is really 'OPENED', 'HEADERS_RECEIVED'
- // or 'LOADING' - meaning that stuff is happening
- return 'uploading';
- } else {
- if (this.flowObj.opts.successStatuses.indexOf(this.xhr.status) > -1) {
- // HTTP 200, perfect
- // HTTP 202 Accepted - The request has been accepted for processing, but the processing has not been completed.
- return 'success';
- } else if (this.flowObj.opts.permanentErrors.indexOf(this.xhr.status) > -1 ||
- !isTest && this.retries >= this.flowObj.opts.maxChunkRetries) {
- // HTTP 413/415/500/501, permanent error
- return 'error';
- } else {
- // this should never happen, but we'll reset and queue a retry
- // a likely case for this would be 503 service unavailable
- this.abort();
- return 'pending';
+ function asyncAddFile(_x3) {
+ return _asyncAddFile.apply(this, arguments);
}
- }
- },
- /**
- * Get response from xhr request
- * @function
- * @returns {String}
- */
- message: function () {
- return this.xhr ? this.xhr.responseText : '';
- },
+ return asyncAddFile;
+ }()
+ /**
+ * Add a HTML5 File object to the list of files.
+ * @function
+ * @param {FileList|Array} fileList
+ * @param {Event} [event] event is optional
+ *
+ * @return Promise{[,...]} The promise of getting an array of AsyncFlowFile.
+ */
+
+ }, {
+ key: "asyncAddFiles",
+ value: function () {
+ var _asyncAddFiles = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee4(fileList) {
+ var event,
+ initFileFn,
+ item,
+ file,
+ uniqueIdentifier,
+ states,
+ iterator,
+ _item$value2,
+ flowFile,
+ state,
+ flowfiles,
+ _iterator11,
+ _step11,
+ ff,
+ _iterator12,
+ _step12,
+ _file3,
+ _args5 = arguments;
+
+ return regeneratorRuntime.wrap(function _callee4$(_context5) {
+ while (1) {
+ switch (_context5.prev = _context5.next) {
+ case 0:
+ event = _args5.length > 1 && _args5[1] !== undefined ? _args5[1] : null;
+ initFileFn = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : this.opts.initFileFn;
+ states = [];
+ iterator = this.filterFileList(fileList, event);
+
+ case 4:
+ if (!((item = iterator.next()) && !item.done)) {
+ _context5.next = 16;
+ break;
+ }
+
+ _item$value2 = _slicedToArray(item.value, 2);
+ file = _item$value2[0];
+ uniqueIdentifier = _item$value2[1];
+ _context5.next = 10;
+ return this.aHook('filter-file', file, event);
+
+ case 10:
+ if (_context5.sent) {
+ _context5.next = 12;
+ break;
+ }
+
+ return _context5.abrupt("continue", 4);
+
+ case 12:
+ // ToDo: parallelizable ?
+ flowFile = new AsyncFlowFile(this, file, uniqueIdentifier), state = flowFile.bootstrap(event, initFileFn);
+ states.push(state);
+ _context5.next = 4;
+ break;
+
+ case 16:
+ _context5.next = 18;
+ return Promise.all(states);
+
+ case 18:
+ flowfiles = _context5.sent;
+ _iterator11 = _createForOfIteratorHelper(flowfiles);
+ _context5.prev = 20;
+
+ _iterator11.s();
+
+ case 22:
+ if ((_step11 = _iterator11.n()).done) {
+ _context5.next = 29;
+ break;
+ }
+
+ ff = _step11.value;
+ this.hook('file-added', ff, event);
+ _context5.next = 27;
+ return this.aHook('file-added', ff, event);
+
+ case 27:
+ _context5.next = 22;
+ break;
+
+ case 29:
+ _context5.next = 34;
+ break;
+
+ case 31:
+ _context5.prev = 31;
+ _context5.t0 = _context5["catch"](20);
+
+ _iterator11.e(_context5.t0);
+
+ case 34:
+ _context5.prev = 34;
+
+ _iterator11.f();
+
+ return _context5.finish(34);
+
+ case 37:
+ this.hook('files-added', flowfiles, event);
+ _context5.next = 40;
+ return this.aHook('files-added', flowfiles, event);
+
+ case 40:
+ flowfiles = flowfiles.filter(function (e) {
+ return e && e.file;
+ });
+ _iterator12 = _createForOfIteratorHelper(flowfiles);
+
+ try {
+ for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
+ _file3 = _step12.value;
+
+ if (this.opts.singleFile && this.files.length > 0) {
+ this.removeFile(this.files[0]);
+ }
+
+ this.files.push(_file3);
+ }
+ } catch (err) {
+ _iterator12.e(err);
+ } finally {
+ _iterator12.f();
+ }
+
+ this.hook('files-submitted', this.files, event);
+ _context5.next = 46;
+ return this.aHook('files-submitted', this.files, event);
+
+ case 46:
+ return _context5.abrupt("return", flowfiles);
+
+ case 47:
+ case "end":
+ return _context5.stop();
+ }
+ }
+ }, _callee4, this, [[20, 31, 34, 37]]);
+ }));
- /**
- * Get upload progress
- * @function
- * @returns {number}
- */
- progress: function () {
- if (this.pendingRetry) {
- return 0;
- }
- var s = this.status();
- if (s === 'success' || s === 'error') {
- return 1;
- } else if (s === 'pending') {
- return 0;
- } else {
- return this.total > 0 ? this.loaded / this.total : 0;
- }
- },
+ function asyncAddFiles(_x4) {
+ return _asyncAddFiles.apply(this, arguments);
+ }
- /**
- * Count total size uploaded
- * @function
- * @returns {number}
- */
- sizeUploaded: function () {
- var size = this.endByte - this.startByte;
- // can't return only chunk.loaded value, because it is bigger than chunk size
- if (this.status() !== 'success') {
- size = this.progress() * size;
+ return asyncAddFiles;
+ }()
+ /**
+ * Cancel upload of a specific FlowFile object from the list.
+ * @function
+ * @param {FlowFile} file
+ */
+
+ }, {
+ key: "removeFile",
+ value: function removeFile(file) {
+ for (var i = this.files.length - 1; i >= 0; i--) {
+ if (this.files[i] === file) {
+ this.files.splice(i, 1);
+ file.abort();
+ this.emit('file-removed', file);
+ }
+ }
}
- return size;
- },
-
- /**
- * Prepare Xhr request. Set query, headers and data
- * @param {string} method GET or POST
- * @param {bool} isTest is this a test request
- * @param {string} [paramsMethod] octet or form
- * @param {Blob} [blob] to send
- * @returns {FormData|Blob|Null} data to send
- */
- prepareXhrRequest: function(method, isTest, paramsMethod, blob) {
- // Add data from the query options
- var query = evalOpts(this.flowObj.opts.query, this.fileObj, this, isTest);
- query = extend(query || {}, this.getParams());
-
- var target = evalOpts(this.flowObj.opts.target, this.fileObj, this, isTest);
- var data = null;
- if (method === 'GET' || paramsMethod === 'octet') {
- // Add data from the query options
- var params = [];
- each(query, function (v, k) {
- params.push([encodeURIComponent(k), encodeURIComponent(v)].join('='));
+ /**
+ * Look up a FlowFile object by its unique identifier.
+ * @function
+ * @param {string} uniqueIdentifier
+ * @returns {boolean|FlowFile} false if file was not found
+ */
+
+ }, {
+ key: "getFromUniqueIdentifier",
+ value: function getFromUniqueIdentifier(uniqueIdentifier) {
+ var ret = false;
+ each(this.files, function (file) {
+ if (file.uniqueIdentifier === uniqueIdentifier) {
+ ret = file;
+ }
});
- target = this.getTarget(target, params);
- data = blob || null;
- } else {
- // Add data from the query options
- data = new FormData();
- each(query, function (v, k) {
- data.append(k, v);
+ return ret;
+ }
+ /**
+ * Returns the total size of all files in bytes.
+ * @function
+ * @returns {number}
+ */
+
+ }, {
+ key: "getSize",
+ value: function getSize() {
+ var totalSize = 0;
+ each(this.files, function (file) {
+ totalSize += file.size;
});
- if (typeof blob !== "undefined") {
- data.append(this.flowObj.opts.fileParameterName, blob, this.filename || this.fileObj.file.name);
- }
+ return totalSize;
}
-
- this.xhr.open(method, target, true);
- this.xhr.withCredentials = this.flowObj.opts.withCredentials;
-
- // Add data from header options
- each(evalOpts(this.flowObj.opts.headers, this.fileObj, this, isTest), function (v, k) {
- this.xhr.setRequestHeader(k, v);
- }, this);
-
- return data;
- }
- };
-
- /**
- * Remove value from array
- * @param array
- * @param value
- */
- function arrayRemove(array, value) {
- var index = array.indexOf(value);
- if (index > -1) {
- array.splice(index, 1);
- }
- }
-
- /**
- * If option is a function, evaluate it with given params
- * @param {*} data
- * @param {...} args arguments of a callback
- * @returns {*}
- */
- function evalOpts(data, args) {
- if (typeof data === "function") {
- // `arguments` is an object, not array, in FF, so:
- args = Array.prototype.slice.call(arguments);
- data = data.apply(null, args.slice(1));
- }
- return data;
- }
- Flow.evalOpts = evalOpts;
-
- /**
- * Execute function asynchronously
- * @param fn
- * @param context
- */
- function async(fn, context) {
- setTimeout(fn.bind(context), 0);
- }
-
- /**
- * Extends the destination object `dst` by copying all of the properties from
- * the `src` object(s) to `dst`. You can specify multiple `src` objects.
- * @function
- * @param {Object} dst Destination object.
- * @param {...Object} src Source object(s).
- * @returns {Object} Reference to `dst`.
- */
- function extend(dst, src) {
- each(arguments, function(obj) {
- if (obj !== dst) {
- each(obj, function(value, key){
- dst[key] = value;
+ /**
+ * Returns the total size uploaded of all files in bytes.
+ * @function
+ * @returns {number}
+ */
+
+ }, {
+ key: "sizeUploaded",
+ value: function sizeUploaded() {
+ var size = 0;
+ each(this.files, function (file) {
+ size += file.sizeUploaded();
});
+ return size;
}
- });
- return dst;
- }
- Flow.extend = extend;
+ /**
+ * Returns remaining time to upload all files in seconds. Accuracy is based on average speed.
+ * If speed is zero, time remaining will be equal to positive infinity `Number.POSITIVE_INFINITY`
+ * @function
+ * @returns {number}
+ */
+
+ }, {
+ key: "timeRemaining",
+ value: function timeRemaining() {
+ var sizeDelta = 0;
+ var averageSpeed = 0;
+ each(this.files, function (file) {
+ if (!file.paused && !file.error) {
+ sizeDelta += file.size - file.sizeUploaded();
+ averageSpeed += file.averageSpeed;
+ }
+ });
- /**
- * Iterate each element of an object
- * @function
- * @param {Array|Object} obj object or an array to iterate
- * @param {Function} callback first argument is a value and second is a key.
- * @param {Object=} context Object to become context (`this`) for the iterator function.
- */
- function each(obj, callback, context) {
- if (!obj) {
- return ;
- }
- var key;
- // Is Array?
- // Array.isArray won't work, not only arrays can be iterated by index https://github.com/flowjs/ng-flow/issues/236#
- if (typeof(obj.length) !== 'undefined') {
- for (key = 0; key < obj.length; key++) {
- if (callback.call(context, obj[key], key) === false) {
- return ;
+ if (sizeDelta && !averageSpeed) {
+ return Number.POSITIVE_INFINITY;
}
- }
- } else {
- for (key in obj) {
- if (obj.hasOwnProperty(key) && callback.call(context, obj[key], key) === false) {
- return ;
+
+ if (!sizeDelta && !averageSpeed) {
+ return 0;
}
+
+ return Math.floor(sizeDelta / averageSpeed);
}
- }
- }
- Flow.each = each;
+ }]);
- /**
- * FlowFile constructor
- * @type {FlowFile}
- */
- Flow.FlowFile = FlowFile;
+ return Flow;
+ }(_default);
- /**
- * FlowFile constructor
- * @type {FlowChunk}
- */
- Flow.FlowChunk = FlowChunk;
+ return Flow;
- /**
- * Library version
- * @type {string}
- */
- Flow.version = '2.14.1';
-
- if ( typeof module === "object" && module && typeof module.exports === "object" ) {
- // Expose Flow as module.exports in loaders that implement the Node
- // module pattern (including browserify). Do not create the global, since
- // the user will be storing it themselves locally, and globals are frowned
- // upon in the Node module world.
- module.exports = Flow;
- } else {
- // Otherwise expose Flow to the global object as usual
- window.Flow = Flow;
-
- // Register as a named AMD module, since Flow can be concatenated with other
- // files that may use define, but not via a proper concatenation script that
- // understands anonymous AMD modules. A named AMD is safest and most robust
- // way to register. Lowercase flow is used because AMD module names are
- // derived from file names, and Flow is normally delivered in a lowercase
- // file name. Do this after creating the global so that if an AMD module wants
- // to call noConflict to hide this version of Flow, it will work.
- if ( typeof define === "function" && define.amd ) {
- define( "flow", [], function () { return Flow; } );
- }
- }
-})(typeof window !== 'undefined' && window, typeof document !== 'undefined' && document);
+})));
+//# sourceMappingURL=flow.js.map
diff --git a/dist/flow.min.js b/dist/flow.min.js
index ef301778..ceea9357 100644
--- a/dist/flow.min.js
+++ b/dist/flow.min.js
@@ -1,2 +1,3 @@
-/*! @flowjs/flow.js 2.14.1 */
-!function(a,b,c){"use strict";function d(b){if(this.support=!("undefined"==typeof File||"undefined"==typeof Blob||"undefined"==typeof FileList||!Blob.prototype.slice&&!Blob.prototype.webkitSlice&&!Blob.prototype.mozSlice),this.support){this.supportDirectory=/Chrome/.test(a.navigator.userAgent)||/Firefox/.test(a.navigator.userAgent)||/Edge/.test(a.navigator.userAgent),this.files=[],this.defaults={chunkSize:1048576,forceChunkSize:!1,simultaneousUploads:3,singleFile:!1,fileParameterName:"file",progressCallbacksInterval:500,speedSmoothingFactor:.1,query:{},headers:{},withCredentials:!1,preprocess:null,changeRawDataBeforeSend:null,method:"multipart",testMethod:"GET",uploadMethod:"POST",prioritizeFirstAndLastChunk:!1,allowDuplicateUploads:!1,target:"/",testChunks:!0,generateUniqueIdentifier:null,maxChunkRetries:0,chunkRetryInterval:null,permanentErrors:[404,413,415,500,501],successStatuses:[200,201,202],onDropStopPropagation:!1,initFileFn:null,readFileFn:f},this.opts={},this.events={};var c=this;this.onDrop=function(a){c.opts.onDropStopPropagation&&a.stopPropagation(),a.preventDefault();var b=a.dataTransfer;b.items&&b.items[0]&&b.items[0].webkitGetAsEntry?c.webkitReadDataTransfer(a):c.addFiles(b.files,a)},this.preventEvent=function(a){a.preventDefault()},this.opts=d.extend({},this.defaults,b||{})}}function e(a,b,d){this.flowObj=a,this.bytes=null,this.file=b,this.name=b.fileName||b.name,this.size=b.size,this.relativePath=b.relativePath||b.webkitRelativePath||this.name,this.uniqueIdentifier=d===c?a.generateUniqueIdentifier(b):d,this.chunkSize=0,this.chunks=[],this.paused=!1,this.error=!1,this.averageSpeed=0,this.currentSpeed=0,this._lastProgressCallback=Date.now(),this._prevUploadedSize=0,this._prevProgress=0,this.bootstrap()}function f(a,b,c,d,e){var f="slice";a.file.slice?f="slice":a.file.mozSlice?f="mozSlice":a.file.webkitSlice&&(f="webkitSlice"),e.readFinished(a.file[f](b,c,d))}function g(a,b,c){this.flowObj=a,this.fileObj=b,this.offset=c,this.tested=!1,this.retries=0,this.pendingRetry=!1,this.preprocessState=0,this.readState=0,this.loaded=0,this.total=0,this.chunkSize=this.fileObj.chunkSize,this.startByte=this.offset*this.chunkSize,this.filename=null,this.computeEndByte=function(){var a=Math.min(this.fileObj.size,(this.offset+1)*this.chunkSize);return this.fileObj.size-a-1&&a.splice(c,1)}function i(a,b){return"function"==typeof a&&(b=Array.prototype.slice.call(arguments),a=a.apply(null,b.slice(1))),a}function j(a,b){setTimeout(a.bind(b),0)}function k(a,b){return l(arguments,function(b){b!==a&&l(b,function(b,c){a[c]=b})}),a}function l(a,b,c){if(a){var d;if("undefined"!=typeof a.length){for(d=0;d1&&"pending"===a.chunks[a.chunks.length-1].status()?(a.chunks[a.chunks.length-1].send(),b=!0,!1):void 0}),b))return b;if(l(this.files,function(a){if(a.paused||l(a.chunks,function(a){if("pending"===a.status())return a.send(),b=!0,!1}),b)return!1}),b)return!0;var c=!1;return l(this.files,function(a){if(!a.isComplete())return c=!0,!1}),c||a||j(function(){this.fire("complete")},this),!1},assignBrowse:function(a,c,d,e){a instanceof Element&&(a=[a]),l(a,function(a){var f;"INPUT"===a.tagName&&"file"===a.type?f=a:(f=b.createElement("input"),f.setAttribute("type","file"),k(f.style,{visibility:"hidden",position:"absolute",width:"1px",height:"1px"}),a.appendChild(f),a.addEventListener("click",function(){f.click()},!1)),this.opts.singleFile||d||f.setAttribute("multiple","multiple"),c&&f.setAttribute("webkitdirectory","webkitdirectory"),l(e,function(a,b){f.setAttribute(b,a)});var g=this;f.addEventListener("change",function(a){a.target.value&&(g.addFiles(a.target.files,a),a.target.value="")},!1)},this)},assignDrop:function(a){"undefined"==typeof a.length&&(a=[a]),l(a,function(a){a.addEventListener("dragover",this.preventEvent,!1),a.addEventListener("dragenter",this.preventEvent,!1),a.addEventListener("drop",this.onDrop,!1)},this)},unAssignDrop:function(a){"undefined"==typeof a.length&&(a=[a]),l(a,function(a){a.removeEventListener("dragover",this.preventEvent),a.removeEventListener("dragenter",this.preventEvent),a.removeEventListener("drop",this.onDrop)},this)},isUploading:function(){var a=!1;return l(this.files,function(b){if(b.isUploading())return a=!0,!1}),a},_shouldUploadNext:function(){var a=0,b=!0,c=this.opts.simultaneousUploads;return l(this.files,function(d){l(d.chunks,function(d){if("uploading"===d.status()&&(a++,a>=c))return b=!1,!1})}),b&&a},upload:function(){var a=this._shouldUploadNext();if(a!==!1){this.fire("uploadStart");for(var b=!1,c=1;c<=this.opts.simultaneousUploads-a;c++)b=this.uploadNextChunk(!0)||b;b||j(function(){this.fire("complete")},this)}},resume:function(){l(this.files,function(a){a.isComplete()||a.resume()})},pause:function(){l(this.files,function(a){a.pause()})},cancel:function(){for(var a=this.files.length-1;a>=0;a--)this.files[a].cancel()},progress:function(){var a=0,b=0;return l(this.files,function(c){a+=c.progress()*c.size,b+=c.size}),b>0?a/b:0},addFile:function(a,b){this.addFiles([a],b)},addFiles:function(a,b){var c=[];l(a,function(a){if((!m||m&&a.size>0)&&(a.size%4096!==0||"."!==a.name&&"."!==a.fileName)){var d=this.generateUniqueIdentifier(a);if(this.opts.allowDuplicateUploads||!this.getFromUniqueIdentifier(d)){var f=new e(this,a,d);this.fire("fileAdded",f,b)&&c.push(f)}}},this),this.fire("filesAdded",c,b)&&(l(c,function(a){this.opts.singleFile&&this.files.length>0&&this.removeFile(this.files[0]),this.files.push(a)},this),this.fire("filesSubmitted",c,b))},removeFile:function(a){for(var b=this.files.length-1;b>=0;b--)this.files[b]===a&&(this.files.splice(b,1),a.abort(),this.fire("fileRemoved",a))},getFromUniqueIdentifier:function(a){var b=!1;return l(this.files,function(c){c.uniqueIdentifier===a&&(b=c)}),b},getSize:function(){var a=0;return l(this.files,function(b){a+=b.size}),a},sizeUploaded:function(){var a=0;return l(this.files,function(b){a+=b.sizeUploaded()}),a},timeRemaining:function(){var a=0,b=0;return l(this.files,function(c){c.paused||c.error||(a+=c.size-c.sizeUploaded(),b+=c.averageSpeed)}),a&&!b?Number.POSITIVE_INFINITY:a||b?Math.floor(a/b):0}},e.prototype={measureSpeed:function(){var a=Date.now()-this._lastProgressCallback;if(a){var b=this.flowObj.opts.speedSmoothingFactor,c=this.sizeUploaded();this.currentSpeed=Math.max((c-this._prevUploadedSize)/a*1e3,0),this.averageSpeed=b*this.currentSpeed+(1-b)*this.averageSpeed,this._prevUploadedSize=c}},chunkEvent:function(a,b,c){switch(b){case"progress":if(Date.now()-this._lastProgressCallback.9999?1:b),this._prevProgress},isUploading:function(){var a=!1;return l(this.chunks,function(b){if("uploading"===b.status())return a=!0,!1}),a},isComplete:function(){var a=!1;return l(this.chunks,function(b){var c=b.status();if("pending"===c||"uploading"===c||"reading"===c||1===b.preprocessState||1===b.readState)return a=!0,!1}),!a},sizeUploaded:function(){var a=0;return l(this.chunks,function(b){a+=b.sizeUploaded()}),a},timeRemaining:function(){if(this.paused||this.error)return 0;var a=this.size-this.sizeUploaded();return a&&!this.averageSpeed?Number.POSITIVE_INFINITY:a||this.averageSpeed?Math.floor(a/this.averageSpeed):0},getType:function(){return this.file.type&&this.file.type.split("/")[1]},getExtension:function(){return this.name.substr((~-this.name.lastIndexOf(".")>>>0)+2).toLowerCase()}},g.prototype={getParams:function(){return{flowChunkNumber:this.offset+1,flowChunkSize:this.chunkSize,flowCurrentChunkSize:this.endByte-this.startByte,flowTotalSize:this.fileObj.size,flowIdentifier:this.fileObj.uniqueIdentifier,flowFilename:this.fileObj.name,flowRelativePath:this.fileObj.relativePath,flowTotalChunks:this.fileObj.chunks.length}},getTarget:function(a,b){return 0==b.length?a:(a+=a.indexOf("?")<0?"?":"&",a+b.join("&"))},test:function(){this.xhr=new XMLHttpRequest,this.xhr.addEventListener("load",this.testHandler,!1),this.xhr.addEventListener("error",this.testHandler,!1);var a=i(this.flowObj.opts.testMethod,this.fileObj,this),b=this.prepareXhrRequest(a,!0);this.xhr.send(b)},preprocessFinished:function(){this.endByte=this.computeEndByte(),this.preprocessState=2,this.send()},readFinished:function(a){this.readState=2,this.bytes=a,this.send()},send:function(){var a=this.flowObj.opts.preprocess,b=this.flowObj.opts.readFileFn;if("function"==typeof a)switch(this.preprocessState){case 0:return this.preprocessState=1,void a(this);case 1:return}switch(this.readState){case 0:return this.readState=1,void b(this.fileObj,this.startByte,this.endByte,this.fileObj.file.type,this);case 1:return}if(this.flowObj.opts.testChunks&&!this.tested)return void this.test();this.loaded=0,this.total=0,this.pendingRetry=!1,this.xhr=new XMLHttpRequest,this.xhr.upload.addEventListener("progress",this.progressHandler,!1),this.xhr.addEventListener("load",this.doneHandler,!1),this.xhr.addEventListener("error",this.doneHandler,!1);var c=i(this.flowObj.opts.uploadMethod,this.fileObj,this),d=this.prepareXhrRequest(c,!1,this.flowObj.opts.method,this.bytes),e=this.flowObj.opts.changeRawDataBeforeSend;"function"==typeof e&&(d=e(this,d)),this.xhr.send(d)},abort:function(){var a=this.xhr;this.xhr=null,a&&a.abort()},status:function(a){return 1===this.readState?"reading":this.pendingRetry||1===this.preprocessState?"uploading":this.xhr?this.xhr.readyState<4?"uploading":this.flowObj.opts.successStatuses.indexOf(this.xhr.status)>-1?"success":this.flowObj.opts.permanentErrors.indexOf(this.xhr.status)>-1||!a&&this.retries>=this.flowObj.opts.maxChunkRetries?"error":(this.abort(),"pending"):"pending"},message:function(){return this.xhr?this.xhr.responseText:""},progress:function(){if(this.pendingRetry)return 0;var a=this.status();return"success"===a||"error"===a?1:"pending"===a?0:this.total>0?this.loaded/this.total:0},sizeUploaded:function(){var a=this.endByte-this.startByte;return"success"!==this.status()&&(a=this.progress()*a),a},prepareXhrRequest:function(a,b,c,d){var e=i(this.flowObj.opts.query,this.fileObj,this,b);e=k(e||{},this.getParams());var f=i(this.flowObj.opts.target,this.fileObj,this,b),g=null;if("GET"===a||"octet"===c){var h=[];l(e,function(a,b){h.push([encodeURIComponent(b),encodeURIComponent(a)].join("="))}),f=this.getTarget(f,h),g=d||null}else g=new FormData,l(e,function(a,b){g.append(b,a)}),"undefined"!=typeof d&&g.append(this.flowObj.opts.fileParameterName,d,this.filename||this.fileObj.file.name);return this.xhr.open(a,f,!0),this.xhr.withCredentials=this.flowObj.opts.withCredentials,l(i(this.flowObj.opts.headers,this.fileObj,this,b),function(a,b){this.xhr.setRequestHeader(b,a)},this),g}},d.evalOpts=i,d.extend=k,d.each=l,d.FlowFile=e,d.FlowChunk=g,d.version="2.14.1","object"==typeof module&&module&&"object"==typeof module.exports?module.exports=d:(a.Flow=d,"function"==typeof define&&define.amd&&define("flow",[],function(){return d}))}("undefined"!=typeof window&&window,"undefined"!=typeof document&&document);
\ No newline at end of file
+/*! @flowjs/flow.js 3.0.0-alpha.0 */
+function t(e){return(t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(e)}function e(t,e,r,n,i,o,a){try{var s=t[o](a),u=s.value}catch(t){return void r(t)}s.done?e(u):Promise.resolve(u).then(n,i)}function r(t){return function(){var r=this,n=arguments;return new Promise((function(i,o){var a=t.apply(r,n);function s(t){e(a,i,o,s,u,"next",t)}function u(t){e(a,i,o,s,u,"throw",t)}s(void 0)}))}}function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){for(var r=0;rt.length)&&(e=t.length);for(var r=0,n=new Array(e);r=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var o,a=!0,s=!1;return{s:function(){r=t[Symbol.iterator]()},n:function(){var t=r.next();return a=t.done,t},e:function(t){s=!0,o=t},f:function(){try{a||null==r.return||r.return()}finally{if(s)throw o}}}}var k="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function S(t){var e={exports:{}};return t(e,e.exports),e.exports}var x=function(t){return t&&t.Math==Math&&t},O=x("object"==("undefined"==typeof globalThis?"undefined":t(globalThis))&&globalThis)||x("object"==("undefined"==typeof window?"undefined":t(window))&&window)||x("object"==("undefined"==typeof self?"undefined":t(self))&&self)||x("object"==t(k)&&k)||function(){return this}()||Function("return this")(),E=function(t){try{return!!t()}catch(t){return!0}},j=!E((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),_={}.propertyIsEnumerable,R=Object.getOwnPropertyDescriptor,P={f:R&&!_.call({1:2},1)?function(t){var e=R(this,t);return!!e&&e.enumerable}:_},A=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}},T={}.toString,F=function(t){return T.call(t).slice(8,-1)},I="".split,C=E((function(){return!Object("z").propertyIsEnumerable(0)}))?function(t){return"String"==F(t)?I.call(t,""):Object(t)}:Object,L=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t},N=function(t){return C(L(t))},z=function(e){return"object"===t(e)?null!==e:"function"==typeof e},M=function(t,e){if(!z(t))return t;var r,n;if(e&&"function"==typeof(r=t.toString)&&!z(n=r.call(t)))return n;if("function"==typeof(r=t.valueOf)&&!z(n=r.call(t)))return n;if(!e&&"function"==typeof(r=t.toString)&&!z(n=r.call(t)))return n;throw TypeError("Can't convert object to primitive value")},D={}.hasOwnProperty,U=function(t,e){return D.call(t,e)},H=O.document,B=z(H)&&z(H.createElement),G=function(t){return B?H.createElement(t):{}},q=!j&&!E((function(){return 7!=Object.defineProperty(G("div"),"a",{get:function(){return 7}}).a})),$=Object.getOwnPropertyDescriptor,V={f:j?$:function(t,e){if(t=N(t),e=M(e,!0),q)try{return $(t,e)}catch(t){}if(U(t,e))return A(!P.f.call(t,e),t[e])}},Y=function(t){if(!z(t))throw TypeError(String(t)+" is not an object");return t},X=Object.defineProperty,K={f:j?X:function(t,e,r){if(Y(t),e=M(e,!0),Y(r),q)try{return X(t,e,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported");return"value"in r&&(t[e]=r.value),t}},W=j?function(t,e,r){return K.f(t,e,A(1,r))}:function(t,e,r){return t[e]=r,t},J=function(t,e){try{W(O,t,e)}catch(r){O[t]=e}return e},Z=O["__core-js_shared__"]||J("__core-js_shared__",{}),Q=Function.toString;"function"!=typeof Z.inspectSource&&(Z.inspectSource=function(t){return Q.call(t)});var tt,et,rt,nt=Z.inspectSource,it=O.WeakMap,ot="function"==typeof it&&/native code/.test(nt(it)),at=S((function(t){(t.exports=function(t,e){return Z[t]||(Z[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.8.3",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"})})),st=0,ut=Math.random(),ct=function(t){return"Symbol("+String(void 0===t?"":t)+")_"+(++st+ut).toString(36)},lt=at("keys"),ft=function(t){return lt[t]||(lt[t]=ct(t))},ht={},pt=O.WeakMap;if(ot){var dt=Z.state||(Z.state=new pt),vt=dt.get,yt=dt.has,gt=dt.set;tt=function(t,e){return e.facade=t,gt.call(dt,t,e),e},et=function(t){return vt.call(dt,t)||{}},rt=function(t){return yt.call(dt,t)}}else{var mt=ft("state");ht[mt]=!0,tt=function(t,e){return e.facade=t,W(t,mt,e),e},et=function(t){return U(t,mt)?t[mt]:{}},rt=function(t){return U(t,mt)}}var bt,wt,kt={set:tt,get:et,has:rt,enforce:function(t){return rt(t)?et(t):tt(t,{})},getterFor:function(t){return function(e){var r;if(!z(e)||(r=et(e)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return r}}},St=S((function(t){var e=kt.get,r=kt.enforce,n=String(String).split("String");(t.exports=function(t,e,i,o){var a,s=!!o&&!!o.unsafe,u=!!o&&!!o.enumerable,c=!!o&&!!o.noTargetGet;"function"==typeof i&&("string"!=typeof e||U(i,"name")||W(i,"name",e),(a=r(i)).source||(a.source=n.join("string"==typeof e?e:""))),t!==O?(s?!c&&t[e]&&(u=!0):delete t[e],u?t[e]=i:W(t,e,i)):u?t[e]=i:J(e,i)})(Function.prototype,"toString",(function(){return"function"==typeof this&&e(this).source||nt(this)}))})),xt=O,Ot=function(t){return"function"==typeof t?t:void 0},Et=function(t,e){return arguments.length<2?Ot(xt[t])||Ot(O[t]):xt[t]&&xt[t][e]||O[t]&&O[t][e]},jt=Math.ceil,_t=Math.floor,Rt=function(t){return isNaN(t=+t)?0:(t>0?_t:jt)(t)},Pt=Math.min,At=function(t){return t>0?Pt(Rt(t),9007199254740991):0},Tt=Math.max,Ft=Math.min,It=function(t,e){var r=Rt(t);return r<0?Tt(r+e,0):Ft(r,e)},Ct=function(t){return function(e,r,n){var i,o=N(e),a=At(o.length),s=It(n,a);if(t&&r!=r){for(;a>s;)if((i=o[s++])!=i)return!0}else for(;a>s;s++)if((t||s in o)&&o[s]===r)return t||s||0;return!t&&-1}},Lt={includes:Ct(!0),indexOf:Ct(!1)},Nt=Lt.indexOf,zt=function(t,e){var r,n=N(t),i=0,o=[];for(r in n)!U(ht,r)&&U(n,r)&&o.push(r);for(;e.length>i;)U(n,r=e[i++])&&(~Nt(o,r)||o.push(r));return o},Mt=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],Dt=Mt.concat("length","prototype"),Ut={f:Object.getOwnPropertyNames||function(t){return zt(t,Dt)}},Ht={f:Object.getOwnPropertySymbols},Bt=Et("Reflect","ownKeys")||function(t){var e=Ut.f(Y(t)),r=Ht.f;return r?e.concat(r(t)):e},Gt=function(t,e){for(var r=Bt(e),n=K.f,i=V.f,o=0;o=74)&&(bt=le.match(/Chrome\/(\d+)/))&&(wt=bt[1]);var de=wt&&+wt,ve=se("species"),ye=function(t){return de>=51||!E((function(){var e=[];return(e.constructor={})[ve]=function(){return{foo:1}},1!==e[t](Boolean).foo}))},ge=se("isConcatSpreadable"),me=de>=51||!E((function(){var t=[];return t[ge]=!1,t.concat()[0]!==t})),be=ye("concat"),we=function(t){if(!z(t))return!1;var e=t[ge];return void 0!==e?!!e:Qt(t)};Zt({target:"Array",proto:!0,forced:!me||!be},{concat:function(t){var e,r,n,i,o,a=te(this),s=ce(a,0),u=0;for(e=-1,n=arguments.length;e9007199254740991)throw TypeError("Maximum allowed index exceeded");for(r=0;r=9007199254740991)throw TypeError("Maximum allowed index exceeded");ee(s,u++,o)}return s.length=u,s}});var ke=function(t){if("function"!=typeof t)throw TypeError(String(t)+" is not a function");return t},Se=function(t,e,r){if(ke(t),void 0===e)return t;switch(r){case 0:return function(){return t.call(e)};case 1:return function(r){return t.call(e,r)};case 2:return function(r,n){return t.call(e,r,n)};case 3:return function(r,n,i){return t.call(e,r,n,i)}}return function(){return t.apply(e,arguments)}},xe=[].push,Oe=function(t){var e=1==t,r=2==t,n=3==t,i=4==t,o=6==t,a=7==t,s=5==t||o;return function(u,c,l,f){for(var h,p,d=te(u),v=C(d),y=Se(c,l,3),g=At(v.length),m=0,b=f||ce,w=e?b(u,g):r||a?b(u,0):void 0;g>m;m++)if((s||m in v)&&(p=y(h=v[m],m,d),t))if(e)w[m]=p;else if(p)switch(t){case 3:return!0;case 5:return h;case 6:return m;case 2:xe.call(w,h)}else switch(t){case 4:return!1;case 7:xe.call(w,h)}return o?-1:n||i?i:w}},Ee={forEach:Oe(0),map:Oe(1),filter:Oe(2),some:Oe(3),every:Oe(4),find:Oe(5),findIndex:Oe(6),filterOut:Oe(7)},je=Object.defineProperty,_e={},Re=function(t){throw t},Pe=function(t,e){if(U(_e,t))return _e[t];e||(e={});var r=[][t],n=!!U(e,"ACCESSORS")&&e.ACCESSORS,i=U(e,0)?e[0]:Re,o=U(e,1)?e[1]:void 0;return _e[t]=!!r&&!E((function(){if(n&&!j)return!0;var t={length:-1};n?je(t,1,{enumerable:!0,get:Re}):t[1]=1,r.call(t,i,o)}))},Ae=Ee.filter,Te=ye("filter"),Fe=Pe("filter");Zt({target:"Array",proto:!0,forced:!Te||!Fe},{filter:function(t){return Ae(this,t,arguments.length>1?arguments[1]:void 0)}});var Ie,Ce=Object.keys||function(t){return zt(t,Mt)},Le=j?Object.defineProperties:function(t,e){Y(t);for(var r,n=Ce(e),i=n.length,o=0;i>o;)K.f(t,r=n[o++],e[r]);return t},Ne=Et("document","documentElement"),ze=ft("IE_PROTO"),Me=function(){},De=function(t){return"