diff --git a/js/actions/contract_agreement_list_actions.js b/js/actions/contract_agreement_list_actions.js index 94f292c5..86988f47 100644 --- a/js/actions/contract_agreement_list_actions.js +++ b/js/actions/contract_agreement_list_actions.js @@ -37,11 +37,11 @@ class ContractAgreementListActions { fetchAvailableContractAgreementList(issuer){ return Q.Promise((resolve, reject) => { - this.actions.fetchContractAgreementList(issuer, 'True', null) + this.actions.fetchContractAgreementList(issuer, true, null) .then((contractAgreementListAccepted) => { if (!contractAgreementListAccepted) { // fetch pending agreements if no accepted ones - return this.actions.fetchContractAgreementList(issuer, null, 'True'); + return this.actions.fetchContractAgreementList(issuer, null, true); } else { resolve(contractAgreementListAccepted); diff --git a/js/app.js b/js/app.js index 5ad36d28..bd9e79be 100644 --- a/js/app.js +++ b/js/app.js @@ -46,7 +46,6 @@ requests.defaults({ class AppGateway { - start() { let settings; let subdomain = window.location.host.split('.')[0]; diff --git a/js/components/acl_proxy.js b/js/components/acl_proxy.js index 10a7516e..4fc90a9b 100644 --- a/js/components/acl_proxy.js +++ b/js/components/acl_proxy.js @@ -21,7 +21,7 @@ let AclProxy = React.createClass({ }, getChildren() { - if (this.props.children.length && this.props.children.length > 1){ + if (React.Children.count(this.props.children) > 1){ /* This might ruin styles for header items in the navbar etc */ diff --git a/js/components/ascribe_forms/form.js b/js/components/ascribe_forms/form.js index 47703ded..f7b1f76f 100644 --- a/js/components/ascribe_forms/form.js +++ b/js/components/ascribe_forms/form.js @@ -65,12 +65,12 @@ let Form = React.createClass({ reset() { // If onReset prop is defined from outside, // notify component that a form reset is happening. - if(this.props.onReset && typeof this.props.onReset === 'function') { + if(typeof this.props.onReset === 'function') { this.props.onReset(); } for(let ref in this.refs) { - if (this.refs[ref].reset && typeof this.refs[ref].reset === 'function'){ + if(typeof this.refs[ref].reset === 'function') { this.refs[ref].reset(); } } @@ -123,11 +123,12 @@ let Form = React.createClass({ getFormData() { let data = {}; - for(let ref in this.refs){ + + for(let ref in this.refs) { data[this.refs[ref].props.name] = this.refs[ref].state.value; } - if (this.props.getFormData && typeof this.props.getFormData === 'function'){ + if(typeof this.props.getFormData === 'function') { data = mergeOptionsWithDuplicates(data, this.props.getFormData()); } @@ -135,16 +136,16 @@ let Form = React.createClass({ }, handleChangeChild(){ - this.setState({edited: true}); + this.setState({ edited: true }); }, handleSuccess(response){ - if(this.props.handleSuccess && typeof this.props.handleSuccess === 'function') { + if(typeof this.props.handleSuccess === 'function') { this.props.handleSuccess(response); } for(let ref in this.refs) { - if(this.refs[ref] && this.refs[ref].handleSuccess && typeof this.refs[ref].handleSuccess === 'function'){ + if(this.refs[ref] && typeof this.refs[ref].handleSuccess === 'function'){ this.refs[ref].handleSuccess(); } } @@ -163,8 +164,7 @@ let Form = React.createClass({ this.setState({errors: this.state.errors.concat(err.json.errors[input])}); } } - } - else { + } else { let formData = this.getFormData(); // sentry shouldn't post the user's password @@ -187,7 +187,7 @@ let Form = React.createClass({ clearErrors(){ for(let ref in this.refs){ - if (this.refs[ref] && this.refs[ref].clearErrors && typeof this.refs[ref].clearErrors === 'function'){ + if (this.refs[ref] && typeof this.refs[ref].clearErrors === 'function'){ this.refs[ref].clearErrors(); } } diff --git a/js/components/ascribe_forms/form_loan.js b/js/components/ascribe_forms/form_loan.js index 8e83ca34..dacbae77 100644 --- a/js/components/ascribe_forms/form_loan.js +++ b/js/components/ascribe_forms/form_loan.js @@ -57,6 +57,15 @@ let LoanForm = React.createClass({ this.getContractAgreementsOrCreatePublic(this.props.email); }, + componentWillReceiveProps(nextProps) { + // however, it can also be that at the time the component is mounting, + // the email is not defined (because it's asynchronously fetched from the server). + // Then we need to update it as soon as it is included into LoanForm's props. + if(nextProps && nextProps.email) { + this.getContractAgreementsOrCreatePublic(nextProps.email); + } + }, + componentWillUnmount() { ContractAgreementListStore.unlisten(this.onChange); }, @@ -66,11 +75,12 @@ let LoanForm = React.createClass({ }, getContractAgreementsOrCreatePublic(email){ + ContractAgreementListActions.flushContractAgreementList(); if (email) { ContractAgreementListActions.fetchAvailableContractAgreementList(email).then( (contractAgreementList) => { if (!contractAgreementList) { - ContractAgreementListActions.createContractAgreementFromPublicContract.defer(email); + ContractAgreementListActions.createContractAgreementFromPublicContract(email); } } ); diff --git a/js/components/ascribe_forms/form_register_piece.js b/js/components/ascribe_forms/form_register_piece.js index 8f2666c0..fbbc330a 100644 --- a/js/components/ascribe_forms/form_register_piece.js +++ b/js/components/ascribe_forms/form_register_piece.js @@ -13,7 +13,7 @@ import ApiUrls from '../../constants/api_urls'; import { getLangText } from '../../utils/lang_utils'; import { mergeOptions } from '../../utils/general_utils'; -import { isReadyForFormSubmission } from '../ascribe_uploader/react_s3_fine_uploader_utils'; +import { formSubmissionValidation } from '../ascribe_uploader/react_s3_fine_uploader_utils'; let RegisterPieceForm = React.createClass({ @@ -100,7 +100,7 @@ let RegisterPieceForm = React.createClass({ ignoreFocus={true}> -1) { + inputDOMNode.value = this.state.initialValue; + } // For some inputs, reseting state.value is not enough to visually reset the // component. // // So if the input actually needs a visual reset, it needs to implement // a dedicated reset method. - if(this.refs.input.reset && typeof this.refs.input.reset === 'function') { - this.refs.input.reset(); + if(typeof input.reset === 'function') { + input.reset(); } }, handleChange(event) { - this.props.handleChange(event); - if (this.props.onChange && typeof this.props.onChange === 'function') { + if (typeof this.props.onChange === 'function') { this.props.onChange(event); } @@ -130,7 +143,7 @@ let Property = React.createClass({ // if onClick is defined from the outside, // just call it - if(this.props.onClick && typeof this.props.onClick === 'function') { + if(typeof this.props.onClick === 'function') { this.props.onClick(); } @@ -145,7 +158,7 @@ let Property = React.createClass({ isFocused: false }); - if(this.props.onBlur && typeof this.props.onBlur === 'function') { + if(typeof this.props.onBlur === 'function') { this.props.onBlur(event); } }, @@ -237,7 +250,7 @@ let Property = React.createClass({ overlay={tooltip}>
{this.state.errors} - { this.props.label} + {this.props.label} {this.renderChildren(style)} {footer}
diff --git a/js/components/ascribe_media/media_player.js b/js/components/ascribe_media/media_player.js index e4b69c69..e767a800 100644 --- a/js/components/ascribe_media/media_player.js +++ b/js/components/ascribe_media/media_player.js @@ -208,7 +208,8 @@ let MediaPlayer = React.createClass({
You can leave this page and check back on the status later.

+ label="%(percent)s%" + className="ascribe-progress-bar" /> ); } else { diff --git a/js/components/ascribe_uploader/file_drag_and_drop.js b/js/components/ascribe_uploader/file_drag_and_drop.js index 7d6c8a66..312b504d 100644 --- a/js/components/ascribe_uploader/file_drag_and_drop.js +++ b/js/components/ascribe_uploader/file_drag_and_drop.js @@ -1,7 +1,7 @@ 'use strict'; import React from 'react'; -import ProgressBar from 'react-progressbar'; +import ProgressBar from 'react-bootstrap/lib/ProgressBar'; import FileDragAndDropDialog from './file_drag_and_drop_dialog'; import FileDragAndDropPreviewIterator from './file_drag_and_drop_preview_iterator'; @@ -169,12 +169,16 @@ let FileDragAndDrop = React.createClass({ if(this.props.hashingProgress !== -2) { return (
-

{getLangText('Computing hash(es)... This may take a few minutes.')}

-

- {Math.ceil(this.props.hashingProgress)}% - {getLangText('Cancel hashing')} -

- +
+

{getLangText('Computing hash(es)... This may take a few minutes.')}

+

+ {getLangText('Cancel hashing')} +

+ +
); } else { diff --git a/js/components/ascribe_uploader/file_drag_and_drop_dialog.js b/js/components/ascribe_uploader/file_drag_and_drop_dialog.js index f5399f9c..0cb14be7 100644 --- a/js/components/ascribe_uploader/file_drag_and_drop_dialog.js +++ b/js/components/ascribe_uploader/file_drag_and_drop_dialog.js @@ -32,7 +32,7 @@ let FileDragAndDropDialog = React.createClass({ queryParamsUpload.method = 'upload'; return ( - +

{getLangText('Would you rather')}

- +
); } else { if(this.props.multipleFiles) { return ( - +

{getLangText('Drag files here')}

{getLangText('or')}

{getLangText('choose files to upload')} - +
); } else { let dialog = queryParams.method === 'hash' ? getLangText('choose a file to hash') : getLangText('choose a file to upload'); return ( - +

{getLangText('Drag a file here')}

{getLangText('or')}

{dialog} - +
); } } diff --git a/js/components/ascribe_uploader/file_drag_and_drop_preview.js b/js/components/ascribe_uploader/file_drag_and_drop_preview.js index 9c6cdbdd..05c4a688 100644 --- a/js/components/ascribe_uploader/file_drag_and_drop_preview.js +++ b/js/components/ascribe_uploader/file_drag_and_drop_preview.js @@ -72,7 +72,7 @@ let FileDragAndDropPreview = React.createClass({ if(this.props.areAssetsEditable) { removeBtn = (
-
); diff --git a/js/components/ascribe_uploader/file_drag_and_drop_preview_iterator.js b/js/components/ascribe_uploader/file_drag_and_drop_preview_iterator.js index 39ee67f7..ec1dd181 100644 --- a/js/components/ascribe_uploader/file_drag_and_drop_preview_iterator.js +++ b/js/components/ascribe_uploader/file_drag_and_drop_preview_iterator.js @@ -3,6 +3,10 @@ import React from 'react'; import FileDragAndDropPreview from './file_drag_and_drop_preview'; +import FileDragAndDropPreviewProgress from './file_drag_and_drop_preview_progress'; + +import { displayValidFilesFilter } from './react_s3_fine_uploader_utils'; + let FileDragAndDropPreviewIterator = React.createClass({ propTypes: { @@ -16,26 +20,37 @@ let FileDragAndDropPreviewIterator = React.createClass({ }, render() { - if(this.props.files) { + let { + files, + handleDeleteFile, + handleCancelFile, + handlePauseFile, + handleResumeFile, + areAssetsDownloadable, + areAssetsEditable + } = this.props; + + files = files.filter(displayValidFilesFilter); + + if(files && files.length > 0) { return ( -
- {this.props.files.map((file, i) => { - if(file.status !== 'deleted' && file.status !== 'canceled' && file.size !== -1) { +
+
+ {files.map((file, i) => { return ( + handleDeleteFile={handleDeleteFile} + handleCancelFile={handleCancelFile} + handlePauseFile={handlePauseFile} + handleResumeFile={handleResumeFile} + areAssetsDownloadable={areAssetsDownloadable} + areAssetsEditable={areAssetsEditable}/> ); - } else { - return null; - } - })} + })} +
+
); } else { diff --git a/js/components/ascribe_uploader/file_drag_and_drop_preview_other.js b/js/components/ascribe_uploader/file_drag_and_drop_preview_other.js index 1d948572..2528a9d7 100644 --- a/js/components/ascribe_uploader/file_drag_and_drop_preview_other.js +++ b/js/components/ascribe_uploader/file_drag_and_drop_preview_other.js @@ -1,7 +1,7 @@ 'use strict'; import React from 'react'; -import ProgressBar from 'react-progressbar'; +import ProgressBar from 'react-bootstrap/lib/ProgressBar'; import AppConstants from '../../constants/application_constants'; import { getLangText } from '../../utils/lang_utils.js'; @@ -55,7 +55,9 @@ let FileDragAndDropPreviewOther = React.createClass({ return (
- +
{actionSymbol} diff --git a/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js new file mode 100644 index 00000000..d1b34f41 --- /dev/null +++ b/js/components/ascribe_uploader/file_drag_and_drop_preview_progress.js @@ -0,0 +1,64 @@ +'use strict'; + +import React from 'react'; + +import ProgressBar from 'react-bootstrap/lib/ProgressBar'; + +import { displayValidProgressFilesFilter } from './react_s3_fine_uploader_utils'; + + +let FileDragAndDropPreviewProgress = React.createClass({ + propTypes: { + files: React.PropTypes.array + }, + + calcOverallFileSize() { + let overallFileSize = 0; + let files = this.props.files.filter(displayValidProgressFilesFilter); + + // We just sum up all files' sizes + for(let i = 0; i < files.length; i++) { + overallFileSize += files[i].size; + } + + return overallFileSize; + }, + + calcOverallProgress() { + let overallProgress = 0; + let overallFileSize = this.calcOverallFileSize(); + let files = this.props.files.filter(displayValidProgressFilesFilter); + + // We calculate the overall progress by summing the individuals + // files' progresses in relation to their size + for(let i = 0; i < files.length; i++) { + overallProgress += files[i].size / overallFileSize * files[i].progress; + } + + return overallProgress; + }, + + render() { + let overallProgress = this.calcOverallProgress(); + let overallFileSize = this.calcOverallFileSize(); + let style = { + visibility: 'hidden' + }; + + // only visible if overallProgress is over zero + // or the overallFileSize is greater than 10MB + if(overallProgress !== 0 && overallFileSize > 10000000) { + style.visibility = 'visible'; + } + + return ( + + ); + } +}); + +export default FileDragAndDropPreviewProgress; \ No newline at end of file diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader.js b/js/components/ascribe_uploader/react_s3_fine_uploader.js index 6f0d7a90..4fba1a82 100644 --- a/js/components/ascribe_uploader/react_s3_fine_uploader.js +++ b/js/components/ascribe_uploader/react_s3_fine_uploader.js @@ -4,9 +4,6 @@ import React from 'react/addons'; import Router from 'react-router'; import Q from 'q'; -import { getCookie } from '../../utils/fetch_api_utils'; -import { getLangText } from '../../utils/lang_utils'; - import S3Fetcher from '../../fetchers/s3_fetcher'; import fineUploader from 'fineUploader'; @@ -18,8 +15,11 @@ import GlobalNotificationActions from '../../actions/global_notification_actions import AppConstants from '../../constants/application_constants'; import { computeHashOfFile } from '../../utils/file_utils'; +import { displayValidFilesFilter } from './react_s3_fine_uploader_utils'; +import { getCookie } from '../../utils/fetch_api_utils'; +import { getLangText } from '../../utils/lang_utils'; -var ReactS3FineUploader = React.createClass({ +let ReactS3FineUploader = React.createClass({ propTypes: { keyRoutine: React.PropTypes.shape({ url: React.PropTypes.string, @@ -343,11 +343,9 @@ var ReactS3FineUploader = React.createClass({ completed: false }; - let newState = React.addons.update(this.state, { - startedChunks: { $set: chunks } - }); + let startedChunks = React.addons.update(this.state.startedChunks, { $set: chunks }); - this.setState(newState); + this.setState({ startedChunks }); }, onUploadChunkSuccess(id, chunkData, responseJson, xhr) { @@ -360,11 +358,9 @@ var ReactS3FineUploader = React.createClass({ chunks[chunkKey].responseJson = responseJson; chunks[chunkKey].xhr = xhr; - let newState = React.addons.update(this.state, { - startedChunks: { $set: chunks } - }); + let startedChunks = React.addons.update(this.state.startedChunks, { $set: chunks }); - this.setState(newState); + this.setState({ startedChunks }); } }, @@ -384,11 +380,8 @@ var ReactS3FineUploader = React.createClass({ files[id].status = 'upload successful'; files[id].key = this.state.uploader.getKey(id); - let newState = React.addons.update(this.state, { - filesToUpload: { $set: files } - }); - - this.setState(newState); + let filesToUpload = React.addons.update(this.state.filesToUpload, { $set: files }); + this.setState({ filesToUpload }); // Only after the blob has been created server-side, we can make the form submittable. this.createBlob(files[id]) @@ -470,15 +463,17 @@ var ReactS3FineUploader = React.createClass({ } else { console.warn('You didn\'t define the functions isReadyForFormSubmission and/or setIsUploadReady in as a prop in react-s3-fine-uploader'); } + + return true; }, onProgress(id, name, uploadedBytes, totalBytes) { - let newState = React.addons.update(this.state, { - filesToUpload: { [id]: { - progress: { $set: (uploadedBytes / totalBytes) * 100} } + let filesToUpload = React.addons.update(this.state.filesToUpload, { + [id]: { + progress: { $set: (uploadedBytes / totalBytes) * 100} } }); - this.setState(newState); + this.setState({ filesToUpload }); }, onSessionRequestComplete(response, success) { @@ -500,8 +495,9 @@ var ReactS3FineUploader = React.createClass({ return file; }); - let newState = React.addons.update(this.state, {filesToUpload: {$set: updatedFilesToUpload}}); - this.setState(newState); + let filesToUpload = React.addons.update(this.state.filesToUpload, {$set: updatedFilesToUpload}); + + this.setState({filesToUpload }); } else { // server has to respond with 204 //let notification = new GlobalNotificationModel('Could not load attached files (Further data)', 'danger', 10000); @@ -513,13 +509,11 @@ var ReactS3FineUploader = React.createClass({ onDeleteComplete(id, xhr, isError) { if(isError) { - let notification = new GlobalNotificationModel(getLangText('Couldn\'t delete file'), 'danger', 10000); + this.setStatusOfFile(id, 'online'); + + let notification = new GlobalNotificationModel(getLangText('There was an error deleting your file.'), 'danger', 10000); GlobalNotificationActions.appendGlobalNotification(notification); } else { - - // To hide the file in this component, we need to set it's status to "deleted" - this.setStatusOfFile(id, 'deleted'); - let notification = new GlobalNotificationModel(getLangText('File deleted'), 'success', 5000); GlobalNotificationActions.appendGlobalNotification(notification); } @@ -541,6 +535,13 @@ var ReactS3FineUploader = React.createClass({ }, handleDeleteFile(fileId) { + // We set the files state to 'deleted' immediately, so that the user is not confused with + // the unresponsiveness of the UI + // + // If there is an error during the deletion, we will just change the status back to 'online' + // and display an error message + this.setStatusOfFile(fileId, 'deleted'); + // In some instances (when the file was already uploaded and is just displayed to the user // - for example in the contract or additional files dialog) // fineuploader does not register an id on the file (we do, don't be confused by this!). @@ -558,8 +559,6 @@ var ReactS3FineUploader = React.createClass({ // promise } else { let fileToDelete = this.state.filesToUpload[fileId]; - fileToDelete.status = 'deleted'; - S3Fetcher .deleteFile(fileToDelete.s3Key, fileToDelete.s3Bucket) .then(() => this.onDeleteComplete(fileToDelete.id, null, false)) @@ -591,7 +590,7 @@ var ReactS3FineUploader = React.createClass({ handleUploadFile(files) { // If multiple set and user already uploaded its work, // cancel upload - if(!this.props.multiple && this.state.filesToUpload.filter((file) => file.status !== 'deleted' && file.status !== 'canceled').length > 0) { + if(!this.props.multiple && this.state.filesToUpload.filter(displayValidFilesFilter).length > 0) { return; } @@ -606,7 +605,7 @@ var ReactS3FineUploader = React.createClass({ files = validFiles; // Call this method to signal the outside component that an upload is in progress - if(this.props.uploadStarted && typeof this.props.uploadStarted === 'function' && files.length > 0) { + if(typeof this.props.uploadStarted === 'function' && files.length > 0) { this.props.uploadStarted(); } @@ -747,6 +746,7 @@ var ReactS3FineUploader = React.createClass({ synchronizeFileLists(files) { let oldFiles = this.state.filesToUpload; let oldAndNewFiles = this.state.uploader.getUploads(); + // Add fineuploader specific information to new files for(let i = 0; i < oldAndNewFiles.length; i++) { for(let j = 0; j < files.length; j++) { @@ -761,6 +761,22 @@ var ReactS3FineUploader = React.createClass({ // and re-add fineuploader specific information for old files as well for(let i = 0; i < oldAndNewFiles.length; i++) { for(let j = 0; j < oldFiles.length; j++) { + + // EXCEPTION: + // + // Files do not necessarily come from the user's hard drive but can also be fetched + // from Amazon S3. This is handled in onSessionRequestComplete. + // + // If the user deletes one of those files, then fineuploader will still keep it in his + // files array but with key, progress undefined and size === -1 but + // status === 'upload successful'. + // This poses a problem as we depend on the amount of files that have + // status === 'upload successful', therefore once the file is synced, + // we need to tag its status as 'deleted' (which basically happens here) + if(oldAndNewFiles[i].size === -1 && (!oldAndNewFiles[i].progress || oldAndNewFiles[i].progress === 0)) { + oldAndNewFiles[i].status = 'deleted'; + } + if(oldAndNewFiles[i].originalName === oldFiles[j].name) { oldAndNewFiles[i].progress = oldFiles[j].progress; oldAndNewFiles[i].type = oldFiles[j].type; @@ -771,30 +787,23 @@ var ReactS3FineUploader = React.createClass({ } // set the new file array - let newState = React.addons.update(this.state, { - filesToUpload: { $set: oldAndNewFiles } - }); - this.setState(newState); + let filesToUpload = React.addons.update(this.state.filesToUpload, { $set: oldAndNewFiles }); + + this.setState({ filesToUpload }); }, setStatusOfFile(fileId, status) { - // also, sync files from state with the ones from fineuploader - let filesToUpload = JSON.parse(JSON.stringify(this.state.filesToUpload)); + let changeSet = {}; - filesToUpload[fileId].status = status; - - // is status is set to deleted or canceled, we also need to reset the progress - // back to zero if(status === 'deleted' || status === 'canceled') { - filesToUpload[fileId].progress = 0; + changeSet.progress = { $set: 0 }; } - // set state - let newState = React.addons.update(this.state, { - filesToUpload: { $set: filesToUpload } - }); + changeSet.status = { $set: status }; - this.setState(newState); + let filesToUpload = React.addons.update(this.state.filesToUpload, { [fileId]: changeSet }); + + this.setState({ filesToUpload }); }, isDropzoneInactive() { diff --git a/js/components/ascribe_uploader/react_s3_fine_uploader_utils.js b/js/components/ascribe_uploader/react_s3_fine_uploader_utils.js index dbbfd63f..92d5c2ba 100644 --- a/js/components/ascribe_uploader/react_s3_fine_uploader_utils.js +++ b/js/components/ascribe_uploader/react_s3_fine_uploader_utils.js @@ -31,4 +31,24 @@ export const formSubmissionValidation = { return false; } } -}; \ No newline at end of file +}; + +/** + * Filter function for filtering all deleted and canceled files + * @param {object} file A file from filesToUpload that has status as a prop. + * @return {boolean} + */ +export function displayValidFilesFilter(file) { + return file.status !== 'deleted' && file.status !== 'canceled'; +} + + +/** + * Filter function for which files to integrate in the progress process + * @param {object} file A file from filesToUpload, that has a status as a prop. + * @return {boolean} + */ +export function displayValidProgressFilesFilter(file) { + return file.status !== 'deleted' && file.status !== 'canceled' && file.status !== 'online'; +} + diff --git a/js/components/ascribe_uploader/vendor/s3.fine-uploader.js b/js/components/ascribe_uploader/vendor/s3.fine-uploader.js index e0f096df..5b90cf5a 100644 --- a/js/components/ascribe_uploader/vendor/s3.fine-uploader.js +++ b/js/components/ascribe_uploader/vendor/s3.fine-uploader.js @@ -3,7 +3,7 @@ * * Copyright 2015, Widen Enterprises, Inc. info@fineuploader.com * -* Version: 5.2.2 +* Version: 5.3.0 * * Homepage: http://fineuploader.com * @@ -894,7 +894,7 @@ var qq = function(element) { }()); /*global qq */ -qq.version = "5.2.2"; +qq.version = "5.3.0"; /* globals qq */ qq.supportedFeatures = (function() { @@ -1928,6 +1928,10 @@ qq.status = { this._endpointStore.set(endpoint, id); }, + setForm: function(elementOrId) { + this._updateFormSupportAndParams(elementOrId); + }, + setItemLimit: function(newItemLimit) { this._currentItemLimit = newItemLimit; }, @@ -1945,16 +1949,11 @@ qq.status = { }, uploadStoredFiles: function() { - var idToUpload; - if (this._storedIds.length === 0) { this._itemError("noFilesError"); } else { - while (this._storedIds.length) { - idToUpload = this._storedIds.shift(); - this._uploadFile(idToUpload); - } + this._uploadStoredFiles(); } } }; @@ -2038,10 +2037,11 @@ qq.status = { }); }, - _createStore: function(initialValue, readOnlyValues) { + _createStore: function(initialValue, _readOnlyValues_) { var store = {}, catchall = initialValue, perIdReadOnlyValues = {}, + readOnlyValues = _readOnlyValues_, copy = function(orig) { if (qq.isObject(orig)) { return qq.extend({}, orig); @@ -2095,8 +2095,20 @@ qq.status = { addReadOnly: function(id, values) { // Only applicable to Object stores if (qq.isObject(store)) { - perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {}; - qq.extend(perIdReadOnlyValues[id], values); + // If null ID, apply readonly values to all files + if (id === null) { + if (qq.isFunction(values)) { + readOnlyValues = values; + } + else { + readOnlyValues = readOnlyValues || {}; + qq.extend(readOnlyValues, values); + } + } + else { + perIdReadOnlyValues[id] = perIdReadOnlyValues[id] || {}; + qq.extend(perIdReadOnlyValues[id], values); + } } }, @@ -2882,7 +2894,7 @@ qq.status = { _onBeforeManualRetry: function(id) { var itemLimit = this._currentItemLimit, fileName; - console.log(this._handler.isValid(id)); + if (this._preventRetries[id]) { this.log("Retries are forbidden for id " + id, "warn"); return false; @@ -3005,13 +3017,14 @@ qq.status = { this._onSubmit.apply(this, arguments); this._uploadData.setStatus(id, qq.status.SUBMITTED); this._onSubmitted.apply(this, arguments); - this._options.callbacks.onSubmitted.apply(this, arguments); if (this._options.autoUpload) { + this._options.callbacks.onSubmitted.apply(this, arguments); this._uploadFile(id); } else { this._storeForLater(id); + this._options.callbacks.onSubmitted.apply(this, arguments); } }, @@ -3238,6 +3251,23 @@ qq.status = { } }, + _updateFormSupportAndParams: function(formElementOrId) { + this._options.form.element = formElementOrId; + + this._formSupport = qq.FormSupport && new qq.FormSupport( + this._options.form, qq.bind(this.uploadStoredFiles, this), qq.bind(this.log, this) + ); + + if (this._formSupport && this._formSupport.attachedToForm) { + this._paramsStore.addReadOnly(null, this._formSupport.getFormInputsAsObject); + + this._options.autoUpload = this._formSupport.newAutoUpload; + if (this._formSupport.newEndpoint) { + this.setEndpoint(this._formSupport.newEndpoint); + } + } + }, + _upload: function(id, params, endpoint) { var name = this.getName(id); @@ -3264,6 +3294,25 @@ qq.status = { } }, + _uploadStoredFiles: function() { + var idToUpload, stillSubmitting, + self = this; + + while (this._storedIds.length) { + idToUpload = this._storedIds.shift(); + this._uploadFile(idToUpload); + } + + // If we are still waiting for some files to clear validation, attempt to upload these again in a bit + stillSubmitting = this.getUploads({status: qq.status.SUBMITTING}).length; + if (stillSubmitting) { + qq.log("Still waiting for " + stillSubmitting + " files to clear submit queue. Will re-parse stored IDs array shortly."); + setTimeout(function() { + self._uploadStoredFiles(); + }, 1000); + } + }, + /** * Performs some internal validation checks on an item, defined in the `validation` option. * @@ -5271,6 +5320,7 @@ qq.XhrUploadHandler = function(spec) { */ getResumableFilesData: function() { var resumableFilesData = []; + handler._iterateResumeRecords(function(key, uploadData) { handler.moveInProgressToRemaining(null, uploadData.chunking.inProgress, uploadData.chunking.remaining); @@ -5461,7 +5511,7 @@ qq.XhrUploadHandler = function(spec) { _iterateResumeRecords: function(callback) { if (resumeEnabled) { qq.each(localStorage, function(key, item) { - if (key.indexOf(qq.format("qq{}resume-", namespace)) === 0) { + if (key.indexOf(qq.format("qq{}resume", namespace)) === 0) { var uploadData = JSON.parse(item); callback(key, uploadData); } @@ -5728,7 +5778,9 @@ qq.WindowReceiveMessage = function(o) { }, getItemByFileId: function(id) { - return this._templating.getFileContainer(id); + if (!this._templating.isHiddenForever(id)) { + return this._templating.getFileContainer(id); + } }, reset: function() { @@ -6238,11 +6290,6 @@ qq.WindowReceiveMessage = function(o) { dontDisplay = this._handler.isProxied(id) && this._options.scaling.hideScaled, record; - // If we don't want this file to appear in the UI, skip all of this UI-related logic. - if (dontDisplay) { - return; - } - if (this._options.display.prependFiles) { if (this._totalFilesInBatch > 1 && this._filesInBatchAddedToUi > 0) { prependIndex = this._filesInBatchAddedToUi - 1; @@ -6274,7 +6321,7 @@ qq.WindowReceiveMessage = function(o) { } } - this._templating.addFile(id, this._options.formatFileName(name), prependData); + this._templating.addFile(id, this._options.formatFileName(name), prependData, dontDisplay); if (canned) { this._thumbnailUrls[id] && this._templating.updateThumbnail(id, this._thumbnailUrls[id], true); @@ -6638,6 +6685,7 @@ qq.Templating = function(spec) { HIDE_DROPZONE_ATTR = "qq-hide-dropzone", DROPZPONE_TEXT_ATTR = "qq-drop-area-text", IN_PROGRESS_CLASS = "qq-in-progress", + HIDDEN_FOREVER_CLASS = "qq-hidden-forever", isCancelDisabled = false, generatedThumbnails = 0, thumbnailQueueMonitorRunning = false, @@ -7273,7 +7321,7 @@ qq.Templating = function(spec) { isCancelDisabled = true; }, - addFile: function(id, name, prependInfo) { + addFile: function(id, name, prependInfo, hideForever) { var fileEl = qq.toElement(templateHtml.fileTemplate), fileNameEl = getTemplateEl(fileEl, selectorClasses.file), uploaderEl = getTemplateEl(container, selectorClasses.uploader), @@ -7296,30 +7344,36 @@ qq.Templating = function(spec) { fileList.appendChild(fileEl); } - hide(getProgress(id)); - hide(getSize(id)); - hide(getDelete(id)); - hide(getRetry(id)); - hide(getPause(id)); - hide(getContinue(id)); - - if (isCancelDisabled) { - this.hideCancel(id); + if (hideForever) { + fileEl.style.display = "none"; + qq(fileEl).addClass(HIDDEN_FOREVER_CLASS); } + else { + hide(getProgress(id)); + hide(getSize(id)); + hide(getDelete(id)); + hide(getRetry(id)); + hide(getPause(id)); + hide(getContinue(id)); - thumb = getThumbnail(id); - if (thumb && !thumb.src) { - cachedWaitingForThumbnailImg.then(function(waitingImg) { - thumb.src = waitingImg.src; - if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) { - qq(thumb).css({ - maxHeight: waitingImg.style.maxHeight, - maxWidth: waitingImg.style.maxWidth - }); - } + if (isCancelDisabled) { + this.hideCancel(id); + } - show(thumb); - }); + thumb = getThumbnail(id); + if (thumb && !thumb.src) { + cachedWaitingForThumbnailImg.then(function(waitingImg) { + thumb.src = waitingImg.src; + if (waitingImg.style.maxHeight && waitingImg.style.maxWidth) { + qq(thumb).css({ + maxHeight: waitingImg.style.maxHeight, + maxWidth: waitingImg.style.maxWidth + }); + } + + show(thumb); + }); + } } }, @@ -7413,6 +7467,10 @@ qq.Templating = function(spec) { icon && qq(icon).addClass(options.classes.editable); }, + isHiddenForever: function(id) { + return qq(getFile(id)).hasClass(HIDDEN_FOREVER_CLASS); + }, + hideEditIcon: function(id) { var icon = getEditIcon(id); @@ -7572,13 +7630,17 @@ qq.Templating = function(spec) { }, generatePreview: function(id, optFileOrBlob) { - thumbGenerationQueue.push({id: id, optFileOrBlob: optFileOrBlob}); - !thumbnailQueueMonitorRunning && generateNextQueuedPreview(); + if (!this.isHiddenForever(id)) { + thumbGenerationQueue.push({id: id, optFileOrBlob: optFileOrBlob}); + !thumbnailQueueMonitorRunning && generateNextQueuedPreview(); + } }, updateThumbnail: function(id, thumbnailUrl, showWaitingImg) { - thumbGenerationQueue.push({update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg}); - !thumbnailQueueMonitorRunning && generateNextQueuedPreview(); + if (!this.isHiddenForever(id)) { + thumbGenerationQueue.push({update: true, id: id, thumbnailUrl: thumbnailUrl, showWaitingImg: showWaitingImg}); + !thumbnailQueueMonitorRunning && generateNextQueuedPreview(); + } }, hasDialog: function(type) { @@ -9489,12 +9551,6 @@ qq.s3.XhrUploadHandler = function(spec, proxy) { result.success, function failure(reason, xhr) { - console.logGlobal(reason + 'in chunked.combine', false, { - uploadId, - etagMap, - result - }); - result.failure(upload.done(id, xhr).response, xhr); } ); @@ -12335,7 +12391,7 @@ qq.Scaler = function(spec, log) { "use strict"; var self = this, - includeReference = spec.sendOriginal, + includeOriginal = spec.sendOriginal, orient = spec.orient, defaultType = spec.defaultType, defaultQuality = spec.defaultQuality / 100, @@ -12385,16 +12441,18 @@ qq.Scaler = function(spec, log) { }); }); - includeReference && records.push({ + records.push({ uuid: originalFileUuid, name: originalFileName, - blob: originalBlob + size: originalBlob.size, + blob: includeOriginal ? originalBlob : null }); } else { records.push({ uuid: originalFileUuid, name: originalFileName, + size: originalBlob.size, blob: originalBlob }); } @@ -12413,19 +12471,17 @@ qq.Scaler = function(spec, log) { proxyGroupId = qq.getUniqueId(); qq.each(self.getFileRecords(uuid, name, file), function(idx, record) { - var relatedBlob = file, - relatedSize = size, + var blobSize = record.size, id; if (record.blob instanceof qq.BlobProxy) { - relatedBlob = record.blob; - relatedSize = -1; + blobSize = -1; } id = uploadData.addFile({ uuid: record.uuid, name: record.name, - size: relatedSize, + size: blobSize, batchId: batchId, proxyGroupId: proxyGroupId }); @@ -12437,10 +12493,13 @@ qq.Scaler = function(spec, log) { originalId = id; } - addFileToHandler(id, relatedBlob); - - fileList.push({id: id, file: relatedBlob}); - + if (record.blob) { + addFileToHandler(id, record.blob); + fileList.push({id: id, file: record.blob}); + } + else { + uploadData.setStatus(id, qq.status.REJECTED); + } }); // If we are potentially uploading an original file and some scaled versions, @@ -12453,8 +12512,8 @@ qq.Scaler = function(spec, log) { qqparentsize: uploadData.retrieve({id: originalId}).size }; - // Make SURE the UUID for each scaled image is sent with the upload request, - // to be consistent (since we need to ensure it is sent for the original file as well). + // Make sure the UUID for each scaled image is sent with the upload request, + // to be consistent (since we may need to ensure it is sent for the original file as well). params[uuidParamName] = uploadData.retrieve({id: scaledId}).uuid; uploadData.setParentId(scaledId, originalId); @@ -14411,4 +14470,4 @@ code.google.com/p/crypto-js/wiki/License C.HmacSHA1 = Hasher._createHmacHelper(SHA1); }()); -/*! 2015-06-09 */ +/*! 2015-08-26 */ diff --git a/js/components/ascribe_uploader/vendor/s3.fine-uploader.min.js b/js/components/ascribe_uploader/vendor/s3.fine-uploader.min.js index ef244d9e..620fcafc 100644 --- a/js/components/ascribe_uploader/vendor/s3.fine-uploader.min.js +++ b/js/components/ascribe_uploader/vendor/s3.fine-uploader.min.js @@ -3,7 +3,7 @@ * * Copyright 2015, Widen Enterprises, Inc. info@fineuploader.com * -* Version: 5.2.2 +* Version: 5.3.0 * * Homepage: http://fineuploader.com * @@ -13,10 +13,10 @@ */ -var qq=function(a){"use strict";return{hide:function(){return a.style.display="none",this},attach:function(b,c){return a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c),function(){qq(a).detach(b,c)}},detach:function(b,c){return a.removeEventListener?a.removeEventListener(b,c,!1):a.attachEvent&&a.detachEvent("on"+b,c),this},contains:function(b){return b?a===b?!0:a.contains?a.contains(b):!!(8&b.compareDocumentPosition(a)):!1},insertBefore:function(b){return b.parentNode.insertBefore(a,b),this},remove:function(){return a.parentNode.removeChild(a),this},css:function(b){if(null==a.style)throw new qq.Error("Can't apply style to node as it is not on the HTMLElement prototype chain!");return null!=b.opacity&&"string"!=typeof a.style.opacity&&"undefined"!=typeof a.filters&&(b.filter="alpha(opacity="+Math.round(100*b.opacity)+")"),qq.extend(a.style,b),this},hasClass:function(b,c){var d=new RegExp("(^| )"+b+"( |$)");return d.test(a.className)||!(!c||!d.test(a.parentNode.className))},addClass:function(b){return qq(a).hasClass(b)||(a.className+=" "+b),this},removeClass:function(b){var c=new RegExp("(^| )"+b+"( |$)");return a.className=a.className.replace(c," ").replace(/^\s+|\s+$/g,""),this},getByClass:function(b){var c,d=[];return a.querySelectorAll?a.querySelectorAll("."+b):(c=a.getElementsByTagName("*"),qq.each(c,function(a,c){qq(c).hasClass(b)&&d.push(c)}),d)},children:function(){for(var b=[],c=a.firstChild;c;)1===c.nodeType&&b.push(c),c=c.nextSibling;return b},setText:function(b){return a.innerText=b,a.textContent=b,this},clearText:function(){return qq(a).setText("")},hasAttribute:function(b){var c;return a.hasAttribute?a.hasAttribute(b)?null==/^false$/i.exec(a.getAttribute(b)):!1:(c=a[b],void 0===c?!1:null==/^false$/i.exec(c))}}};!function(){"use strict";qq.canvasToBlob=function(a,b,c){return qq.dataUriToBlob(a.toDataURL(b,c))},qq.dataUriToBlob=function(a){var b,c,d,e,f=function(a,b){var c=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,d=c&&new c;return d?(d.append(a),d.getBlob(b)):new Blob([a],{type:b})};return c=a.split(",")[0].indexOf("base64")>=0?atob(a.split(",")[1]):decodeURI(a.split(",")[1]),e=a.split(",")[0].split(":")[1].split(";")[0],b=new ArrayBuffer(c.length),d=new Uint8Array(b),qq.each(c,function(a,b){d[a]=b.charCodeAt(0)}),f(b,e)},qq.log=function(a,b){window.console&&(b&&"info"!==b?window.console[b]?window.console[b](a):window.console.log("<"+b+"> "+a):window.console.log(a))},qq.isObject=function(a){return a&&!a.nodeType&&"[object Object]"===Object.prototype.toString.call(a)},qq.isFunction=function(a){return"function"==typeof a},qq.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)||a&&window.ArrayBuffer&&a.buffer&&a.buffer.constructor===ArrayBuffer},qq.isItemList=function(a){return"[object DataTransferItemList]"===Object.prototype.toString.call(a)},qq.isNodeList=function(a){return"[object NodeList]"===Object.prototype.toString.call(a)||a.item&&a.namedItem},qq.isString=function(a){return"[object String]"===Object.prototype.toString.call(a)},qq.trimStr=function(a){return String.prototype.trim?a.trim():a.replace(/^\s+|\s+$/g,"")},qq.format=function(a){var b=Array.prototype.slice.call(arguments,1),c=a,d=c.indexOf("{}");return qq.each(b,function(a,b){var e=c.substring(0,d),f=c.substring(d+2);return c=e+b+f,d=c.indexOf("{}",d+b.length),0>d?!1:void 0}),c},qq.isFile=function(a){return window.File&&"[object File]"===Object.prototype.toString.call(a)},qq.isFileList=function(a){return window.FileList&&"[object FileList]"===Object.prototype.toString.call(a)},qq.isFileOrInput=function(a){return qq.isFile(a)||qq.isInput(a)},qq.isInput=function(a,b){var c=function(a){var c=a.toLowerCase();return b?"file"!==c:"file"===c};return window.HTMLInputElement&&"[object HTMLInputElement]"===Object.prototype.toString.call(a)&&a.type&&c(a.type)?!0:a.tagName&&"input"===a.tagName.toLowerCase()&&a.type&&c(a.type)?!0:!1},qq.isBlob=function(a){return window.Blob&&"[object Blob]"===Object.prototype.toString.call(a)?!0:void 0},qq.isXhrUploadSupported=function(){var a=document.createElement("input");return a.type="file",void 0!==a.multiple&&"undefined"!=typeof File&&"undefined"!=typeof FormData&&"undefined"!=typeof qq.createXhrInstance().upload},qq.createXhrInstance=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(a){return qq.log("Neither XHR or ActiveX are supported!","error"),null}},qq.isFolderDropSupported=function(a){return a.items&&a.items.length>0&&a.items[0].webkitGetAsEntry},qq.isFileChunkingSupported=function(){return!qq.androidStock()&&qq.isXhrUploadSupported()&&(void 0!==File.prototype.slice||void 0!==File.prototype.webkitSlice||void 0!==File.prototype.mozSlice)},qq.sliceBlob=function(a,b,c){var d=a.slice||a.mozSlice||a.webkitSlice;return d.call(a,b,c)},qq.arrayBufferToHex=function(a){var b="",c=new Uint8Array(a);return qq.each(c,function(a,c){var d=c.toString(16);d.length<2&&(d="0"+d),b+=d}),b},qq.readBlobToHex=function(a,b,c){var d=qq.sliceBlob(a,b,b+c),e=new FileReader,f=new qq.Promise;return e.onload=function(){f.success(qq.arrayBufferToHex(e.result))},e.onerror=f.failure,e.readAsArrayBuffer(d),f},qq.extend=function(a,b,c){return qq.each(b,function(b,d){c&&qq.isObject(d)?(void 0===a[b]&&(a[b]={}),qq.extend(a[b],d,!0)):a[b]=d}),a},qq.override=function(a,b){var c={},d=b(c);return qq.each(d,function(b,d){void 0!==a[b]&&(c[b]=a[b]),a[b]=d}),a},qq.indexOf=function(a,b,c){if(a.indexOf)return a.indexOf(b,c);c=c||0;var d=a.length;for(0>c&&(c+=d);d>c;c+=1)if(a.hasOwnProperty(c)&&a[c]===b)return c;return-1},qq.getUniqueId=function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=0|16*Math.random(),c="x"==a?b:8|3&b;return c.toString(16)})},qq.ie=function(){return-1!==navigator.userAgent.indexOf("MSIE")||-1!==navigator.userAgent.indexOf("Trident")},qq.ie7=function(){return-1!==navigator.userAgent.indexOf("MSIE 7")},qq.ie8=function(){return-1!==navigator.userAgent.indexOf("MSIE 8")},qq.ie10=function(){return-1!==navigator.userAgent.indexOf("MSIE 10")},qq.ie11=function(){return qq.ie()&&-1!==navigator.userAgent.indexOf("rv:11")},qq.safari=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Apple")},qq.chrome=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Google")},qq.opera=function(){return void 0!==navigator.vendor&&-1!==navigator.vendor.indexOf("Opera")},qq.firefox=function(){return!qq.ie11()&&-1!==navigator.userAgent.indexOf("Mozilla")&&void 0!==navigator.vendor&&""===navigator.vendor},qq.windows=function(){return"Win32"===navigator.platform},qq.android=function(){return-1!==navigator.userAgent.toLowerCase().indexOf("android")},qq.androidStock=function(){return qq.android()&&navigator.userAgent.toLowerCase().indexOf("chrome")<0},qq.ios6=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 6_")},qq.ios7=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 7_")},qq.ios8=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 8_")},qq.ios800=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf(" OS 8_0 ")},qq.ios=function(){return-1!==navigator.userAgent.indexOf("iPad")||-1!==navigator.userAgent.indexOf("iPod")||-1!==navigator.userAgent.indexOf("iPhone")},qq.iosChrome=function(){return qq.ios()&&-1!==navigator.userAgent.indexOf("CriOS")},qq.iosSafari=function(){return qq.ios()&&!qq.iosChrome()&&-1!==navigator.userAgent.indexOf("Safari")},qq.iosSafariWebView=function(){return qq.ios()&&!qq.iosChrome()&&!qq.iosSafari()},qq.preventDefault=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},qq.toElement=function(){var a=document.createElement("div");return function(b){a.innerHTML=b;var c=a.firstChild;return a.removeChild(c),c}}(),qq.each=function(a,b){var c,d;if(a)if(window.Storage&&a.constructor===window.Storage)for(c=0;c0?a.substr(b,a.length-b):void 0},qq.getFilename=function(a){return qq.isInput(a)?a.value.replace(/.*(\/|\\)/,""):qq.isFile(a)&&null!==a.fileName&&void 0!==a.fileName?a.fileName:a.name},qq.DisposeSupport=function(){var a=[];return{dispose:function(){var b;do b=a.shift(),b&&b();while(b)},attach:function(){var a=arguments;this.addDisposer(qq(a[0]).attach.apply(this,Array.prototype.slice.call(arguments,1)))},addDisposer:function(b){a.push(b)}}}}(),function(){"use strict";qq.Error=function(a){this.message="[Fine Uploader "+qq.version+"] "+a},qq.Error.prototype=new Error}(),qq.version="5.2.2",qq.supportedFeatures=function(){"use strict";function a(){var a,b=!0;try{a=document.createElement("input"),a.type="file",qq(a).hide(),a.disabled&&(b=!1)}catch(c){b=!1}return b}function b(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[2][1-9]|Chrome\/[3-9][0-9]/)}function c(){return(qq.chrome()||qq.opera())&&void 0!==navigator.userAgent.match(/Chrome\/[1][4-9]|Chrome\/[2-9][0-9]/)}function d(){if(window.XMLHttpRequest){var a=qq.createXhrInstance();return void 0!==a.withCredentials}return!1}function e(){return void 0!==window.XDomainRequest}function f(){return d()?!0:e()}function g(){return void 0!==document.createElement("input").webkitdirectory}function h(){try{return!!window.localStorage}catch(a){return!1}}function i(){var a=document.createElement("span");return("draggable"in a||"ondragstart"in a&&"ondrop"in a)&&!qq.android()&&!qq.ios()}var j,k,l,m,n,o,p,q,r,s,t,u,v,w,x;return j=a(),m=j&&qq.isXhrUploadSupported(),k=m&&!qq.androidStock(),l=m&&i(),n=l&&b(),o=m&&qq.isFileChunkingSupported(),p=m&&o&&h(),q=m&&c(),r=j&&(void 0!==window.postMessage||m),t=d(),s=e(),u=f(),v=g(),w=m&&void 0!==window.FileReader,x=function(){return m?!qq.androidStock()&&!qq.iosChrome():!1}(),{ajaxUploading:m,blobUploading:k,canDetermineSize:m,chunking:o,deleteFileCors:u,deleteFileCorsXdr:s,deleteFileCorsXhr:t,dialogElement:!!window.HTMLDialogElement,fileDrop:l,folderDrop:n,folderSelection:v,imagePreviews:w,imageValidation:w,itemSizeValidation:m,pause:o,progressBar:x,resume:p,scaling:w&&k,tiffPreviews:qq.safari(),unlimitedScaledImageSize:!qq.ios(),uploading:j,uploadCors:r,uploadCustomHeaders:m,uploadNonMultipart:m,uploadViaPaste:q}}(),qq.isGenericPromise=function(a){"use strict";return!!(a&&a.then&&qq.isFunction(a.then))},qq.Promise=function(){"use strict";var a,b,c=[],d=[],e=[],f=0;qq.extend(this,{then:function(e,g){return 0===f?(e&&c.push(e),g&&d.push(g)):-1===f?g&&g.apply(null,b):e&&e.apply(null,a),this},done:function(c){return 0===f?e.push(c):c.apply(null,void 0===b?a:b),this},success:function(){return f=1,a=arguments,c.length&&qq.each(c,function(b,c){c.apply(null,a)}),e.length&&qq.each(e,function(b,c){c.apply(null,a)}),this},failure:function(){return f=-1,b=arguments,d.length&&qq.each(d,function(a,c){c.apply(null,b)}),e.length&&qq.each(e,function(a,c){c.apply(null,b)}),this}})},qq.BlobProxy=function(a,b){"use strict";qq.extend(this,{referenceBlob:a,create:function(){return b(a)}})},qq.UploadButton=function(a){"use strict";function b(){var a=document.createElement("input");return a.setAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME,d),a.setAttribute("title","file input"),e.setMultiple(g.multiple,a),g.folders&&qq.supportedFeatures.folderSelection&&a.setAttribute("webkitdirectory",""),g.acceptFiles&&a.setAttribute("accept",g.acceptFiles),a.setAttribute("type","file"),a.setAttribute("name",g.name),qq(a).css({position:"absolute",right:0,top:0,fontFamily:"Arial",fontSize:qq.ie()&&!qq.ie8()?"3500px":"118px",margin:0,padding:0,cursor:"pointer",opacity:0}),!qq.ie7()&&qq(a).css({height:"100%"}),g.element.appendChild(a),f.attach(a,"change",function(){g.onChange(a)}),f.attach(a,"mouseover",function(){qq(g.element).addClass(g.hoverClass)}),f.attach(a,"mouseout",function(){qq(g.element).removeClass(g.hoverClass)}),f.attach(a,"focus",function(){qq(g.element).addClass(g.focusClass)}),f.attach(a,"blur",function(){qq(g.element).removeClass(g.focusClass)}),a}var c,d,e=this,f=new qq.DisposeSupport,g={element:null,multiple:!1,acceptFiles:null,folders:!1,name:"qqfile",onChange:function(){},ios8BrowserCrashWorkaround:!1,hoverClass:"qq-upload-button-hover",focusClass:"qq-upload-button-focus"};qq.extend(g,a),d=qq.getUniqueId(),qq(g.element).css({position:"relative",overflow:"hidden",direction:"ltr"}),qq.extend(this,{getInput:function(){return c},getButtonId:function(){return d},setMultiple:function(a,b){var c=b||this.getInput();g.ios8BrowserCrashWorkaround&&qq.ios8()&&(qq.iosChrome()||qq.iosSafariWebView())?c.setAttribute("multiple",""):a?c.setAttribute("multiple",""):c.removeAttribute("multiple")},setAcceptFiles:function(a){a!==g.acceptFiles&&c.setAttribute("accept",a)},reset:function(){c.parentNode&&qq(c).remove(),qq(g.element).removeClass(g.focusClass),c=null,c=b()}}),c=b()},qq.UploadButton.BUTTON_ID_ATTR_NAME="qq-button-id",qq.UploadData=function(a){"use strict";function b(a){if(qq.isArray(a)){var b=[];return qq.each(a,function(a,c){b.push(e[c])}),b}return e[a]}function c(a){if(qq.isArray(a)){var b=[];return qq.each(a,function(a,c){b.push(e[f[c]])}),b}return e[f[a]]}function d(a){var b=[],c=[].concat(a);return qq.each(c,function(a,c){var d=g[c];void 0!==d&&qq.each(d,function(a,c){b.push(e[c])})}),b}var e=[],f={},g={},h={},i={};qq.extend(this,{addFile:function(b){var c=b.status||qq.status.SUBMITTING,d=e.push({name:b.name,originalName:b.name,uuid:b.uuid,size:null==b.size?-1:b.size,status:c})-1;return b.batchId&&(e[d].batchId=b.batchId,void 0===i[b.batchId]&&(i[b.batchId]=[]),i[b.batchId].push(d)),b.proxyGroupId&&(e[d].proxyGroupId=b.proxyGroupId,void 0===h[b.proxyGroupId]&&(h[b.proxyGroupId]=[]),h[b.proxyGroupId].push(d)),e[d].id=d,f[b.uuid]=d,void 0===g[c]&&(g[c]=[]),g[c].push(d),a.onStatusChange(d,null,c),d},retrieve:function(a){return qq.isObject(a)&&e.length?void 0!==a.id?b(a.id):void 0!==a.uuid?c(a.uuid):a.status?d(a.status):void 0:qq.extend([],e,!0)},reset:function(){e=[],f={},g={},i={}},setStatus:function(b,c){var d=e[b].status,f=qq.indexOf(g[d],b);g[d].splice(f,1),e[b].status=c,void 0===g[c]&&(g[c]=[]),g[c].push(b),a.onStatusChange(b,d,c)},uuidChanged:function(a,b){var c=e[a].uuid;e[a].uuid=b,f[b]=a,delete f[c]},updateName:function(a,b){e[a].name=b},updateSize:function(a,b){e[a].size=b},setParentId:function(a,b){e[a].parentId=b},getIdsInProxyGroup:function(a){var b=e[a].proxyGroupId;return b?h[b]:[]},getIdsInBatch:function(a){var b=e[a].batchId;return i[b]}})},qq.status={SUBMITTING:"submitting",SUBMITTED:"submitted",REJECTED:"rejected",QUEUED:"queued",CANCELED:"canceled",PAUSED:"paused",UPLOADING:"uploading",UPLOAD_RETRYING:"retrying upload",UPLOAD_SUCCESSFUL:"upload successful",UPLOAD_FAILED:"upload failed",DELETE_FAILED:"delete failed",DELETING:"deleting",DELETED:"deleted"},function(){"use strict";qq.basePublicApi={addBlobs:function(a,b,c){this.addFiles(a,b,c)},addFiles:function(a,b,c){this._maybeHandleIos8SafariWorkaround();var d=0===this._storedIds.length?qq.getUniqueId():this._currentBatchId,e=qq.bind(function(a){this._handleNewFile({blob:a,name:this._options.blobs.defaultName},d,l)},this),f=qq.bind(function(a){this._handleNewFile(a,d,l)},this),g=qq.bind(function(a){var b=qq.canvasToBlob(a);this._handleNewFile({blob:b,name:this._options.blobs.defaultName+".png"},d,l)},this),h=qq.bind(function(a){var b=a.quality&&a.quality/100,c=qq.canvasToBlob(a.canvas,a.type,b);this._handleNewFile({blob:c,name:a.name},d,l)},this),i=qq.bind(function(a){if(qq.isInput(a)&&qq.supportedFeatures.ajaxUploading){var b=Array.prototype.slice.call(a.files),c=this;qq.each(b,function(a,b){c._handleNewFile(b,d,l)})}else this._handleNewFile(a,d,l)},this),j=function(){qq.isFileList(a)&&(a=Array.prototype.slice.call(a)),a=[].concat(a)},k=this,l=[];this._currentBatchId=d,a&&(j(),qq.each(a,function(a,b){qq.isFileOrInput(b)?i(b):qq.isBlob(b)?e(b):qq.isObject(b)?b.blob&&b.name?f(b):b.canvas&&b.name&&h(b):b.tagName&&"canvas"===b.tagName.toLowerCase()?g(b):k.log(b+" is not a valid file container! Ignoring!","warn")}),this.log("Received "+l.length+" files."),this._prepareItemsForUpload(l,b,c))},cancel:function(a){this._handler.cancel(a)},cancelAll:function(){var a=[],b=this;qq.extend(a,this._storedIds),qq.each(a,function(a,c){b.cancel(c)}),this._handler.cancelAll()},clearStoredFiles:function(){this._storedIds=[]},continueUpload:function(a){var b=this._uploadData.retrieve({id:a});return qq.supportedFeatures.pause&&this._options.chunking.enabled?b.status===qq.status.PAUSED?(this.log(qq.format("Paused file ID {} ({}) will be continued. Not paused.",a,this.getName(a))),this._uploadFile(a),!0):(this.log(qq.format("Ignoring continue for file ID {} ({}). Not paused.",a,this.getName(a)),"error"),!1):!1},deleteFile:function(a){return this._onSubmitDelete(a)},doesExist:function(a){return this._handler.isValid(a)},drawThumbnail:function(a,b,c,d){var e,f,g=new qq.Promise;return this._imageGenerator?(e=this._thumbnailUrls[a],f={scale:c>0,maxSize:c>0?c:null},!d&&qq.supportedFeatures.imagePreviews&&(e=this.getFile(a)),null==e?g.failure({container:b,error:"File or URL not found."}):this._imageGenerator.generate(e,b,f).then(function(a){g.success(a)},function(a,b){g.failure({container:a,error:b||"Problem generating thumbnail"})})):g.failure({container:b,error:"Missing image generator module"}),g},getButton:function(a){return this._getButton(this._buttonIdsForFileIds[a])},getEndpoint:function(a){return this._endpointStore.get(a)},getFile:function(a){return this._handler.getFile(a)||null},getInProgress:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED]}).length},getName:function(a){return this._uploadData.retrieve({id:a}).name},getParentId:function(a){var b=this.getUploads({id:a}),c=null;return b&&void 0!==b.parentId&&(c=b.parentId),c},getResumableFilesData:function(){return this._handler.getResumableFilesData()},getSize:function(a){return this._uploadData.retrieve({id:a}).size},getNetUploads:function(){return this._netUploaded},getRemainingAllowedItems:function(){var a=this._currentItemLimit;return a>0?a-this._netUploadedOrQueued:null},getUploads:function(a){return this._uploadData.retrieve(a)},getUuid:function(a){return this._uploadData.retrieve({id:a}).uuid},log:function(a,b){!this._options.debug||b&&"info"!==b?b&&"info"!==b&&qq.log("[Fine Uploader "+qq.version+"] "+a,b):qq.log("[Fine Uploader "+qq.version+"] "+a)},pauseUpload:function(a){var b=this._uploadData.retrieve({id:a});if(!qq.supportedFeatures.pause||!this._options.chunking.enabled)return!1;if(qq.indexOf([qq.status.UPLOADING,qq.status.UPLOAD_RETRYING],b.status)>=0){if(this._handler.pause(a))return this._uploadData.setStatus(a,qq.status.PAUSED),!0;this.log(qq.format("Unable to pause file ID {} ({}).",a,this.getName(a)),"error")}else this.log(qq.format("Ignoring pause for file ID {} ({}). Not in progress.",a,this.getName(a)),"error");return!1},reset:function(){this.log("Resetting uploader..."),this._handler.reset(),this._storedIds=[],this._autoRetries=[],this._retryTimeouts=[],this._preventRetries=[],this._thumbnailUrls=[],qq.each(this._buttons,function(a,b){b.reset()}),this._paramsStore.reset(),this._endpointStore.reset(),this._netUploadedOrQueued=0,this._netUploaded=0,this._uploadData.reset(),this._buttonIdsForFileIds=[],this._pasteHandler&&this._pasteHandler.reset(),this._options.session.refreshOnReset&&this._refreshSessionData(),this._succeededSinceLastAllComplete=[],this._failedSinceLastAllComplete=[],this._totalProgress&&this._totalProgress.reset()},retry:function(a){return this._manualRetry(a)},scaleImage:function(a,b){var c=this;return qq.Scaler.prototype.scaleImage(a,b,{log:qq.bind(c.log,c),getFile:qq.bind(c.getFile,c),uploadData:c._uploadData})},setCustomHeaders:function(a,b){this._customHeadersStore.set(a,b)},setDeleteFileCustomHeaders:function(a,b){this._deleteFileCustomHeadersStore.set(a,b)},setDeleteFileEndpoint:function(a,b){this._deleteFileEndpointStore.set(a,b)},setDeleteFileParams:function(a,b){this._deleteFileParamsStore.set(a,b)},setEndpoint:function(a,b){this._endpointStore.set(a,b)},setItemLimit:function(a){this._currentItemLimit=a},setName:function(a,b){this._uploadData.updateName(a,b)},setParams:function(a,b){this._paramsStore.set(a,b)},setUuid:function(a,b){return this._uploadData.uuidChanged(a,b)},uploadStoredFiles:function(){var a;if(0===this._storedIds.length)this._itemError("noFilesError");else for(;this._storedIds.length;)a=this._storedIds.shift(),this._uploadFile(a)}},qq.basePrivateApi={_addCannedFile:function(a){var b=this._uploadData.addFile({uuid:a.uuid,name:a.name,size:a.size,status:qq.status.UPLOAD_SUCCESSFUL});return a.deleteFileEndpoint&&this.setDeleteFileEndpoint(a.deleteFileEndpoint,b),a.deleteFileParams&&this.setDeleteFileParams(a.deleteFileParams,b),a.thumbnailUrl&&(this._thumbnailUrls[b]=a.thumbnailUrl),this._netUploaded++,this._netUploadedOrQueued++,b},_annotateWithButtonId:function(a,b){qq.isFile(a)&&(a.qqButtonId=this._getButtonId(b))},_batchError:function(a){this._options.callbacks.onError(null,null,a,void 0)},_createDeleteHandler:function(){var a=this;return new qq.DeleteFileAjaxRequester({method:this._options.deleteFile.method.toUpperCase(),maxConnections:this._options.maxConnections,uuidParamName:this._options.request.uuidName,customHeaders:this._deleteFileCustomHeadersStore,paramsStore:this._deleteFileParamsStore,endpointStore:this._deleteFileEndpointStore,cors:this._options.cors,log:qq.bind(a.log,a),onDelete:function(b){a._onDelete(b),a._options.callbacks.onDelete(b)},onDeleteComplete:function(b,c,d){a._onDeleteComplete(b,c,d),a._options.callbacks.onDeleteComplete(b,c,d)}})},_createPasteHandler:function(){var a=this;return new qq.PasteSupport({targetElement:this._options.paste.targetElement,callbacks:{log:qq.bind(a.log,a),pasteReceived:function(b){a._handleCheckedCallback({name:"onPasteReceived",callback:qq.bind(a._options.callbacks.onPasteReceived,a,b),onSuccess:qq.bind(a._handlePasteSuccess,a,b),identifier:"pasted image"})}}})},_createStore:function(a,b){var c={},d=a,e={},f=function(a){return qq.isObject(a)?qq.extend({},a):a},g=function(){return qq.isFunction(b)?b():b},h=function(a,c){b&&qq.isObject(c)&&qq.extend(c,g()),e[a]&&qq.extend(c,e[a])};return{set:function(a,b){null==b?(c={},d=f(a)):c[b]=f(a)},get:function(a){var b;return b=null!=a&&c[a]?c[a]:f(d),h(a,b),f(b)},addReadOnly:function(a,b){qq.isObject(c)&&(e[a]=e[a]||{},qq.extend(e[a],b))},remove:function(a){return delete c[a]},reset:function(){c={},e={},d=a}}},_createUploadDataTracker:function(){var a=this;return new qq.UploadData({getName:function(b){return a.getName(b)},getUuid:function(b){return a.getUuid(b)},getSize:function(b){return a.getSize(b)},onStatusChange:function(b,c,d){a._onUploadStatusChange(b,c,d),a._options.callbacks.onStatusChange(b,c,d),a._maybeAllComplete(b,d),a._totalProgress&&setTimeout(function(){a._totalProgress.onStatusChange(b,c,d)},0)}})},_createUploadButton:function(a){function b(){return qq.supportedFeatures.ajaxUploading?d._options.workarounds.iosEmptyVideos&&qq.ios()&&!qq.ios6()&&d._isAllowedExtension(f,".mov")?!1:void 0===a.multiple?d._options.multiple:a.multiple:!1}var c,d=this,e=a.accept||this._options.validation.acceptFiles,f=a.allowedExtensions||this._options.validation.allowedExtensions;return c=new qq.UploadButton({element:a.element,folders:a.folders,name:this._options.request.inputName,multiple:b(),acceptFiles:e,onChange:function(a){d._onInputChange(a)},hoverClass:this._options.classes.buttonHover,focusClass:this._options.classes.buttonFocus,ios8BrowserCrashWorkaround:this._options.workarounds.ios8BrowserCrash}),this._disposeSupport.addDisposer(function(){c.dispose()}),d._buttons.push(c),c},_createUploadHandler:function(a,b){var c=this,d={},e={debug:this._options.debug,maxConnections:this._options.maxConnections,cors:this._options.cors,paramsStore:this._paramsStore,endpointStore:this._endpointStore,chunking:this._options.chunking,resume:this._options.resume,blobs:this._options.blobs,log:qq.bind(c.log,c),preventRetryParam:this._options.retry.preventRetryResponseProperty,onProgress:function(a,b,e,f){0>e||0>f||(d[a]?(d[a].loaded!==e||d[a].total!==f)&&(c._onProgress(a,b,e,f),c._options.callbacks.onProgress(a,b,e,f)):(c._onProgress(a,b,e,f),c._options.callbacks.onProgress(a,b,e,f)),d[a]={loaded:e,total:f})},onComplete:function(a,b,e,f){delete d[a];var g,h=c.getUploads({id:a}).status;h!==qq.status.UPLOAD_SUCCESSFUL&&h!==qq.status.UPLOAD_FAILED&&(g=c._onComplete(a,b,e,f),g instanceof qq.Promise?g.done(function(){c._options.callbacks.onComplete(a,b,e,f)}):c._options.callbacks.onComplete(a,b,e,f))},onCancel:function(a,b,d){var e=new qq.Promise;return c._handleCheckedCallback({name:"onCancel",callback:qq.bind(c._options.callbacks.onCancel,c,a,b),onFailure:e.failure,onSuccess:function(){d.then(function(){c._onCancel(a,b)}),e.success()},identifier:a}),e},onUploadPrep:qq.bind(this._onUploadPrep,this),onUpload:function(a,b){c._onUpload(a,b),c._options.callbacks.onUpload(a,b)},onUploadChunk:function(a,b,d){c._onUploadChunk(a,d),c._options.callbacks.onUploadChunk(a,b,d)},onUploadChunkSuccess:function(){c._options.callbacks.onUploadChunkSuccess.apply(c,arguments)},onResume:function(a,b,d){return c._options.callbacks.onResume(a,b,d)},onAutoRetry:function(){return c._onAutoRetry.apply(c,arguments)},onUuidChanged:function(a,b){c.log("Server requested UUID change from '"+c.getUuid(a)+"' to '"+b+"'"),c.setUuid(a,b)},getName:qq.bind(c.getName,c),getUuid:qq.bind(c.getUuid,c),getSize:qq.bind(c.getSize,c),setSize:qq.bind(c._setSize,c),getDataByUuid:function(a){return c.getUploads({uuid:a})},isQueued:function(a){var b=c.getUploads({id:a}).status;return b===qq.status.QUEUED||b===qq.status.SUBMITTED||b===qq.status.UPLOAD_RETRYING||b===qq.status.PAUSED},getIdsInProxyGroup:c._uploadData.getIdsInProxyGroup,getIdsInBatch:c._uploadData.getIdsInBatch};return qq.each(this._options.request,function(a,b){e[a]=b}),e.customHeaders=this._customHeadersStore,a&&qq.each(a,function(a,b){e[a]=b}),new qq.UploadHandlerController(e,b)},_fileOrBlobRejected:function(a){this._netUploadedOrQueued--,this._uploadData.setStatus(a,qq.status.REJECTED)},_formatSize:function(a){var b=-1;do a/=1e3,b++;while(a>999);return Math.max(a,.1).toFixed(1)+this._options.text.sizeSymbols[b]},_generateExtraButtonSpecs:function(){var a=this;this._extraButtonSpecs={},qq.each(this._options.extraButtons,function(b,c){var d=c.multiple,e=qq.extend({},a._options.validation,!0),f=qq.extend({},c);void 0===d&&(d=a._options.multiple),f.validation&&qq.extend(e,c.validation,!0),qq.extend(f,{multiple:d,validation:e},!0),a._initExtraButton(f)})},_getButton:function(a){var b=this._extraButtonSpecs[a];return b?b.element:a===this._defaultButtonId?this._options.button:void 0},_getButtonId:function(a){var b,c,d=a;if(d instanceof qq.BlobProxy&&(d=d.referenceBlob),d&&!qq.isBlob(d)){if(qq.isFile(d))return d.qqButtonId;if("input"===d.tagName.toLowerCase()&&"file"===d.type.toLowerCase())return d.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME);if(b=d.getElementsByTagName("input"),qq.each(b,function(a,b){return"file"===b.getAttribute("type")?(c=b,!1):void 0}),c)return c.getAttribute(qq.UploadButton.BUTTON_ID_ATTR_NAME)}},_getNotFinished:function(){return this._uploadData.retrieve({status:[qq.status.UPLOADING,qq.status.UPLOAD_RETRYING,qq.status.QUEUED,qq.status.SUBMITTING,qq.status.SUBMITTED,qq.status.PAUSED]}).length},_getValidationBase:function(a){var b=this._extraButtonSpecs[a];return b?b.validation:this._options.validation},_getValidationDescriptor:function(a){return a.file instanceof qq.BlobProxy?{name:qq.getFilename(a.file.referenceBlob),size:a.file.referenceBlob.size}:{name:this.getUploads({id:a.id}).name,size:this.getUploads({id:a.id}).size}},_getValidationDescriptors:function(a){var b=this,c=[];return qq.each(a,function(a,d){c.push(b._getValidationDescriptor(d))}),c},_handleCameraAccess:function(){if(this._options.camera.ios&&qq.ios()){var a="image/*;capture=camera",b=this._options.camera.button,c=b?this._getButtonId(b):this._defaultButtonId,d=this._options;c&&c!==this._defaultButtonId&&(d=this._extraButtonSpecs[c]),d.multiple=!1,null===d.validation.acceptFiles?d.validation.acceptFiles=a:d.validation.acceptFiles+=","+a,qq.each(this._buttons,function(a,b){return b.getButtonId()===c?(b.setMultiple(d.multiple),b.setAcceptFiles(d.acceptFiles),!1):void 0})}},_handleCheckedCallback:function(a){var b=this,c=a.callback();return qq.isGenericPromise(c)?(this.log(a.name+" - waiting for "+a.name+" promise to be fulfilled for "+a.identifier),c.then(function(c){b.log(a.name+" promise success for "+a.identifier),a.onSuccess(c)},function(){a.onFailure?(b.log(a.name+" promise failure for "+a.identifier),a.onFailure()):b.log(a.name+" promise failure for "+a.identifier)})):(c!==!1?a.onSuccess(c):a.onFailure?(this.log(a.name+" - return value was 'false' for "+a.identifier+". Invoking failure callback."),a.onFailure()):this.log(a.name+" - return value was 'false' for "+a.identifier+". Will not proceed."),c)},_handleNewFile:function(a,b,c){var d=this,e=qq.getUniqueId(),f=-1,g=qq.getFilename(a),h=a.blob||a,i=this._customNewFileHandler?this._customNewFileHandler:qq.bind(d._handleNewFileGeneric,d);!qq.isInput(h)&&h.size>=0&&(f=h.size),i(h,g,e,f,c,b,this._options.request.uuidName,{uploadData:d._uploadData,paramsStore:d._paramsStore,addFileToHandler:function(a,b){d._handler.add(a,b),d._netUploadedOrQueued++,d._trackButton(a)}})},_handleNewFileGeneric:function(a,b,c,d,e,f){var g=this._uploadData.addFile({uuid:c,name:b,size:d,batchId:f});this._handler.add(g,a),this._trackButton(g),this._netUploadedOrQueued++,e.push({id:g,file:a})},_handlePasteSuccess:function(a,b){var c=a.type.split("/")[1],d=b;null==d&&(d=this._options.paste.defaultName),d+="."+c,this.addFiles({name:d,blob:a})},_initExtraButton:function(a){var b=this._createUploadButton({element:a.element,multiple:a.multiple,accept:a.validation.acceptFiles,folders:a.folders,allowedExtensions:a.validation.allowedExtensions});this._extraButtonSpecs[b.getButtonId()]=a},_initFormSupportAndParams:function(){this._formSupport=qq.FormSupport&&new qq.FormSupport(this._options.form,qq.bind(this.uploadStoredFiles,this),qq.bind(this.log,this)),this._formSupport&&this._formSupport.attachedToForm?(this._paramsStore=this._createStore(this._options.request.params,this._formSupport.getFormInputsAsObject),this._options.autoUpload=this._formSupport.newAutoUpload,this._formSupport.newEndpoint&&(this._options.request.endpoint=this._formSupport.newEndpoint)):this._paramsStore=this._createStore(this._options.request.params) -},_isDeletePossible:function(){return qq.DeleteFileAjaxRequester&&this._options.deleteFile.enabled?this._options.cors.expected?qq.supportedFeatures.deleteFileCorsXhr?!0:qq.supportedFeatures.deleteFileCorsXdr&&this._options.cors.allowXdr?!0:!1:!0:!1},_isAllowedExtension:function(a,b){var c=!1;return a.length?(qq.each(a,function(a,d){if(qq.isString(d)){var e=new RegExp("\\."+d+"$","i");if(null!=b.match(e))return c=!0,!1}}),c):!0},_itemError:function(a,b,c){function d(a,b){g=g.replace(a,b)}var e,f,g=this._options.messages[a],h=[],i=[].concat(b),j=i[0],k=this._getButtonId(c),l=this._getValidationBase(k);return qq.each(l.allowedExtensions,function(a,b){qq.isString(b)&&h.push(b)}),e=h.join(", ").toLowerCase(),d("{file}",this._options.formatFileName(j)),d("{extensions}",e),d("{sizeLimit}",this._formatSize(l.sizeLimit)),d("{minSizeLimit}",this._formatSize(l.minSizeLimit)),f=g.match(/(\{\w+\})/g),null!==f&&qq.each(f,function(a,b){d(b,i[a])}),this._options.callbacks.onError(null,j,g,void 0),g},_manualRetry:function(a,b){return this._onBeforeManualRetry(a)?(this._netUploadedOrQueued++,this._uploadData.setStatus(a,qq.status.UPLOAD_RETRYING),b?b(a):this._handler.retry(a),!0):void 0},_maybeAllComplete:function(a,b){var c=this,d=this._getNotFinished();b===qq.status.UPLOAD_SUCCESSFUL?this._succeededSinceLastAllComplete.push(a):b===qq.status.UPLOAD_FAILED&&this._failedSinceLastAllComplete.push(a),0===d&&(this._succeededSinceLastAllComplete.length||this._failedSinceLastAllComplete.length)&&setTimeout(function(){c._onAllComplete(c._succeededSinceLastAllComplete,c._failedSinceLastAllComplete)},0)},_maybeHandleIos8SafariWorkaround:function(){var a=this;if(this._options.workarounds.ios8SafariUploads&&qq.ios800()&&qq.iosSafari())throw setTimeout(function(){window.alert(a._options.messages.unsupportedBrowserIos8Safari)},0),new qq.Error(this._options.messages.unsupportedBrowserIos8Safari)},_maybeParseAndSendUploadError:function(a,b,c,d){if(!c.success)if(d&&200!==d.status&&!c.error)this._options.callbacks.onError(a,b,"XHR returned response code "+d.status,d);else{var e=c.error?c.error:this._options.text.defaultResponseError;this._options.callbacks.onError(a,b,e,d)}},_maybeProcessNextItemAfterOnValidateCallback:function(a,b,c,d,e){var f=this;if(b.length>c)if(a||!this._options.validation.stopOnFirstInvalidFile)setTimeout(function(){var a=f._getValidationDescriptor(b[c]),g=f._getButtonId(b[c].file),h=f._getButton(g);f._handleCheckedCallback({name:"onValidate",callback:qq.bind(f._options.callbacks.onValidate,f,a,h),onSuccess:qq.bind(f._onValidateCallbackSuccess,f,b,c,d,e),onFailure:qq.bind(f._onValidateCallbackFailure,f,b,c,d,e),identifier:"Item '"+a.name+"', size: "+a.size})},0);else if(!a)for(;c0&&this._netUploadedOrQueued+1>c?(this._itemError("retryFailTooManyItems"),!1):(this.log("Retrying upload for '"+b+"' (id: "+a+")..."),!0)):(this.log("'"+a+"' is not a valid file ID","error"),!1)},_onCancel:function(a){this._netUploadedOrQueued--,clearTimeout(this._retryTimeouts[a]);var b=qq.indexOf(this._storedIds,a);!this._options.autoUpload&&b>=0&&this._storedIds.splice(b,1),this._uploadData.setStatus(a,qq.status.CANCELED)},_onComplete:function(a,b,c,d){return c.success?(c.thumbnailUrl&&(this._thumbnailUrls[a]=c.thumbnailUrl),this._netUploaded++,this._uploadData.setStatus(a,qq.status.UPLOAD_SUCCESSFUL)):(this._netUploadedOrQueued--,this._uploadData.setStatus(a,qq.status.UPLOAD_FAILED),c[this._options.retry.preventRetryResponseProperty]===!0&&(this._preventRetries[a]=!0)),this._maybeParseAndSendUploadError(a,b,c,d),c.success?!0:!1},_onDelete:function(a){this._uploadData.setStatus(a,qq.status.DELETING)},_onDeleteComplete:function(a,b,c){var d=this.getName(a);c?(this._uploadData.setStatus(a,qq.status.DELETE_FAILED),this.log("Delete request for '"+d+"' has failed.","error"),void 0===b.withCredentials?this._options.callbacks.onError(a,d,"Delete request failed",b):this._options.callbacks.onError(a,d,"Delete request failed with response code "+b.status,b)):(this._netUploadedOrQueued--,this._netUploaded--,this._handler.expunge(a),this._uploadData.setStatus(a,qq.status.DELETED),this.log("Delete request for '"+d+"' has succeeded."))},_onInputChange:function(a){var b;if(qq.supportedFeatures.ajaxUploading){for(b=0;b0&&this.addFiles(a);qq.each(this._buttons,function(a,b){b.reset()})},_onProgress:function(a,b,c,d){this._totalProgress&&this._totalProgress.onIndividualProgress(a,c,d)},_onSubmit:function(){},_onSubmitCallbackSuccess:function(a){this._onSubmit.apply(this,arguments),this._uploadData.setStatus(a,qq.status.SUBMITTED),this._onSubmitted.apply(this,arguments),this._options.callbacks.onSubmitted.apply(this,arguments),this._options.autoUpload?this._uploadFile(a):this._storeForLater(a)},_onSubmitDelete:function(a,b,c){var d,e=this.getUuid(a);return b&&(d=qq.bind(b,this,a,e,c)),this._isDeletePossible()?(this._handleCheckedCallback({name:"onSubmitDelete",callback:qq.bind(this._options.callbacks.onSubmitDelete,this,a),onSuccess:d||qq.bind(this._deleteHandler.sendDelete,this,a,e,c),identifier:a}),!0):(this.log("Delete request ignored for ID "+a+", delete feature is disabled or request not possible "+"due to CORS on a user agent that does not support pre-flighting.","warn"),!1)},_onSubmitted:function(){},_onTotalProgress:function(a,b){this._options.callbacks.onTotalProgress(a,b)},_onUploadPrep:function(){},_onUpload:function(a){this._uploadData.setStatus(a,qq.status.UPLOADING)},_onUploadChunk:function(){},_onUploadStatusChange:function(a,b,c){c===qq.status.PAUSED&&clearTimeout(this._retryTimeouts[a])},_onValidateBatchCallbackFailure:function(a){var b=this;qq.each(a,function(a,c){b._fileOrBlobRejected(c.id)})},_onValidateBatchCallbackSuccess:function(a,b,c,d,e){var f,g=this._currentItemLimit,h=this._netUploadedOrQueued;0===g||g>=h?b.length>0?this._handleCheckedCallback({name:"onValidate",callback:qq.bind(this._options.callbacks.onValidate,this,a[0],e),onSuccess:qq.bind(this._onValidateCallbackSuccess,this,b,0,c,d),onFailure:qq.bind(this._onValidateCallbackFailure,this,b,0,c,d),identifier:"Item '"+b[0].file.name+"', size: "+b[0].file.size}):this._itemError("noFilesError"):(this._onValidateBatchCallbackFailure(b),f=this._options.messages.tooManyItemsError.replace(/\{netItems\}/g,h).replace(/\{itemLimit\}/g,g),this._batchError(f))},_onValidateCallbackFailure:function(a,b,c,d){var e=b+1;this._fileOrBlobRejected(a[b].id,a[b].file.name),this._maybeProcessNextItemAfterOnValidateCallback(!1,a,e,c,d)},_onValidateCallbackSuccess:function(a,b,c,d){var e=this,f=b+1,g=this._getValidationDescriptor(a[b]);this._validateFileOrBlobData(a[b],g).then(function(){e._upload(a[b].id,c,d),e._maybeProcessNextItemAfterOnValidateCallback(!0,a,f,c,d)},function(){e._maybeProcessNextItemAfterOnValidateCallback(!1,a,f,c,d)})},_prepareItemsForUpload:function(a,b,c){if(0===a.length)return this._itemError("noFilesError"),void 0;var d=this._getValidationDescriptors(a),e=this._getButtonId(a[0].file),f=this._getButton(e);this._handleCheckedCallback({name:"onValidateBatch",callback:qq.bind(this._options.callbacks.onValidateBatch,this,d,f),onSuccess:qq.bind(this._onValidateBatchCallbackSuccess,this,d,a,b,c,f),onFailure:qq.bind(this._onValidateBatchCallbackFailure,this,a),identifier:"batch validation"})},_preventLeaveInProgress:function(){var a=this;this._disposeSupport.attach(window,"beforeunload",function(b){return a.getInProgress()?(b=b||window.event,b.returnValue=a._options.messages.onLeave,a._options.messages.onLeave):void 0})},_refreshSessionData:function(){var a=this,b=this._options.session;qq.Session&&null!=this._options.session.endpoint&&(this._session||(qq.extend(b,this._options.cors),b.log=qq.bind(this.log,this),b.addFileRecord=qq.bind(this._addCannedFile,this),this._session=new qq.Session(b)),setTimeout(function(){a._session.refresh().then(function(b,c){a._options.callbacks.onSessionRequestComplete(b,!0,c)},function(b,c){a._options.callbacks.onSessionRequestComplete(b,!1,c)})},0))},_setSize:function(a,b){this._uploadData.updateSize(a,b),this._totalProgress&&this._totalProgress.onNewSize(a)},_shouldAutoRetry:function(a){var b=this._uploadData.retrieve({id:a});return!this._preventRetries[a]&&this._options.retry.enableAuto&&b.status!==qq.status.PAUSED&&(void 0===this._autoRetries[a]&&(this._autoRetries[a]=0),this._autoRetries[a]0&&h.sizeLimit&&f>h.sizeLimit?(this._itemError("sizeError",e,d),i.failure()):f>0&&f=0}function c(){var a=!1;return qq.each(a,function(b,c){return qq.indexOf(["Accept","Accept-Language","Content-Language","Content-Type"],c)<0?(a=!0,!1):void 0}),a}function d(a){return w.cors.expected&&void 0===a.withCredentials}function e(){var a;return(window.XMLHttpRequest||window.ActiveXObject)&&(a=qq.createXhrInstance(),void 0===a.withCredentials&&(a=new XDomainRequest)),a}function f(a,b){var c=v[a].xhr;return c||(c=b?b:w.cors.expected?e():qq.createXhrInstance(),v[a].xhr=c),c}function g(a){var b,c=qq.indexOf(u,a),d=w.maxConnections;delete v[a],u.splice(c,1),u.length>=d&&d>c&&(b=u[d-1],j(b))}function h(a,b){var c=f(a),e=w.method,h=b===!0;g(a),h?s(e+" request for "+a+" has failed","error"):d(c)||q(c.status)||(h=!0,s(e+" request for "+a+" has failed - response code "+c.status,"error")),w.onComplete(a,c,h)}function i(a){var b,c=v[a].additionalParams,d=w.mandatedParams;return w.paramsStore.get&&(b=w.paramsStore.get(a)),c&&qq.each(c,function(a,c){b=b||{},b[a]=c}),d&&qq.each(d,function(a,c){b=b||{},b[a]=c}),b}function j(a,b){var c,e=f(a,b),g=w.method,h=i(a),j=v[a].payload;return w.onSend(a),c=k(a,h),d(e)?(e.onload=n(a),e.onerror=o(a)):e.onreadystatechange=l(a),m(a),e.open(g,c,!0),w.cors.expected&&w.cors.sendCredentials&&!d(e)&&(e.withCredentials=!0),p(a),s("Sending "+g+" request for "+a),j?e.send(j):t||!h?e.send():h&&w.contentType&&w.contentType.toLowerCase().indexOf("application/x-www-form-urlencoded")>=0?e.send(qq.obj2url(h,"")):h&&w.contentType&&w.contentType.toLowerCase().indexOf("application/json")>=0?e.send(JSON.stringify(h)):e.send(h),e}function k(a,b){var c=w.endpointStore.get(a),d=v[a].addToPath;return void 0!=d&&(c+="/"+d),t&&b?qq.obj2url(b,c):c}function l(a){return function(){4===f(a).readyState&&h(a)}}function m(a){var b=w.onProgress;b&&(f(a).upload.onprogress=function(c){c.lengthComputable&&b(a,c.loaded,c.total)})}function n(a){return function(){h(a)}}function o(a){return function(){h(a,!0)}}function p(a){var e=f(a),g=w.customHeaders,h=v[a].additionalHeaders||{},i=w.method,j={};d(e)||(w.acceptHeader&&e.setRequestHeader("Accept",w.acceptHeader),w.allowXRequestedWithAndCacheControl&&(w.cors.expected&&b()&&!c(g)||(e.setRequestHeader("X-Requested-With","XMLHttpRequest"),e.setRequestHeader("Cache-Control","no-cache"))),!w.contentType||"POST"!==i&&"PUT"!==i||e.setRequestHeader("Content-Type",w.contentType),qq.extend(j,qq.isFunction(g)?g(a):g),qq.extend(j,h),qq.each(j,function(a,b){e.setRequestHeader(a,b)}))}function q(a){return qq.indexOf(w.successfulResponseCodes[w.method],a)>=0}function r(a,b,c,d,e,f){v[a]={addToPath:c,additionalParams:d,additionalHeaders:e,payload:f};var g=u.push(a);return g<=w.maxConnections?j(a,b):void 0}var s,t,u=[],v={},w={acceptHeader:null,validMethods:["PATCH","POST","PUT"],method:"POST",contentType:"application/x-www-form-urlencoded",maxConnections:3,customHeaders:{},endpointStore:{},paramsStore:{},mandatedParams:{},allowXRequestedWithAndCacheControl:!0,successfulResponseCodes:{DELETE:[200,202,204],PATCH:[200,201,202,203,204],POST:[200,201,202,203,204],PUT:[200,201,202,203,204],GET:[200]},cors:{expected:!1,sendCredentials:!1},log:function(){},onSend:function(){},onComplete:function(){},onProgress:null};if(qq.extend(w,a),s=w.log,qq.indexOf(w.validMethods,w.method)<0)throw new Error("'"+w.method+"' is not a supported method for this type of request!");t="GET"===w.method||"DELETE"===w.method,qq.extend(this,{initTransport:function(a){var b,c,d,e,f;return{withPath:function(a){return b=a,this},withParams:function(a){return c=a,this},withHeaders:function(a){return d=a,this},withPayload:function(a){return e=a,this},withCacheBuster:function(){return f=!0,this},send:function(g){return f&&qq.indexOf(["GET","DELETE"],w.method)>=0&&(c.qqtimestamp=(new Date).getTime()),r(a,g,b,c,d,e)}}},canceled:function(a){g(a)}})},qq.UploadHandler=function(a){"use strict";var b=a.proxy,c={},d=b.onCancel,e=b.getName;qq.extend(this,{add:function(a,b){c[a]=b,c[a].temp={}},cancel:function(a){var b=this,f=new qq.Promise,g=d(a,e(a),f);g.then(function(){b.isValid(a)&&(c[a].canceled=!0,b.expunge(a)),f.success()})},expunge:function(a){delete c[a]},getThirdPartyFileId:function(a){return c[a].key},isValid:function(a){return void 0!==c[a]},reset:function(){c={}},_getFileState:function(a){return c[a]},_setThirdPartyFileId:function(a,b){c[a].key=b},_wasCanceled:function(a){return!!c[a].canceled}})},qq.UploadHandlerController=function(a,b){"use strict";var c,d,e,f=this,g=!1,h=!1,i={paramsStore:{},maxConnections:3,chunking:{enabled:!1,multiple:{enabled:!1}},log:function(){},onProgress:function(){},onComplete:function(){},onCancel:function(){},onUploadPrep:function(){},onUpload:function(){},onUploadChunk:function(){},onUploadChunkSuccess:function(){},onAutoRetry:function(){},onResume:function(){},onUuidChanged:function(){},getName:function(){},setSize:function(){},isQueued:function(){},getIdsInProxyGroup:function(){},getIdsInBatch:function(){}},j={done:function(a,b,c,d){var f=e._getChunkData(a,b);e._getFileState(a).attemptingResume=!1,delete e._getFileState(a).temp.chunkProgress[b],e._getFileState(a).loaded+=f.size,i.onUploadChunkSuccess(a,e._getChunkDataForCallback(f),c,d)},finalize:function(a){var b=i.getSize(a),c=i.getName(a);d("All chunks have been uploaded for "+a+" - finalizing...."),e.finalizeChunks(a).then(function(f,g){d("Finalize successful for "+a);var h=m.normalizeResponse(f,!0);i.onProgress(a,c,b,b),e._maybeDeletePersistedChunkData(a),m.cleanup(a,h,g)},function(b,e){var f=m.normalizeResponse(b,!1);d("Problem finalizing chunks for file ID "+a+" - "+f.error,"error"),f.reset&&j.reset(a),i.onAutoRetry(a,c,f,e)||m.cleanup(a,f,e)})},hasMoreParts:function(a){return!!e._getFileState(a).chunking.remaining.length},nextPart:function(a){var b=e._getFileState(a).chunking.remaining.shift();return b>=e._getTotalChunks(a)&&(b=null),b},reset:function(a){d("Server or callback has ordered chunking effort to be restarted on next attempt for item ID "+a,"error"),e._maybeDeletePersistedChunkData(a),e.reevaluateChunking(a),e._getFileState(a).loaded=0},sendNext:function(a){var b=i.getSize(a),c=i.getName(a),f=j.nextPart(a),g=e._getChunkData(a,f),l=e._getFileState(a).attemptingResume,n=e._getFileState(a).chunking.inProgress||[];null==e._getFileState(a).loaded&&(e._getFileState(a).loaded=0),l&&i.onResume(a,c,g)===!1&&(j.reset(a),f=j.nextPart(a),g=e._getChunkData(a,f),l=!1),null==f&&0===n.length?j.finalize(a):(d("Sending chunked upload request for item "+a+": bytes "+(g.start+1)+"-"+g.end+" of "+b),i.onUploadChunk(a,c,e._getChunkDataForCallback(g)),n.push(f),e._getFileState(a).chunking.inProgress=n,h&&k.open(a,f),h&&k.available()&&e._getFileState(a).chunking.remaining.length&&j.sendNext(a),e.uploadChunk(a,f,l).then(function(b,c){d("Chunked upload request succeeded for "+a+", chunk "+f),e.clearCachedChunk(a,f);var g=e._getFileState(a).chunking.inProgress||[],h=m.normalizeResponse(b,!0),i=qq.indexOf(g,f);d(qq.format("Chunk {} for file {} uploaded successfully.",f,a)),j.done(a,f,h,c),i>=0&&g.splice(i,1),e._maybePersistChunkedState(a),j.hasMoreParts(a)||0!==g.length?j.hasMoreParts(a)&&j.sendNext(a):j.finalize(a)},function(b,g){d("Chunked upload request failed for "+a+", chunk "+f),e.clearCachedChunk(a,f);var l,n=m.normalizeResponse(b,!1);n.reset?j.reset(a):(l=qq.indexOf(e._getFileState(a).chunking.inProgress,f),l>=0&&(e._getFileState(a).chunking.inProgress.splice(l,1),e._getFileState(a).chunking.remaining.unshift(f))),e._getFileState(a).temp.ignoreFailure||(h&&(e._getFileState(a).temp.ignoreFailure=!0,qq.each(e._getXhrs(a),function(a,b){b.abort()}),e.moveInProgressToRemaining(a),k.free(a,!0)),i.onAutoRetry(a,c,n,g)||m.cleanup(a,n,g))}).done(function(){e.clearXhr(a,f)}))}},k={_open:[],_openChunks:{},_waiting:[],available:function(){var a=i.maxConnections,b=0,c=0;return qq.each(k._openChunks,function(a,d){b++,c+=d.length}),a-(k._open.length-b+c)},free:function(a,b){var c,f=!b,g=qq.indexOf(k._waiting,a),h=qq.indexOf(k._open,a);delete k._openChunks[a],m.getProxyOrBlob(a)instanceof qq.BlobProxy&&(d("Generated blob upload has ended for "+a+", disposing generated blob."),delete e._getFileState(a).file),g>=0?k._waiting.splice(g,1):f&&h>=0&&(k._open.splice(h,1),c=k._waiting.shift(),c>=0&&(k._open.push(c),m.start(c)))},getWaitingOrConnected:function(){var a=[];return qq.each(k._openChunks,function(b,c){c&&c.length&&a.push(parseInt(b))}),qq.each(k._open,function(b,c){k._openChunks[c]||a.push(parseInt(c))}),a=a.concat(k._waiting)},isUsingConnection:function(a){return qq.indexOf(k._open,a)>=0},open:function(a,b){return null==b&&k._waiting.push(a),k.available()?(null==b?(k._waiting.pop(),k._open.push(a)):function(){var c=k._openChunks[a]||[];c.push(b),k._openChunks[a]=c}(),!0):!1},reset:function(){k._waiting=[],k._open=[]}},l={send:function(a,b){e._getFileState(a).loaded=0,d("Sending simple upload request for "+a),e.uploadFile(a).then(function(c,e){d("Simple upload request succeeded for "+a);var f=m.normalizeResponse(c,!0),g=i.getSize(a);i.onProgress(a,b,g,g),m.maybeNewUuid(a,f),m.cleanup(a,f,e)},function(c,e){d("Simple upload request failed for "+a);var f=m.normalizeResponse(c,!1);i.onAutoRetry(a,b,f,e)||m.cleanup(a,f,e)})}},m={cancel:function(a){d("Cancelling "+a),i.paramsStore.remove(a),k.free(a)},cleanup:function(a,b,c){var d=i.getName(a);i.onComplete(a,d,b,c),e._getFileState(a)&&e._clearXhrs&&e._clearXhrs(a),k.free(a)},getProxyOrBlob:function(a){return e.getProxy&&e.getProxy(a)||e.getFile&&e.getFile(a)},initHandler:function(){var a=b?qq[b]:qq.traditional,c=qq.supportedFeatures.ajaxUploading?"Xhr":"Form";e=new a[c+"UploadHandler"](i,{getDataByUuid:i.getDataByUuid,getName:i.getName,getSize:i.getSize,getUuid:i.getUuid,log:d,onCancel:i.onCancel,onProgress:i.onProgress,onUuidChanged:i.onUuidChanged}),e._removeExpiredChunkingRecords&&e._removeExpiredChunkingRecords()},isDeferredEligibleForUpload:function(a){return i.isQueued(a)},maybeDefer:function(a,b){return b&&!e.getFile(a)&&b instanceof qq.BlobProxy?(i.onUploadPrep(a),d("Attempting to generate a blob on-demand for "+a),b.create().then(function(b){d("Generated an on-demand blob for "+a),e.updateBlob(a,b),i.setSize(a,b.size),e.reevaluateChunking(a),m.maybeSendDeferredFiles(a)},function(b){var e={};b&&(e.error=b),d(qq.format("Failed to generate blob for ID {}. Error message: {}.",a,b),"error"),i.onComplete(a,i.getName(a),qq.extend(e,c),null),m.maybeSendDeferredFiles(a),k.free(a)}),!1):m.maybeSendDeferredFiles(a)},maybeSendDeferredFiles:function(a){var b=i.getIdsInProxyGroup(a),c=!1;return b&&b.length?(d("Maybe ready to upload proxy group file "+a),qq.each(b,function(b,d){if(m.isDeferredEligibleForUpload(d)&&e.getFile(d))c=d===a,m.now(d);else if(m.isDeferredEligibleForUpload(d))return!1})):(c=!0,m.now(a)),c},maybeNewUuid:function(a,b){void 0!==b.newUuid&&i.onUuidChanged(a,b.newUuid)},normalizeResponse:function(a,b){var c=a;return qq.isObject(a)||(c={},qq.isString(a)&&!b&&(c.error=a)),c.success=b,c},now:function(a){var b=i.getName(a);if(!f.isValid(a))throw new qq.Error(a+" is not a valid file ID to upload!");i.onUpload(a,b),g&&e._shouldChunkThisFile(a)?j.sendNext(a):l.send(a,b)},start:function(a){var b=m.getProxyOrBlob(a);return b?m.maybeDefer(a,b):(m.now(a),!0)}};qq.extend(this,{add:function(){e.add.apply(this,arguments)},upload:function(a){return k.open(a)?m.start(a):!1},retry:function(a){return h&&(e._getFileState(a).temp.ignoreFailure=!1),k.isUsingConnection(a)?m.start(a):f.upload(a)},cancel:function(a){var b=e.cancel(a);qq.isGenericPromise(b)?b.then(function(){m.cancel(a)}):b!==!1&&m.cancel(a)},cancelAll:function(){var a,b=k.getWaitingOrConnected();if(b.length)for(a=b.length-1;a>=0;a--)f.cancel(b[a]);k.reset()},getFile:function(a){return e.getProxy&&e.getProxy(a)?e.getProxy(a).referenceBlob:e.getFile&&e.getFile(a)},isProxied:function(a){return!(!e.getProxy||!e.getProxy(a))},getInput:function(a){return e.getInput?e.getInput(a):void 0},reset:function(){d("Resetting upload handler"),f.cancelAll(),k.reset(),e.reset()},expunge:function(a){return f.isValid(a)?e.expunge(a):void 0},isValid:function(a){return e.isValid(a)},getResumableFilesData:function(){return e.getResumableFilesData?e.getResumableFilesData():[]},getThirdPartyFileId:function(a){return f.isValid(a)?e.getThirdPartyFileId(a):void 0},pause:function(a){return f.isResumable(a)&&e.pause&&f.isValid(a)&&e.pause(a)?(k.free(a),e.moveInProgressToRemaining(a),!0):!1},isResumable:function(a){return!!e.isResumable&&e.isResumable(a)}}),qq.extend(i,a),d=i.log,g=i.chunking.enabled&&qq.supportedFeatures.chunking,h=g&&i.chunking.concurrent.enabled,c=function(){var a={};return a[i.preventRetryParam]=!0,a}(),m.initHandler()},qq.FormUploadHandler=function(a){"use strict";function b(a){delete k[a],m&&(clearTimeout(l[a]),delete l[a],q.stopReceivingMessages(a));var b=document.getElementById(g._getIframeName(a));b&&(b.setAttribute("src","javascript:false;"),qq(b).remove())}function c(a){return a.split("_")[0]}function d(a){var b=qq.toElement("